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!

• Your 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 Dec 16 '15 at 21:52
• @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 Dec 17 '15 at 10:26
• maybe 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 Dec 17 '15 at 11:53
• @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 Dec 19 '15 at 5:04

# 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.

• damn you, pyth! – Cyoce Dec 18 '15 at 1:55
• +3 bytes: the last string should be *BANG!*, not BANG – ayane Dec 18 '15 at 5:34

## 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) stdouts. 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 • Crossed out 64 is normal 64? – Cyoce Dec 18 '15 at 5:06 • @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 Dec 18 '15 at 7:51 • it was a pun on this – Cyoce Dec 19 '15 at 7:22 • @Cyoce oh, pardon me, first post and all that, not aware of the local lore :) – D-side Dec 19 '15 at 21:27 # 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 ) • "*Bang!*" is not greater than 7. But NaN is not smaller than 7. – Bergi Dec 16 '15 at 12:38 • @Bergi That's true. I reworded the explanation to make it a bit clearer. – user81655 Dec 16 '15 at 12:43 • @Bergi only in Javascript does that statement come even close to making sense. – MikeTheLiar Dec 16 '15 at 16:03 # 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 # 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. • 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 Dec 16 '15 at 10:04 • 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 Dec 16 '15 at 10:15 • stupid me forgot to reinitialize the string to empty before starting so thats why it showes BANG at the start... – Eumel Dec 16 '15 at 10:25 • No problem, I saw the gif now, looks like it works pretty well :) – Katenkyo Dec 16 '15 at 10:26 ## Pyth, 3130 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 • Your first one is actually shorter, you don't need the trailing". – FryAmTheEggman Dec 16 '15 at 14:06 • @FryAmTheEggman Oh, right, forgot about that. Thanks! – Doorknob Dec 16 '15 at 14:31 • 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 Dec 16 '15 at 14:38 • You can simply remove the chars .?. There is no need for an else. – Jakube Dec 16 '15 at 17:57 • @FryAmTheEggman confusing people is awesome. It can be amazing at filtering out the scrubs. – Cyoce Dec 18 '15 at 8:40 ## 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 # 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!*$

# 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*' # C, 11074 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!*"); } # 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 # 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. • Following Bruce's example, you can save a few bytes with from random import* – wnnmaw Dec 16 '15 at 17:25 • Unless there's something else I'm missing, it's one byte of savings. But I'll take it! Thanks! – Steve Eckert Dec 16 '15 at 17:30 • Nice attempt, I used your solution as an inspiration for my python 2 solution ^^ – basile-henry Dec 16 '15 at 17:52 # 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!*" # 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*"))) # R, 8680 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*')}) # Python 2, 108104102100 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 • 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 Dec 16 '15 at 16:58 • Yes, thanks a lot! I was actually trying to resolve that issue, didn't get to edit it correctly before you did. – ბიმო Dec 16 '15 at 17:02 • I get your byte count as 112, what did you use? – wnnmaw Dec 16 '15 at 17:22 • Also, you can save 2 bytes by doing a=shuffle([1,0,0,0,0,0]) – wnnmaw Dec 16 '15 at 17:22 • As 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? – ბიმო Dec 16 '15 at 17:33 # Perl 5, 40 bytes <>,print"*$_*"for(click)x rand 5,'BANG!'

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

# 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

## 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

;; 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*")))

# 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) • 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 Dec 16 '15 at 13:21 • @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 Dec 16 '15 at 13:29 • @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 Dec 16 '15 at 13:41 • 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 Dec 16 '15 at 13:50 • You're very welcome, glad to have helped! – Dom Hastings Dec 16 '15 at 13:51 # MATL, 41 bytes 6Yrj?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 > 6Yrj?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 > 6Yrj?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 # 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. # 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". # 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.) # Perl 5, 6951 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
• 49: map{<>;print"*click*"}1..rand 6;<>;print"*BANG!*" – Oleg V. Volkov Dec 16 '15 at 21:17
• @OlegV.Volkov Thanks! I'll edit it in now. – ASCIIThenANSI Dec 16 '15 at 23:45

# 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.

# APL, 39/65 bytes

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

• What do the two byte counts mean? – Mego Dec 17 '15 at 9:37

# 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 :)

# Julia, 71 bytes

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

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

b -= 1
end