Russian Roulette, Reloaded

32

4

Let's play Russian Roulette!

Normally, this would be a race to write the shortest MOD 6 program, but that's not very realistic, as the chance of winning decreases with each click. Here are the rules:

  1. Emulate a real six-shooter:
    • A single bullet is placed into one of the six chambers, and the barrel is spun once, only before playing.
    • The chance of losing on the nth try is 1/6.
    • The chance of losing after n tries is 1/(6-n)
    • You are guaranteed to lose in, at most, 6 tries.
  2. Losing:
    • Display the text *BANG!*
    • Terminate the program.
  3. Winning:
    • "Winning" means the gun does not fire, but the bullet is one chamber closer to the hammer.
    • Display the text *click*
    • Present a "trigger" to the user, along with the ability to terminate the program (e.g. "ctrl+c", see below).
  4. Program specific:
    • Pulling the trigger is some form of user input, including the first try. (This can be a keystroke, a mouse click, whatever; text prompts are not required.)
    • Only one instance of the program is allowed until it is terminated. (Running a new instance of the program is akin to giving the barrel a good spin, i.e. the probability of losing on the next click is reset to 1/6.)

Shortest code wins!

Leaderboard

<style>body { text-align: left !important} #answer-list { padding: 10px; width: 290px; float: left; } #language-list { padding: 10px; width: 290px; float: left; } table thead { font-weight: bold; } table td { padding: 5px; }</style><script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"> <div id="language-list"> <h2>Shortest Solution by Language</h2> <table class="language-list"> <thead> <tr><td>Language</td><td>User</td><td>Score</td></tr> </thead> <tbody id="languages"> </tbody> </table> </div> <div id="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr> </thead> <tbody id="answers"> </tbody> </table> </div> <table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr> </tbody> </table> <table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr> </tbody> </table><script>var QUESTION_ID = 66763; var ANSWER_FILTER = "!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe"; var COMMENT_FILTER = "!)Q2B_A2kjfAiU78X(md6BoYk"; var OVERRIDE_USER = 38512; var answers = [], answers_hash, answer_ids, answer_page = 1, more_answers = true, comment_page; function answersUrl(index) { return "https://api.stackexchange.com/2.2/questions/" + QUESTION_ID + "/answers?page=" + index + "&pagesize=100&order=desc&sort=creation&site=codegolf&filter=" + ANSWER_FILTER; } function commentUrl(index, answers) { return "https://api.stackexchange.com/2.2/answers/" + answers.join(';') + "/comments?page=" + index + "&pagesize=100&order=desc&sort=creation&site=codegolf&filter=" + COMMENT_FILTER; } function getAnswers() { jQuery.ajax({ url: answersUrl(answer_page++), method: "get", dataType: "jsonp", crossDomain: true, success: function (data) { answers.push.apply(answers, data.items); answers_hash = []; answer_ids = []; data.items.forEach(function(a) { a.comments = []; var id = +a.share_link.match(/\d+/); answer_ids.push(id); answers_hash[id] = a; }); if (!data.has_more) more_answers = false; comment_page = 1; getComments(); } }); } function getComments() { jQuery.ajax({ url: commentUrl(comment_page++, answer_ids), method: "get", dataType: "jsonp", crossDomain: true, success: function (data) { data.items.forEach(function(c) { if (c.owner.user_id === OVERRIDE_USER) answers_hash[c.post_id].comments.push(c); }); if (data.has_more) getComments(); else if (more_answers) getAnswers(); else process(); } }); } getAnswers(); var SCORE_REG = /<h\d>\s*([^\n,<]*(?:<(?:[^\n>]*>[^\n<]*<\/[^\n>]*>)[^\n,<]*)*),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/; var OVERRIDE_REG = /^Override\s*header:\s*/i; function getAuthorName(a) { return a.owner.display_name; } function process() { var valid = []; answers.forEach(function(a) { var body = a.body; a.comments.forEach(function(c) { if(OVERRIDE_REG.test(c.body)) body = '<h1>' + c.body.replace(OVERRIDE_REG, '') + '</h1>'; }); var match = body.match(SCORE_REG); if (match) valid.push({ user: getAuthorName(a), size: +match[2], language: match[1], link: a.share_link, }); else console.log(body); }); valid.sort(function (a, b) { var aB = a.size, bB = b.size; return aB - bB }); var languages = {}; var place = 1; var lastSize = null; var lastPlace = 1; valid.forEach(function (a) { if (a.size != lastSize) lastPlace = place; lastSize = a.size; ++place; var answer = jQuery("#answer-template").html(); answer = answer.replace("{{PLACE}}", lastPlace + ".") .replace("{{NAME}}", a.user) .replace("{{LANGUAGE}}", a.language) .replace("{{SIZE}}", a.size) .replace("{{LINK}}", a.link); answer = jQuery(answer); jQuery("#answers").append(answer); var lang = a.language; lang = jQuery('<a>'+lang+'</a>').text(); languages[lang] = languages[lang] || {lang: a.language, lang_raw: lang.toLowerCase(), user: a.user, size: a.size, link: a.link}; }); var langs = []; for (var lang in languages) if (languages.hasOwnProperty(lang)) langs.push(languages[lang]); langs.sort(function (a, b) { if (a.lang_raw > b.lang_raw) return 1; if (a.lang_raw < b.lang_raw) return -1; return 0; }); for (var i = 0; i < langs.length; ++i) { var language = jQuery("#language-template").html(); var lang = langs[i]; language = language.replace("{{LANGUAGE}}", lang.lang) .replace("{{NAME}}", lang.user) .replace("{{SIZE}}", lang.size) .replace("{{LINK}}", lang.link); language = jQuery(language); jQuery("#languages").append(language); } }</script>

