Take the 2-minute tour ×
Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

Write a program which plays Russian Roulette!

If the program is started,

  • there should be a 5 in 6 chance of it ending normally after printing "I survived!"
  • there should be a 1 in 6 chance of the program crashing. (segmentation fault, etc.)

No input, and no other outputs are allowed.

The randomness must be fair: it must have a uniform probability distribution. This means an uninitialized variable (or a RNG without seed) MOD 6 will not be sufficient.

If the solution works with only one dedicated operating system / platform, you will receive a 6 byte penalty to the score.

Shortest code wins, not sooner than 10 days after first valid answer.

share|improve this question
    
Can we rely on the underlying runtime to be fair, even if not explicitly guaranteed in documentation? E.g. Python's randrange(5) might be implemented as randrange(MAX_INT)%6. –  ugoren Nov 26 '12 at 5:35
    
To inspire creativity, you might consider granting a bonus to those solutions which don't rely on division by zero. –  primo Nov 27 '12 at 17:04
    
Perhaps said bonus should involve dividing the score by 2. –  Joe Z. Feb 15 '13 at 15:46
1  
@JoeZeng : that would have been too much. Usually you can make it a different error, like null pointer reference, etc. for the cost of just a few characters. –  vsz Feb 15 '13 at 16:53
    
I see. I'm not too experienced in creating scoring conditions for code golf puzzles, so I'm still learning stuff like that. –  Joe Z. Feb 15 '13 at 16:55

25 Answers 25

up vote 2 down vote accepted

J, 18

