# Russian Roulette

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.

• 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. 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. Nov 27 '12 at 17:04
• Perhaps said bonus should involve dividing the score by 2. Feb 15 '13 at 15:46
• @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. Feb 15 '13 at 16:55

<?~$$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. ## R 30 "I survived!"[6*runif(1)<5||Z] One time out of six, it will throw an error: Error: object 'Z' not found ## Dyalog APL - 252221 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 • 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 Jan 21 '13 at 19:12 • 1÷0 is a DOMAIN ERROR in Dyalog but in ngn/apl it's . The result from ?6 is 1..6 when ⎕IO←1 (default in Dyalog) and 0..5 when ⎕IO←0 (only option in ngn/apl). In Dyalog, the PRNG can be seeded by setting ⎕RL. Initially it has some pre-determined default value. If you set ⎕RL←0, the PRNG is re-seeded fairly unpredictably by the OS. TryAPL is using Dyalog and does support the ? function. – ngn Dec 5 '14 at 23:43 • It's quite possible that something was changed back then, we are occasionally updating the software behind TryAPL or experimenting with features of the website. Am I affiliated? If I tell you, I'll have to kill you... well, with a probability of 1÷6 :) – ngn Dec 12 '14 at 0:22 • By the way, here's an 18-character solution: 'I survived!'⊣÷⍟?6 – ngn Dec 12 '14 at 0:37 ## 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 • Can be even shorter with 6/rand(6). 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!" 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. Nov 27 '12 at 7:43 ## J, 18 'I survived!'[q:?6 Failing with domain error when trying to factorise 0. • Does J seed its RNG automatically? – vsz Feb 15 '13 at 7:09 • @vsz Yes, with ?. You can use ?. for fixed seed. Feb 15 '13 at 7:14 ## 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. ## vba, 27 ?1/int(6*rnd),"I Survived!" used in immediate window. On failure, an error window stating: appears • Missing the ! in the text. Nov 26 '12 at 21:59 • @steenslag , fixed Nov 27 '12 at 3:22 • @SeanCheshire I've offered an alternative to your answer. 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!

# 05AB1E, 13 12 bytes

6LΩiFë“IÐ–d!

-1 byte thanks to @Emigna.

05AB1E actually shouldn't be able to error at all, but since the new version of 05AB1E still has some issues compared to the legacy version, I can take that to my advantage to error out for this challenge.

Try it online.

Explanation:

6L          # Create the list [1,2,3,4,5,6]
Ω         # Get a random choice from this list
i        # If it is 1:
F       #  Do a ranged loop, which currently results in a "(RuntimeError) Could not
#  convert  to integer." error when no argument is given
ë        # Else:
“IÐ–d!  #  Push dictionary string "I survived!" (which is output implicitly as result)

See this 05AB1E tip of mine (section How to use the dictionary?) to understand why “IÐ–d! is "I survived!".

• Seems like 5ÝΩz“IÐ–d! should work but apparently 1 / 0 = 0. Apr 10 '19 at 17:17
• @MagicOctopusUrn Yeah, 05AB1E almost never errors.. Apart from the pretty old builtin .0 which used to throw a division by 0 error to STDERR in an old version of 05AB1E, I don't even know how to error in the legacy 05AB1E at all.. The new version still has quite a lot of errors however, which I took to my opportunity here. ;) Apr 10 '19 at 19:02
• I miss the old .0, on more than one occasion it made someone go "Wat... Why is that a command?" Apr 10 '19 at 19:14

## C, 6765 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!");
}
• 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. Nov 25 '12 at 8:51
• @vsz, fixed now - no extra output in any case. Also works with optimization, and 2 characters shorter. Nov 25 '12 at 8:59

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

• -1 and ceiling are not needed. cast will truncate 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. 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. Nov 30 '12 at 16:55
• I doubt you have tested this script more than 20 times. This doesn't always return the expected result always. 1 in 6 this will fail and not return an output. This syntax will work: 0/floor(rand()*6)=0 Apr 9 '19 at 7:54

Javascript, 42

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.

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.
• 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!" Nov 28 '12 at 17:46

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

• 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. Dec 5 '12 at 18:31
• I reported this, and it has been fixed (along with another bug I stumbled across) in the latest version of the GolfScript interpreter. 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.

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

• 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+). 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 :) 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. Dec 5 '12 at 14:01
• I count 29 bytes. Nov 16 '17 at 23:39

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

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

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

# 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

• I tried R, and couldn't get it to fail - if(1/0)"I Survived!" still printed I Survived 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',) Nov 27 '12 at 23:05

## Emacs-Lisp, 42 characters

(if (= (random 6) 5)
z (message "I survived!")
)

## Javascript, 40 chars

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