ayane

Posted 2015-12-16T09:16:53.303

Reputation: 929

I'm unclear on the probabilities. Is the loss time uniformly distributed between 1 and 6? – xnor – 2015-12-16T09:39:13.410

@xnor The probability of losing on the nth try is 1/6 - however, the probability of losing after n tries is 1/(6-n), since the probability of firing a bullet reaches one as the number of remaining empty chambers reaches zero. – ayane – 2015-12-16T10:02:00.253

This is very hard to do nondeterministically, I find. – cat – 2015-12-16T14:01:11.737

3Your assumptions are wrong - the chance of losing on the n'th try is only ⅙ if you respin the bullets after each shot. Without respinning the chance of losing is ⅙ on the first shot, ⅕ on the second, ¼ on the third... ending in 1 on the 6th. You recognise this with "You are guaranteed to lose in, at most, 6 tries". – rhialto – 2015-12-16T21:52:15.090

2@user2956063 you are forgetting that there is a (n-1)/6 chance that you never reach the n:th try, and thus cannot lose. They balance out to a uniform 1/6. – Jacob Raihle – 2015-12-17T10:26:00.737

2maybe that's a difference in the way computer scientists and statisticians express probability then - to me "The chance of losing on the nth try is ⅙" say's it's constant - whether n is 1 or 100. – rhialto – 2015-12-17T11:53:28.270

3Why was this not titled "Russian Roulette, Reloaded"? – Hand-E-Food – 2015-12-18T04:51:35.023

@Hand-E-Food Because I'm not very creative, especially with titles :P – ayane – 2015-12-18T05:19:35.797

