Russian Roulette, Reloaded
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 aputs
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$><<
withp
. 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!*'
- Kudos to Martin Büttner for -4 extra bytes.
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 neitherfalse
nornil
.||
-expression is implicitly returned from the block. It's a short-circuit: it returns its first operand (unless it'snil
orfalse
) or a second one (otherwise). So it either returnstrue
(ifx<1
or, clearer but longerx == 0
) or the return value ofputs
, while...puts
always returnsnil
. Yep.gets
requests input. Merely hitting Enter suffices.- Ctrl+C terminates the program
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
)
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