31
\$\begingroup\$

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>

\$\endgroup\$
10
  • 3
    \$\begingroup\$ 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". \$\endgroup\$
    – rhialto
    Dec 16, 2015 at 21:52
  • 2
    \$\begingroup\$ @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. \$\endgroup\$ Dec 17, 2015 at 10:26
  • 2
    \$\begingroup\$ 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. \$\endgroup\$
    – rhialto
    Dec 17, 2015 at 11:53
  • 3
    \$\begingroup\$ Why was this not titled "Russian Roulette, Reloaded"? \$\endgroup\$ Dec 18, 2015 at 4:51
  • 1
    \$\begingroup\$ @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. \$\endgroup\$ Dec 19, 2015 at 5:04

32 Answers 32

14
\$\begingroup\$

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
\$\endgroup\$
4
  • \$\begingroup\$ Crossed out 64 is normal 64? \$\endgroup\$
    – Cyoce
    Dec 18, 2015 at 5:06
  • \$\begingroup\$ @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. \$\endgroup\$
    – D-side
    Dec 18, 2015 at 7:51
  • \$\begingroup\$ it was a pun on this \$\endgroup\$
    – Cyoce
    Dec 19, 2015 at 7:22
  • \$\begingroup\$ @Cyoce oh, pardon me, first post and all that, not aware of the local lore :) \$\endgroup\$
    – D-side
    Dec 19, 2015 at 21:27
9
\$\begingroup\$

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
  )
\$\endgroup\$
3
  • \$\begingroup\$ "*Bang!*" is not greater than 7. But NaN is not smaller than 7. \$\endgroup\$
    – Bergi
    Dec 16, 2015 at 12:38
  • \$\begingroup\$ @Bergi That's true. I reworded the explanation to make it a bit clearer. \$\endgroup\$
    – user81655
    Dec 16, 2015 at 12:43
  • 6
    \$\begingroup\$ @Bergi only in Javascript does that statement come even close to making sense. \$\endgroup\$ Dec 16, 2015 at 16:03
7
\$\begingroup\$

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
\$\endgroup\$
6
\$\begingroup\$

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.

\$\endgroup\$
4
  • \$\begingroup\$ 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!*"? \$\endgroup\$
    – Katenkyo
    Dec 16, 2015 at 10:04
  • \$\begingroup\$ 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 \$\endgroup\$
    – Eumel
    Dec 16, 2015 at 10:15
  • \$\begingroup\$ stupid me forgot to reinitialize the string to empty before starting so thats why it showes BANG at the start... \$\endgroup\$
    – Eumel
    Dec 16, 2015 at 10:25
  • \$\begingroup\$ No problem, I saw the gif now, looks like it works pretty well :) \$\endgroup\$
    – Katenkyo
    Dec 16, 2015 at 10:26
5
\$\begingroup\$

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
\$\endgroup\$
5
  • \$\begingroup\$ Your first one is actually shorter, you don't need the trailing". \$\endgroup\$ Dec 16, 2015 at 14:06
  • \$\begingroup\$ @FryAmTheEggman Oh, right, forgot about that. Thanks! \$\endgroup\$
    – Doorknob
    Dec 16, 2015 at 14:31
  • \$\begingroup\$ 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 \$\endgroup\$ Dec 16, 2015 at 14:38
  • 1
    \$\begingroup\$ You can simply remove the chars .?. There is no need for an else. \$\endgroup\$
    – Jakube
    Dec 16, 2015 at 17:57
  • \$\begingroup\$ @FryAmTheEggman confusing people is awesome. It can be amazing at filtering out the scrubs. \$\endgroup\$
    – Cyoce
    Dec 18, 2015 at 8:40
5
\$\begingroup\$

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
\$\endgroup\$
4
\$\begingroup\$

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.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ damn you, pyth! \$\endgroup\$
    – Cyoce
    Dec 18, 2015 at 1:55
  • \$\begingroup\$ +3 bytes: the last string should be *BANG!*, not BANG \$\endgroup\$
    – ayane_m
    Dec 18, 2015 at 5:34