I posted my answer several hours ago and I only just got the title now. well done (or I might just be stupid—that's never outside of the realm of possibility) – Cyoce – 2015-12-18T08:38:32.377

1@user2956063: Your probabilities are conditional. P(lose on shot 2) = ⅙, but P(lose on shot 2 | didn't lose on shot 1) = ⅕. Also, n is (implicitly, I'll grant you) limited to [1,6], so 100 is out. – Tim Pederick – 2015-12-19T05:04:41.680

Answers

3

Pyth, 23 bytes

VO6"*click*" w;"*BANG!*

Really simple. A random number of iterations 0 - 5 display click and request a line of input, followed by a bang at the end.

isaacg

Posted 2015-12-16T09:16:53.303

Reputation: 39 268

1damn you, pyth! – Cyoce – 2015-12-18T01:55:20.873

+3 bytes: the last string should be *BANG!*, not BANG – ayane – 2015-12-18T05:34:55.033

14

Ruby, 51 bytes

[*['*click*']*rand(6),'*BANG!*'].map{|x|gets;$><<x}

Ungolfed:

[
  *(                        # Unwrap the following array into the outer one
    ['*click*'] * rand(6)   # An array of 0-5 clicks, see Array#*
  ),
  '*BANG!*'                 # The End
].map do |x| # Shortest way to iterate I was able to find
  gets       # Await input
  $> << x    # Shove the output string to `stdout`
end          # Return value is an array of several (0-5) `stdout`s. Who cares.

or

(['*click*']*rand(6)<<'*BANG!*').map{|x|gets;$><<x}

Ungolfing left for the readers. Not that difficult

  • Again, kudos to Martin, this time for a trick with $><< as a puts replacement.
  • Doesn't output newlines, but that was not required.
  • The shorter, the simpler. The gist of the required behaviour is to do 0-5 clicks and then fire. For that, outputs are accumulated inside the array.
  • 2 more bytes can be shaved off if outputs like "*click*" are okay (what's required is printed in the end), by replacing $><< with . I wasn't sure if this would still follow the rules.

68 64 bytes

(another approach)

[*0..5].shuffle.find{|x|gets;x<1||puts('*click*')};puts'*BANG!*'

I didn't put much thought into the algorithm (it can possibly be even more compact, but not so clear), but I really like the model inside it:

  • An array emulates a barrel with its elements being chambers' contents. Since only one element is a bullet, rotating it and shuffling it are equivalent.
  • 0 is a bullet. Other numbers are not.
  • find finds a first return value for which the block is neither false nor nil.
  • ||-expression is implicitly returned from the block. It's a short-circuit: it returns its first operand (unless it's nil or false) or a second one (otherwise). So it either returns true (if x<1 or, clearer but longer x == 0) or the return value of puts, while...
  • puts always returns nil. Yep.
  • gets requests input. Merely hitting Enter suffices.
  • Ctrl+C terminates the program

D-side

Posted 2015-12-16T09:16:53.303

Reputation: 241

Crossed out 64 is normal 64? – Cyoce – 2015-12-18T05:06:47.950

@Cyoce uhm... yes. Should be, probably. It's been superceded by the above entry, but it is based on a different idea, so I left them, crossed out. – D-side – 2015-12-18T07:51:39.097

it was a pun on this

– Cyoce – 2015-12-19T07:22:24.427

@Cyoce oh, pardon me, first post and all that, not aware of the local lore :) – D-side – 2015-12-19T21:27:39.107

9

JavaScript, 64 bytes

for(i=6;i<7&&prompt();)alert(new Date%i--?"*click*":i="*BANG!*")

Explanation

To pull the trigger enter any text into the prompt. Enter nothing or click cancel to terminate.

for(
  i=6;             // i = number of chambers
  i<7              // i equals "*BANG!*" (not less than 7) if we lost
    &&prompt();    // see if we should do another shot
)
  alert(           // alert the result
    new Date%i--   // use the current time in milliseconds as a random number, this is safe
                   //     to use because the gap between shots is greater than i (max 6ms)
      ?"*click*"   // on win pass "*click*" to alert
      :i="*BANG!*" // on lose alert "*BANG!*" and set i to not less than 7
  )

user81655

Posted 2015-12-16T09:16:53.303

Reputation: 10 181

"*Bang!*" is not greater than 7. But NaN is not smaller than 7. – Bergi – 2015-12-16T12:38:45.947

@Bergi That's true. I reworded the explanation to make it a bit clearer. – user81655 – 2015-12-16T12:43:35.243

6@Bergi only in Javascript does that statement come even close to making sense. – MikeTheLiar – 2015-12-16T16:03:00.927

7

Lua, 82 75 bytes

Pretty long, but there's lot of verbose in lua.

for a=math.random(6),1,-1 do io.read()print(a>1 and"*click*"or"*BANG!*")end

Katenkyo

Posted 2015-12-16T09:16:53.303

Reputation: 2 857

6

LabVIEW, 46 LabVIEW Primitives

Creates an Array of 0s and one 1, has a loop to wait for clicks and outputs the string. It initially says BANG becuase i forgot to reset the indicator before starting it.

Also note that this is a gif, if if does not play/load for you please reopen the page.

Eumel

Posted 2015-12-16T09:16:53.303

Reputation: 2 487