Not so short, though fun :)

PowerShell, 40 Chars

IF(6/(Get-Random -Max 6)){'I Survived!'}

On Failure: "Attempted to divide by zero."

• Welcome to PPCG! Apr 8 '19 at 21:29
• 32 bytes Apr 9 '19 at 6:24
• 31 bytes Jul 12 '19 at 12:48

# TI-BASIC (TI-84+/SE), 36 bytes

startTmr→rand:1/(1<randInt(1,6:"I survived!

There is no input, as the challenge specifies.
Output is I survived! if successful, a DIVIDE BY 0 error otherwise.

The DIVIDE BY 0 error screen looks like the following:

ERR:DIVIDE BY 0
1:Quit
2:Goto

Selecting either option (and returning to home screen if 2 is selected) shows Error after the program call.

Examples:

prgmCDGFE
Error
prgmCDGFE
I survived!
prgmCDGFE
I survived!
prgmCDGFE
Error

Explanation:

startTmr→rand:1/(1<randInt(1,6:"I survived!   ;full program

startTmr→rand                                 ;store the current time into "rand"
; this is necessary because "rand" is 0 after
; factory reset, the default state for TI-BASIC
; submissions
randInt(1,6                ;get a random integer in [1,6]
1<                           ;is greater than 1?  1 if true, 0 if false
1/(                             ;divide 1 by the result
; throws "DIVIDE BY 0" error if result was
; false
"I survived!   ;leave this string in "Ans"
;implicitly print "Ans"

Notes:

• TI-BASIC is a tokenized language. Byte count does not equal character count.

• Lowercase letters are two bytes each.

• Lowercase letters can be enabled using this assembly program.
• startTmr is a command only on the TI-84+ and TI-84+ SE calculators. Said calculators have different operating systems.

# Python, 53 bytes

Here's a short 53 byte python index out of range program:

import time
[0][time.time()%6<1]
print("I survived!")
• Hi and welcome. Please note that in the rules for this challenge, it states "MOD 6 will not be sufficient." Although I'm not familiar with Python, it looks to me like you are using Modulo here. May 10 '19 at 11:56
• @ShaunBebbers The quote is "This means an uninitialized variable (or a RNG without seed) MOD 6 will not be sufficient," but this meta post says that current time modulo is enough for a PRNG for code-golf May 10 '19 at 13:26
• My misunderstanding then. May 10 '19 at 13:51

# Befunge-98 (FBBI), 28 bytes

r?<?
"< <@,ka"I survived!
=

Try it online!

Errors with a segmentation fault.

## Explanation

Befunge-98 adds some extra features (r, k, and =) that can be used to further golf Joe K's Befunge-93 answer.

The first line (r?<?) calculates the 1/6 chance. The r initially reflects the IP to the left, where it reaches the second ? and goes in a random direction. If it goes right, the r reflects it and it tries again. If it goes up or down, it moves onto the second line, and if it goes left, it moves onto the first ?. There are three ways the IP can leave, so there is a 1/3 chance it moves onto the first ?. If it gets there, it again goes in a random direction. If it goes horizontally, it gets reflected (with either r or <) and tries again. This means that there are only two ways that the IP can leave, and they are equally likely. Either it goes down onto the second line, or it goes up and hits the = on the third line.

There is a 1/6 chance that = is executed (1/3 from the second ? times 1/2 from the first). If it is, it does a system-execute call on the stack (which is empty and interpreted as an empty string). FBBI's implementation of this runs a C system() call on the empty string, which segfaults.

This leaves a 5/6 chance that the IP reaches the second line. If it does, it gets sent left with <, and pushes the string "!devivrus I" onto the stack. ak, prints the top 11 characters of the stack, outputting I survived! Finally, @ ends the program.

# Jelly, 12 bytes

6X’’Xṛ“:ƭ÷»

Try it online!

## Explanation

6X            Generate a random number between 1 and 6 inclusive (using python randrange)
’’          Decrement it twice
X         Generate a random number from 1 to the above value. 0 if the value is 0. Error if the value is negative (1/6 chance)
ṛ        Right Argument; ignore the above value and instead return
“`:ƭ÷»  "I survived!"

Unfortunately, taking the reciprocal of 0, dividing or integer-dividing by 0, and modulo by 0 all give either inf or nan, and don't actually error.

• It's nice to have exactly one documented error in the docs for challenges like these. May 14 at 16:25
• @Razetime yep :D it's the only result when ctrl-f'ing "error" in jelly docs. of course there are a bunch of other ways but most of those errors come from writing the code wrong, not the actual runtime. i suppose i could get a line of STDIN which would EOF but IDK if that's allowed and this is easier anyway May 14 at 16:26

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

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

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

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

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