4
\$\begingroup\$

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!*
$
\$\endgroup\$
4
\$\begingroup\$

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*'
\$\endgroup\$
1
4
\$\begingroup\$

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!*");
}
\$\endgroup\$
0
3
\$\begingroup\$

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
\$\endgroup\$
3
\$\begingroup\$

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

\$\endgroup\$
3
\$\begingroup\$

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!

\$\endgroup\$
0
2
\$\begingroup\$

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*")))
\$\endgroup\$
2
\$\begingroup\$

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*')})
\$\endgroup\$
2
\$\begingroup\$

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
\$\endgroup\$
11
  • \$\begingroup\$ 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! \$\endgroup\$
    – ProgramFOX
    Dec 16, 2015 at 16:58
  • \$\begingroup\$ Yes, thanks a lot! I was actually trying to resolve that issue, didn't get to edit it correctly before you did. \$\endgroup\$ Dec 16, 2015 at 17:02
  • \$\begingroup\$ I get your byte count as 112, what did you use? \$\endgroup\$
    – wnnmaw
    Dec 16, 2015 at 17:22
  • \$\begingroup\$ Also, you can save 2 bytes by doing a=shuffle([1,0,0,0,0,0]) \$\endgroup\$
    – wnnmaw
    Dec 16, 2015 at 17:22
  • 1
    \$\begingroup\$ 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? \$\endgroup\$ Dec 16, 2015 at 17:33
2
\$\begingroup\$

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.

\$\endgroup\$
3
  • \$\begingroup\$ Following Bruce's example, you can save a few bytes with from random import* \$\endgroup\$
    – wnnmaw
    Dec 16, 2015 at 17:25
  • \$\begingroup\$ Unless there's something else I'm missing, it's one byte of savings. But I'll take it! Thanks! \$\endgroup\$ Dec 16, 2015 at 17:30
  • \$\begingroup\$ Nice attempt, I used your solution as an inspiration for my python 2 solution ^^ \$\endgroup\$ Dec 16, 2015 at 17:52
2
\$\begingroup\$

Perl 5, 40 bytes

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

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

\$\endgroup\$
2
\$\begingroup\$

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.

\$\endgroup\$
0
1
\$\begingroup\$

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*")))
\$\endgroup\$
1
\$\begingroup\$

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)
\$\endgroup\$
14
  • \$\begingroup\$ 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... \$\endgroup\$
    – Codefun64
    Dec 16, 2015 at 13:21
  • \$\begingroup\$ @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? \$\endgroup\$
    – Codefun64
    Dec 16, 2015 at 13:29
  • \$\begingroup\$ @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!) \$\endgroup\$
    – Codefun64
    Dec 16, 2015 at 13:41
  • \$\begingroup\$ 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 :) \$\endgroup\$
    – Codefun64
    Dec 16, 2015 at 13:50
  • \$\begingroup\$ You're very welcome, glad to have helped! \$\endgroup\$ Dec 16, 2015 at 13:51
1
\$\begingroup\$

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
\$\endgroup\$
1
\$\begingroup\$

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.

\$\endgroup\$
1
\$\begingroup\$

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".
\$\endgroup\$
1
\$\begingroup\$

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

\$\endgroup\$
1
\$\begingroup\$

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
\$\endgroup\$
2
  • 1
    \$\begingroup\$ 49: map{<>;print"*click*"}1..rand 6;<>;print"*BANG!*" \$\endgroup\$ Dec 16, 2015 at 21:17
  • \$\begingroup\$ @OlegV.Volkov Thanks! I'll edit it in now. \$\endgroup\$ Dec 16, 2015 at 23:45
0
\$\begingroup\$

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.

\$\endgroup\$
0
\$\begingroup\$

APL, 39/65 bytes

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

Pretty straightforward answer.

\$\endgroup\$
1
  • \$\begingroup\$ What do the two byte counts mean? \$\endgroup\$
    – user45941
    Dec 17, 2015 at 9:37
0
\$\begingroup\$

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

\$\endgroup\$
0
\$\begingroup\$

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
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.