I don't see where you do the output of "*click*" in case the gun didn't shoot. Also, does it output "bang" or "*BANG!*"? – Katenkyo – 2015-12-16T10:04:02.097

this should be a gif but for me it doesnt play, that might be the problem. And yes it only puts bang, that was me not reading properly i change that in a sec – Eumel – 2015-12-16T10:15:12.743

stupid me forgot to reinitialize the string to empty before starting so thats why it showes BANG at the start... – Eumel – 2015-12-16T10:25:06.403

No problem, I saw the gif now, looks like it works pretty well :) – Katenkyo – 2015-12-16T10:26:46.693

5

Pyth, 31 30 28 bytes

FN.S6 EI!N"*BANG!*"B"*click*

Almost certainly can be improved. Input any number to pull the trigger, blank input to terminate early (with an error).

Explanation:

FN                               for N in...
  .S6                            shuffle(range(6))...
      E                          get a line of input
       I!N                       if N is falsy (i.e. 0)
          "*BANG!*"              implicit output
                   B             break
                    "*click*     else, print click

Doorknob

Posted 2015-12-16T09:16:53.303

Reputation: 68 138

Your first one is actually shorter, you don't need the trailing". – FryAmTheEggman – 2015-12-16T14:06:05.150

@FryAmTheEggman Oh, right, forgot about that. Thanks! – Doorknob – 2015-12-16T14:31:19.647

Also, I've just noticed something silly, FN<any> is still entirely identical to V<any>, that should probably be changed to not confuse new golfers... :P – FryAmTheEggman – 2015-12-16T14:38:31.660

1You can simply remove the chars .?. There is no need for an else. – Jakube – 2015-12-16T17:57:25.193

@FryAmTheEggman confusing people is awesome. It can be amazing at filtering out the scrubs.

– Cyoce – 2015-12-18T08:40:06.877

5

Seriously, 27 25 bytes

"*BANG!*"6J"*click*"nW,X.

No online link because there is no way to do a prompt with piped input. The program can be CTRL-C'd at any time to chicken out terminate.

Explanation:

"*BANG!*"6J"*click*"nW,X.
"*BANG!*"                  push "*BANG!*"
         6J                push a random integer in [0,6) (n)
           "*click*"n      push "*click*" n times
                     W     while loop (implicitly closed at EOF):
                      ,X.    get input and discard, pop and print top of stack

Mego

Posted 2015-12-16T09:16:53.303

Reputation: 32 998

4

Perl 5, 43 bytes

Run with perl -p. Stable bullet variant - i.e. bullet position is decided only once in very beginning.

$i//=0|rand 6;$_=$i--?'*click*':die'*BANG*'

Oleg V. Volkov

Posted 2015-12-16T09:16:53.303

Reputation: 171

Nice! I would change the header to "Perl 5.10+", since you're using //=. Also, don't forget to count -p in your score.

– ThisSuitIsBlackNot – 2015-12-17T04:46:01.520

4

PHP, 52 bytes

*<?=$n=&rand(0,6-$argi)?click:"BANG!*";$n||@\n?>*

Requires the -F command line option, counted as three. The trigger is pulled by pressing Enter.

Because -F literally runs the script again for every input (I kid you not), die and the like won't actually terminate, so we exit via suppressed runtime error instead, @\n.


Sample Usage

$ php -F primo-roulette.php

*click*
*click*
*BANG!*
$

primo

Posted 2015-12-16T09:16:53.303

Reputation: 30 891

4

C, 110 74 72 bytes

Thanks to Dennis for getting rid of the includes and a lot less bytes.

main(r){for(r=time(0)%6;getchar(),r--;)puts("*click*");puts("*BANG!*");}
main(r)
{
    for(r=time(0)%6;getchar(),r--;)
        puts("*click*");
    puts("*BANG!*");
}

Rainer P.

Posted 2015-12-16T09:16:53.303

Reputation: 2 457

3

Candy, 36 bytes