'I survived!'[q:?6

Failing with domain error when trying to factorise 0.

share|improve this answer
    
Does J seed its RNG automatically? –  vsz Feb 15 '13 at 7:09
    
@vsz Yes, with ?. You can use ?. for fixed seed. –  randomra Feb 15 '13 at 7:14

PHP 38 bytes

<?~$$s[rand(+$s=sssss,5)]?>I survived!

Placing a + before a non-numeric string will evaluate to 0. Should rand(0,5) return 5, $s[rand(0,5)] will be the empty string (since $s is only five characters long), and subsequently $$s[rand(0,5)] will be an uninitialized variable. Attempting to take the inversion will halt on Unsupported Operand Type. Any other value, 0-4 will return s, and because $s is defined, you will survive.

Note: as of php version 4.2.0, the random number generator is seeded automatically.

share|improve this answer

vba, 27

?1/int(6*rnd),"I Survived!"

used in immediate window.
On failure, an error window stating:
division by zero
appears

share|improve this answer
    
Missing the ! in the text. –  steenslag Nov 26 '12 at 21:59
    
@steenslag , fixed –  Sean Cheshire Nov 27 '12 at 3:22
    
@SeanCheshire I've offered an alternative to your answer. –  Gaffi Feb 12 '13 at 12:21

Befunge - 48 chars

 v >91+"!devi"v
/?>?<v"I surv"<
 / / :
   :,_@#

Befunge's only randomness is the ? operator, which sends you heading in one of four posible directions (1/4 chance). By blocking one or two directions, you have 1/3 or 1/2 chance, and by combining these, you get 1/6 chance to get out of the program "alive".

The program crashes by doing a divive-by-zero. I guess it's implementation-specific what will happen (on Wikipedia it says the program should ask for the desired answer), but befungee.py sort of crashes, or exits angrily:

$ for i in {1..6} ; do ./befungee.py roulette.befunge ; done
Error (1,2): integer division or modulo by zero
Error (3,2): integer division or modulo by zero
Error (1,2): integer division or modulo by zero
I survived!
Error (0,1): integer division or modulo by zero
I survived!
share|improve this answer

Ruby, 24-28

p rand(6)<5?"I survived!":1/0

Approx each 6 time, there is a ZeroDivisionError

There is even a shorter version with 24 characters (Thanks to ugoren and histocrat):

6/rand(6);p"I survived!"

If you don't accept the " in the output, then I need 3 more characters. The first option (puts) adds a newline, the second ($><<) makes no newline:

6/rand(6);puts"I survived!"
6/rand(6);$><<"I survived!"

There is a question about random number in ruby at SO. The seed with srand is automatically called with the seed being from the current time if it wasn't already called. (see Julians comment)


Primo had the idea for an extra bonus to those solutions which don't rely on division by zero.

My first solution can be shortened (28 characters) with a undefined local variable or method ``a' for main:Object (NameError)

p rand(6)<5?"I survived!":a
share|improve this answer
    
Can be even shorter with 6/rand(6). –  ugoren Nov 26 '12 at 5:36
    
Does Ruby seed its RNG automatically? –  vsz Nov 26 '12 at 7:08
    
You can trim another three characters by removing the control flow: 1/rand(6);p "I survived!" –  histocrat Nov 26 '12 at 23:30
    
@ugoren / histocrat Thanks for your hints, I adapted my solution. –  knut Nov 26 '12 at 23:36
    
Another byte for you: no white space is required between p and "I survived!". By my count, that's only 24 bytes. –  primo Nov 27 '12 at 7:43

Dyalog APL - 25 22 21 20 Charachters

'I Survived!'⊣1÷6⊤?6

Prints DOMAIN ERROR as the error, due to division by zero.

Shortest non-division by zero solution I could come up with is 23 characters.

('I Survived!'1)[~6⍷?6]

It throws an INDEX ERROR

Try it here

APL Font here

share|improve this answer
    
I would like to accept it, but it does not seem to work. A few times it prints "I survived", but after printing DOMAIN ERROR once, it keeps printing only that. Even if I reload the site completely, it will never ever survive again. –  vsz Jan 19 '13 at 11:45
    
@vsz How strange... It works in my Dyalog APL WS, and I remember testing it with TryAPL when I was done. It still works on my interpreter, but not on the website. If this helps: dl.dropbox.com/u/9086539/apl.png –  MrZander Jan 21 '13 at 19:12
    
I tried it with other interpreters, like ngn.github.com/apl/web/index.html but it doesn't work. Please provide a link to an interpreter where it works, possibly with an explanation whether the RNG must be seeded or is seeded automatically. Otherwise I'll have to accept the golfscript solution. –  vsz Feb 11 '13 at 16:29
    
@vsz I have updated my post to reflect that I am using Dyalog APL. I was under the assumption that tryapl was using Dyalog (and I am confident that it was when I submitted this post). But now it seems to be missing the ? operator. Either way, I am no longer confident in the RNG being seeded automatically. –  MrZander Feb 11 '13 at 18:33

Python, 96

from ctypes import*
from random import*
randrange(5)or pointer(c_int())[9**9]
print'I survived!'

If randrange(5) returns 0, then python will crash due to a segmentation fault.

share|improve this answer

R 30

"I survived!"[6*runif(1)<5||Z]

One time out of six, it will throw an error: Error: object 'Z' not found

share|improve this answer

GolfScript, 21 chars

,6rand/;'I survived!'

Like most of the answers, this one has a one in six chance of crashing with a ZeroDivisionError. The shortest solution I could manage without using division by zero is 23 chars:

5,6rand=+;'I survived!'

which has a 1/6 chance of crashing with undefined method `+' for nil:NilClass (NoMethodError).

(Ps. While developing this, I found what might be a bug in the GolfScript interpreter: code like 0,1> appears to leave a nil value on the stack, which will later crash the program if you try to do anything with that value except pop it off and throw it away with ;. Unfortunately, the fact that I do need to use the value somehow to trigger a crash means that even exploiting this bug didn't help me get below 23 chars.)

share|improve this answer
    
That definitely seems like a bug. 5,5> leaves [] on the stack, which is probably what it should do, but 4,5> leaves nil. If you don't remove it, the interpreter will actually crash while trying to output it. An interesting side-effect is that 4,6rand>+;'I survived!' becomes a valid solution. Someone should probably inform Flagitious. –  primo Dec 5 '12 at 18:31
1  
I reported this, and it has been fixed (along with another bug I stumbled across) in the latest version of the GolfScript interpreter. –  Ilmari Karonen Dec 13 '12 at 20:47

Python, 70 characters

With inspiration from grc's answer.

from random import*
if randrange(5)<1:exec'()'*9**5
print'I survived!'

randrange(5) returns a value between 0 and 5.
If it returns a 0, Python crashes while attempting to exec(ute) a string of code that contains 9^5 sets of parentheses.

share|improve this answer

PHP - 30 bytes

<?rand(0,5)?:~[]?>I survived!

Requires PHP 5.4+ for the short array syntax, invalid operator idea shamelessly stolen from @primo.

As stated, rand() is automatically seeded on first use.

share|improve this answer
    
Division by zero does not halt, it only produces a warning, as well as the text 'I survived!'. Also, rand()%6 is not a uniform distribution, as 32768 = 2 (mod 6). However, rand(0,5)||~$a for 30 bytes is, and will additionally work with all PHP versions (the second expression in a ternary is only optional in 5.3.0+). –  primo Dec 5 '12 at 10:24
    
@primo Guess I was only looking for the stack trace when I was checking the divide by zero one, didn't notice it still printed. I know the ternary shorthand is 5.3+, but I really have no interest in supporting long out of date versions :) –  Leigh Dec 5 '12 at 12:03
    
That I agree with. There's no valid argument for continuing to use less than 5.3 at this point. 5.4, I'm still holding out for a double-digit revision number. –  primo Dec 5 '12 at 14:01

Befunge, 38

v>25*"!devivrus I",,,,,,,,,,,@
?^
v
?^
<1

Pretty straight-forward. Crashing is done by pushing 1s onto the stack until it overflows. I made a few attempts at cutting out those 11 commas and replacing them with some more efficient loop to print everything, but couldn't get it under 11 characters.

Note that counting characters in Befunge is a little tricky... For instance there's only one character on the third line, but I'm counting an extra one there since execution could travel through that location.

share|improve this answer
    
I believe that's the record for the most consecutive commas I've ever seen in a program. –  Joe Z. Feb 15 '13 at 15:47
    
And then I look up how Befunge actually works and palm my face. –  Joe Z. Feb 15 '13 at 15:48

Javascript, 42

(Math.random()*6|0)?alert('i survived!'):b

The bitwise or floors the result of the multiplication thus a value between 0 and 5 results. 0 gets implictly casted to false, so in 5 of 6 cases the alert appears in the 6th case a certain b is referenced, crashing the process.

share|improve this answer

Using the usual divide by zero method:

Perl 5.8 Version

1/(int rand 6)&&print "I survived!"

Perl 5.10 Version

1/(int rand 6)&&say "I survived!"

On failure, these will display:

Illegal division by zero at -e line 1.

Using the bless function which is used for creating objects in perl.

Perl 5.8 Version

print (int rand 6?"I survived!":bless me);

Perl 5.10 Version

say (int rand 6?"I survived!":bless me);

On failure, these will display:

Can't bless non-reference value at -e line 1.
share|improve this answer
3  
a few suggestions: get rid of parentheses, the logical &&, and the extra space. use ~~ instead of int to force integral values. the result is this: 1/~~rand 6;print"I survived!" –  ardnew Nov 28 '12 at 17:46

R, 50 44 42 36

ifelse(!is.na(sample(c(NA,1:5),1)),'I Survived!',)

ifelse(floor(runif(1,0,5))>0,'I Survived!',)

ifelse(floor(runif(1,0,5)),'I Survived!',)

ifelse(sample(0:5,1),'I Survived!',)

Death Err Message:

Error in ifelse(!is.na(1/sample(c(NA, 1:5), 1)), "I Survived!", ) : argument "no" is missing, with no default

share|improve this answer
    
I tried R, and couldn't get it to fail - if(1/0)"I Survived!" still printed I Survived –  Sean Cheshire Nov 27 '12 at 22:55
    
Unlike other languages, R doesn't consider 1/0 to be a math error and doesn't stop execution, it just returns inf for 1/0. I think @vsz wants a breaking error for this round. But supposing vsz counted NA as the death error, I could get my program down to 41 characters: ifelse(sample(c(NA,1:5),1),'I Survived',) –  freewary Nov 27 '12 at 23:05

Emacs-Lisp, 42 characters

(if (= (random 6) 5) 
    z (message "I survived!")
    )
share|improve this answer

Javascript, 40 chars

In Javascript the divide-by-zero trick doesn't even work: it just returns Infinity. Therefore, referencing a non-existing variable:

alert(6*Math.random()|0?"I survived!":f)

Not so short, though fun :)

share|improve this answer

C, 67 65 62 chars

rand()%8 doesn't lose fairness. Division crashes for t=0, gives true for 1 and 2 (retry), gives false for 3..7 (survived).
EDIT: The previous version used a temporary variable, which ended up completely unneeded. 2/(rand()%8) implements both needed conditions.

main(){
        for(srand(time(0));2/(rand()%8););
        puts("I survived!");
}
share|improve this answer
    
It does. "no other outputs are allowed" –  vsz Nov 25 '12 at 8:35
    
@vsz, somehow missed it. But anyway, with gcc/Linux it doesn't print anything. Also, strictly adhering to the standard, this requirement is impossible, because undefined behavior might print anything. –  ugoren Nov 25 '12 at 8:51
    
@vsz, fixed now - no extra output in any case. Also works with optimization, and 2 characters shorter. –  ugoren Nov 25 '12 at 8:59

CMD Shell (Win XP or later), 40 +6

I'm only doing this one because DOS is not something that should even be thought of for code golf, and the whitespace is important

set/a1/(%RANDOM% %% 6)&&echo I Survived!

On failure, it will print

Divide by zero error.

share|improve this answer

Java, 149

public class R{public static void main(String[]s){int[]a={1,1,1,1,1};System.out.println(a[new java.util.Random().nextInt(7)]>0?"I survived!":"");}}

Fails with an "Array out of bounds" error. Managed to shave a few characters by using anonymous Random object (no imports).

share|improve this answer

Groovy, 39

1/new Random().next(6);print"I survived!"

Picks a random number between 0 and 5 inclusive. If 0, throws a divide by zero exception.

share|improve this answer

T-SQL 56 44 40 + 6

 if 1/cast(ceiling(rand()*6)-1as int)<2print'I Survived!'

Credit Sean Cheshire for calling out cast as unnecessary

 if 1/ceiling(rand()*6-1)<2print'I Survived!'

Credit personal message from Sean Cheshire for suggestion to change ceiling to floor.

 if 1/floor(rand()*6)<1print'I Survived!'

Death Err Msg: Msg 8134, Level 16, State 1, Line 3 Divide by zero error encountered.

share|improve this answer
1  
-1 and ceiling are not needed. cast will truncate –  Sean Cheshire Nov 28 '12 at 16:13
    
I'm testing if ceiling can be removed without violating the requirement for uniform distribution, the docs say that rand() returns float values 0 through 1. –  freewary Nov 28 '12 at 16:30
    
I wanted to know if ceiling could be removed from my first entry. I was unable to determine from T-SQL documentation if the rand() function would ever return a 1 or not. So I ran a loop about 50 million times testing the rand() function, never once did it return a 1. But, removing ceiling from my first entry would still be 47 bytes, so my second entry is still shorter. Keep ceiling and remove cast. –  freewary Nov 30 '12 at 16:55

Python (56), Haskell (77)

This crashes with an IndexError when the generated number is 1:

from random import*
print['I survived!'][1/randint(1,7)]

The Haskell solution has the same idea:

import System.Random
main=putStrLn.(["I survived!"]!!).div 1=<<randomRIO(1,6)
share|improve this answer

Python, 59 55 53, 65 59 56

import os
1/(ord(os.urandom(1))%6)
print"I survived!"

ZeroDivisionError when ord(os.urandom(1))%6 evaluates to 0

import os
print(["I survived!"]*5)[ord(os.urandom(1))%6]

IndexError when ord(os.urandom(1))%6 evaluates to 5

share|improve this answer
    
Save 5 characters by changing the import: import random as r then use r.randint –  Steven Rumbalski Feb 11 '13 at 20:50
1  
Or save 8 characters by changing import to import os, then use ord(os.urandom(1))%6 as your random int. –  Steven Rumbalski Feb 11 '13 at 20:59
    
Save 1 character by removing the space after print. –  Steven Rumbalski Feb 11 '13 at 21:01

VBA - 39/46

I don't love Sean Cheshire's numeric output (though still a good answer, it technically fails the No input, and no other outputs are allowed. from the spec...), plus he uses /0, so here are my alternatives:

?Mid("I Survived!",IIf(Int(6*Rnd),1,0))

This resolves to a Run-time error '5': Invalid procedure when trying to reach character 0 (VBA is 1-based indexing).

n="I Survived!":If Int(6*Rnd) Then ?n Else ?-n

This resolves to a Run-time error '13': Type mismatch when applying a negative switch to a string.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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