About half the program is the text to print out :(

:6H_(=b"*click*"(;):=)"*BANG!*\n"(;)

long form:

getc
digit6 rand range0  # build a range from 0 .. rand#
while
  popA              # these are the *click* instances  
  stack2
  "*click*"
  while
    printChr
  endwhile
  getc
  popA
endwhile
"*BANG!*\n"         # out of luck
while
  printChr
endwhile

Dale Johnson

Posted 2015-12-16T09:16:53.303

Reputation: 509

3

Python 3, 95 bytes

Also my first golf attempt, also in Python 3. I swear Bruce and I aren't the same person.

from random import*
for a in range(randint(0,5)):input();print("*click*")
input();print("*bang*")

Ungolfed:

from random import*
for a in range(randint(0,5)):
    input()
    print("*click*")
input()
print("*bang*")

Generate a random number between 0 and 5 inclusive, print click that many times, then print bang. Press enter/return to pull the trigger.

Steve Eckert

Posted 2015-12-16T09:16:53.303

Reputation: 216

Following Bruce's example, you can save a few bytes with from random import* – wnnmaw – 2015-12-16T17:25:35.423

Unless there's something else I'm missing, it's one byte of savings. But I'll take it! Thanks! – Steve Eckert – 2015-12-16T17:30:59.297

Nice attempt, I used your solution as an inspiration for my python 2 solution ^^ – basile-henry – 2015-12-16T17:52:36.860

3

PlatyPar, 26 25 bytes

6#?;wT"*click*"O;"*BANG!*

Explanation:

6#?;                        ## random integer [0,6)
    w           ;           ## while stack.last
     T                      ## stack.last--
      "*click*"O            ## alert "*click*"
                 "*BANG!*   ## alert "*BANG!*"

Try it online!

Cyoce

Posted 2015-12-16T09:16:53.303

Reputation: 2 690

2

Emacs Lisp, 94 89 bytes

(set'b(%(random)6))(dotimes(a(+ b 1))(read-string"")(message(if(eq a b)"BANG""*click*")))

Ungolfed:

(set 'b (% (random) 6))
(dotimes (a (+ b 1))
  (read-string"")
  (message (if (eq a b) "BANG" "*click*")))

Lord Yuuma

Posted 2015-12-16T09:16:53.303

Reputation: 587

2

R, 86 80 77 bytes

As usual, R has awesome features to code golfing but looooooong function names.

sapply(sample(0:5),function(n){!n&&{cat('*BANG!*');q()};readline('*click*')})

durum

Posted 2015-12-16T09:16:53.303

Reputation: 129

2

Python 2, 108 104 102 100 98 bytes

My first attempt at golfing:

from random import*
a=[1]+[0]*5
shuffle(a)
for i in a:input();print("*click*","*BANG!*")[i];" "[i]

Maybe I should add that the program doesn't terminate correctly when you lose, it just throws an exception (which results in termination):

Traceback (most recent call last):
  File "russian_roulette.py", line 4, in <module>
    for i in a:input();print("*click*","*BANG!*")[i];" "[i]
IndexError: string index out of range

ბიმო

Posted 2015-12-16T09:16:53.303

Reputation: 15 345

Welcome to Programming Puzzles & Code Golf! When you post a code golf answer, please include the language name and the byte count (I edited it in for you here). Thanks! – ProgramFOX – 2015-12-16T16:58:41.790

Yes, thanks a lot! I was actually trying to resolve that issue, didn't get to edit it correctly before you did. – ბიმო – 2015-12-16T17:02:09.887

I get your byte count as 112, what did you use?

– wnnmaw – 2015-12-16T17:22:10.713

Also, you can save 2 bytes by doing a=shuffle([1,0,0,0,0,0]) – wnnmaw – 2015-12-16T17:22:41.670

1As far as I know shuffle changes the underlying data structure and doesn't return anything. I tried that, thanks anyways. The headline (language and byte count) was written by ProgramFOX. But when I use wc it gives me 109 which one too much, so it's right. How do you count? – ბიმო – 2015-12-16T17:33:40.520

Why do you need [(i^1)] ? can't you just put [i] and invert BANG and click? Like this: print(("*click*","*BANG!*")[i]) – basile-henry – 2015-12-16T17:49:04.130

I tested it and it seems to work. Do you mean the exception raised by " "[i] when i = 1? I believe my hint doesn't change this behavior. – basile-henry – 2015-12-16T18:00:58.340

Ah, I see you've changed it :) Also if you change from python 3 to python 2 you can get rid of the print parenthesis. – basile-henry – 2015-12-16T18:01:52.567

@Boomerang Thanks and sorry for the confusion.. It works as you said! I was thinking about flipping the bits in the vector (I tried that earlier). I adjusted the code. – ბიმო – 2015-12-16T18:02:27.643

@Boomerang Yes, I know. But then again, how does input() not give an EOF error in python2? Because raw_input() is too long. – ბიმო – 2015-12-16T18:04:37.060

Look at my solution for python 2 ^^ The problem says you can use whatever input. My solution requires the user to input "i" before pressing Enter – basile-henry – 2015-12-16T18:06:19.790

2

Perl 5, 40 bytes

<>,print"*$_*"for(click)x rand 5,'BANG!'

Run without command line options, the trigger is pulled by pressing Enter.

primo

Posted 2015-12-16T09:16:53.303

Reputation: 30 891

2

Python, 81 Bytes

import time
for i in["*click*"]*(int(time.time())%6)+["*BANG!*"]:input();print(i)

inspired by the Ruby(51) and Python solutions

Lars

Posted 2015-12-16T09:16:53.303

Reputation: 21

1

Common Lisp, 109

(do(g(b(nthcdr(random 6)#1='(t()()()()() . #1#))))(g)(read-char)(princ(if(setf g(pop b))"*BANG!*""*click*")))

Not very competitive, but I like circular lists:

(do (;; auxiliary variable x
     x
     ;; initialize infinite barrel, rotate randomly
     (b (nthcdr (random 6) #1='(t()()()()() . #1#))))

    ;; we end the loop when x is T (a bullet is fired)
    (x)

  ;; press enter to shoot
  (read-char)

  ;; pop from b, which makes b advance down the list. The popped value
  ;; goes into x and is used to select the appropriate string for
  ;; printing.
  (princ
   (if (setf x(pop b))
       "*BANG!*"
       "*click*")))

coredump

Posted 2015-12-16T09:16:53.303

Reputation: 6 292

1

Perl 5, 43 bytes

42 bytes + -p command line option. Just press enter to trigger.

$_=0|rand 7-$.<++$i?die"*BANG!*":"*click*"

Thanks to Dom Hastings for his help! Original answer was 67 bytes:

$i++;$a=$i>=int(rand(6));print$_=$a?'*BANG!*':'*click*';last if($a)

Codefun64

Posted 2015-12-16T09:16:53.303

Reputation: 297

Actually the problem with -p was that it would exit before calling the last print statement, not sure why. I've tried it. Other than that, awesome suggestions, thanks! My knowledge continues to grow... – Codefun64 – 2015-12-16T13:21:48.520

@DomHastings Also, unfortunately, for some reason the 0| trick didn't work as expected, but I did shave some bytes off of it, the print statement and the last statement like you suggested. How does it look now? – Codefun64 – 2015-12-16T13:29:14.493

@DomHastings Damn, you are good. I recommend putting that as your own answer, since you definitely wrote a smaller program than I (you have 40 bytes compared to my original 67!) – Codefun64 – 2015-12-16T13:41:41.350

I appreciate the explanation! Always happy to learn more of my favorite scripting language! I never even knew about the prefex incrementing, that's pretty awesome. Thanks :) – Codefun64 – 2015-12-16T13:50:00.160

You're very welcome, glad to have helped! – Dom Hastings – 2015-12-16T13:51:51.937

It seems to violate 'The chance of losing after n tries is 1/(6-n)' rule. – Oleg V. Volkov – 2015-12-16T14:13:32.233

I'm not sure I understand you. The specified rule is merely a mathematical reality; the odds of you being shot on the first attempt, which is "after 0 tries" since you haven't tried yet, is 1/(6-0) or 1/6. The program clearly offers a 1/6 chance of you dying on the first attempt (this is rather macabre, isn't it?)

The "rule" is essentially only actually stating, that we must use a random number generator in our code somewhere. This is adhered to. – Codefun64 – 2015-12-16T14:24:09.927

@Codefun64 When $i is 2, you will have a 1/3 chance of dying (2/6), rather than 1/5 as it should be. rand 6-$. would solve it. – primo – 2015-12-16T14:28:54.257

For example after you fired 4 shots, your 5th should be exactly 1/(6-4) - 50% of dying. This program does not follow this rule. – Oleg V. Volkov – 2015-12-16T14:30:40.960

@primo isn't it 7-$.? – Oleg V. Volkov – 2015-12-16T14:43:21.617

@OlegV.Volkov yes, it is. – primo – 2015-12-16T15:02:45.137

Interesting - I edited the post. I will take another look at this when I get some rest. – Codefun64 – 2015-12-16T15:21:56.283

There no need for the <++$i. 0|rand 7-$. gives you one in six, then one in five, etc. – primo – 2015-12-16T15:22:16.563

I thought there was something off, but I'm so sleep deprived right now I couldn't recognize it. I got suspicious when I ran it like 20 times and never got past 4 shots. Will edit in a moment. – Codefun64 – 2015-12-16T15:24:51.743

1

MATL, 41 bytes

6Yr`j?t@=?'*BANG!*'DT.}'*click*'DT]}T.]]x

To pull the trigger, input a non-empty string (such as 'try').

To terminate, input an empty string

Examples

In this case the trigger was pulled once and... bad luck:

>> matl
 > 6Yr`j?t@=?'*BANG!*'DT.}'*click*'DT]}T.]]x
 > 
> try
*BANG!*

In this case the user stopped (note the final empty input) after two lucky pulls:

>> matl
 > 6Yr`j?t@=?'*BANG!*'DT.}'*click*'DT]}T.]]x
 > 
> try
*click*
> try
*click*
> 

Explanation

6Yr                  % random avlue from 1 to 6    
`                    % do...while  
  j                  % input string
  ?                  % if nonempty
    t                % duplicate the orignal random value
    @                % loop iteration index  
    =                % are the equal?
    ?                % if so             
      '*BANG!*'D     % display string
      T.             % unconditional break                                     
    }                % else
      '*click*'D     % display string
      T              % true value, to go on with do...while loop
    ]                % end if               
  }                  % else                                                    
    T.               % unconditional break
  ]                  % end                                                     
]                    % end                                                     
x                    % delete original random value

Luis Mendo

Posted 2015-12-16T09:16:53.303

Reputation: 87 464

1

Python 2, 88 84 bytes

This solution is inspired by the python 3 solutions already given. I chose python 2 to remove the print parenthesis even though this changes the behavior of input().

import time
for i in[0]*int(time.time()%6)+[1]:input();print("*click*","*BANG!*")[i]
  • I am using modulo of the time as a random function (good enough for russian roulette)
  • the player input should be "i" then Enter (otherwise input() will throw an error), this trick relies on the fact that the input can be "whatever".

basile-henry

Posted 2015-12-16T09:16:53.303

Reputation: 381

1

Perl 6,  58   53 bytes

for ^6 .pick(*) {get;say <*BANG!* *click*>[?$_];!$_&&last} # 58 bytes

$ perl6 -pe '$///=^6 .pick;$_=$/--??"*click*"!!say("BANG!")&&last' # 52+1= 53 bytes

Press enter to pull the trigger, or ctrl+c to put it down.

Brad Gilbert b2gills

Posted 2015-12-16T09:16:53.303

Reputation: 12 713

1

Perl 5, 69 51 49 bytes

map{<>;print"*click*"}1..rand 6;<>;print"*BANG!*"

There is probably some more golfing potential, I will look into this.

Changes:

  • Saved 8 bytes by removing $l and some semicolons, and 10 bytes by changing <STDIN> to <>
  • Saved 2 bytes thanks to Oleg V. Volkov

ASCIIThenANSI

Posted 2015-12-16T09:16:53.303

Reputation: 1 935

149: map{<>;print"*click*"}1..rand 6;<>;print"*BANG!*" – Oleg V. Volkov – 2015-12-16T21:17:28.257

@OlegV.Volkov Thanks! I'll edit it in now. – ASCIIThenANSI – 2015-12-16T23:45:27.153

1

Ruby, 45+1=46

Not as clever as D-side's but slightly shorter.

With command-line flag p, run

rand(7-$.)<1?(puts'*BANG*';exit):$_='*click*'

The user can pull the trigger with return and leave with control-c. p causes the program to run in a loop, reading lines from STDIN and outputting $_. Each time it runs, it increments $.. So on the first run, it chooses a random positive integer less than 6, then 5, then 4, and so on. On the first 0, we output manually and exit, until then we output implicitly.

(and now I notice that there's already a very similar Perl. Oh well.)

histocrat

Posted 2015-12-16T09:16:53.303

Reputation: 20 600

0

VBA, 126 bytes

Golf Version for Minimal Bytes

Sub S()
r=Int(5*Rnd())
e:
a=MsgBox("")
If a=1 Then: If i=r Then MsgBox "*BANG!*" Else: MsgBox "*click*": i=i+1: GoTo e
End Sub

Fun Version that Makes The Buttons more Clear for Increased User Acceptance.

Sub RR()
r = Int(5 * Rnd())
e:
a = MsgBox("Are you Feeling Lucky?", 4)
If a=6 Then: If i=r Then MsgBox "*BANG!*", 16 Else: MsgBox "*click*", 48: i=i+1: GoTo e
End Sub

Some Fun with Custom Forms and You could make a pretty Slick Game in VBA.

JimmyJazzx

Posted 2015-12-16T09:16:53.303

Reputation: 691

0

APL, 39/65 bytes

{⍞⊢↑⍵:⍞←'*BANG*'⋄∇1↓⍵⊣⍞←'*click*'}6=6?6

Pretty straightforward answer.

Oberon

Posted 2015-12-16T09:16:53.303

Reputation: 2 881

What do the two byte counts mean? – Mego – 2015-12-17T09:37:47.997

0

C, 180 Bytes

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int main(){srand(time(NULL));int r,i=6;while(i!=1){getchar();r=rand()%i;if(r){puts("CLICK");}else{puts("BANG");exit(0);}i--;}}

My first attempt at code golf, there's probably a lot of room for improvement :)

Ryan Fitzpatrick

Posted 2015-12-16T09:16:53.303

Reputation: 101

0

Julia, 71 bytes

b=rand(1:6);while b>0 readline();print(b>1?"*click*":"*BANG!*");b-=1end

Press Enter to fire or Ctrl+C to quit. The latter ends with an InterruptException.

Ungolfed:

# Set an initial bullet location
b = rand(1:6)

while b > 0
    # Read user input
    readline()

    # Check the location
    if b > 1
        print("*click*")
    else
        print("*BANG!*")
    end

    b -= 1
end

Alex A.

Posted 2015-12-16T09:16:53.303

Reputation: 23 761

0

Lua, 73 bytes

q=io.read q()for i=2,math.random(6)do print"*click*"q()end print"*BANG!*"

Oleg V. Volkov

Posted 2015-12-16T09:16:53.303

Reputation: 171

0

R, 79 bytes

code

readline();for(n in 6:1)ifelse(1/n>=runif(1),cat("*Bang*"),readline("*click*"))

ungolfed

readline()                    # Waits for user to press [Enter] if [Esc] is pressed exits    
for(n in 6:1) {               # for n=6 to n=1
  ifelse(1/n >= runif(1),     # if 1/n >= a random float from 0 to 1 (uniform dist)
     cat("*Bang*"),           # *You're dead*
     readline("*click*")    # else you have another chance, waits for [Enter] again
  )                           
}

The program will wait for an [Enter] before every try, if the user press [Esc] instead the program will end. If the *Bang* happens the program will print it and throw an error, thus terminating itself (is this correct?).

Mutador

Posted 2015-12-16T09:16:53.303

Reputation: 1 361

0

C, 96 bytes (Without counting comment)

#define R 4//chosen by playing russian roulette, guaranteed to be random
int main(){for(;c++<R&&puts(c<R?"Fire?":"☠Bang!☠");getchar(),puts("*click*"));}

Formatted :

#define R 4 // chosen by playing russian roulette, guaranteed to be random
int main(int c) {
    for( ; c++ < R && puts(c < R ? "Fire?" : "☠Bang!☠") ; getchar(), puts("*click*") );
}

Explanation :

There also is a click when it fires, that's the sound of the hammer being released.

After the bang you need to hit enter to take the gun out of the dead man's hand, rigor mortis squeezed his finger around the trigger. While you are prying his hand open you hear another click as the trigger snaps back into normal position.

x13

Posted 2015-12-16T09:16:53.303

Reputation: 180