28
\$\begingroup\$

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.

\$\endgroup\$
  • 1
    \$\begingroup\$ 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. \$\endgroup\$ – ugoren Nov 26 '12 at 5:35
  • \$\begingroup\$ To inspire creativity, you might consider granting a bonus to those solutions which don't rely on division by zero. \$\endgroup\$ – primo Nov 27 '12 at 17:04
  • \$\begingroup\$ Perhaps said bonus should involve dividing the score by 2. \$\endgroup\$ – Joe Z. Feb 15 '13 at 15:46
  • 1
    \$\begingroup\$ @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. \$\endgroup\$ – vsz Feb 15 '13 at 16:53
  • \$\begingroup\$ I see. I'm not too experienced in creating scoring conditions for code golf puzzles, so I'm still learning stuff like that. \$\endgroup\$ – Joe Z. Feb 15 '13 at 16:55

46 Answers 46

1
\$\begingroup\$

VB.Net, 38 bytes

If(CInt(Rnd() * 6), "I survived!", Dir())

Throws : System.ArgumentException 'Dir' function must first be called with a 'PathName' argument.

Spaces removed :

If(CInt(Rnd()*6),"I survived!",Dir())
\$\endgroup\$
  • 1
    \$\begingroup\$ Welcome to PPCG :) Couple of things: you should include your solution's byte count in the header, I'm pretty sure you can remove all the spaces, and, could you use a single character, undefined function name instead of Dir? Also, does VB.Net have bitwise operators? \$\endgroup\$ – Shaggy Apr 11 '19 at 20:35
  • \$\begingroup\$ Thanks for the welcome and tips - first attempt at code golf! VB.Net will not compile an undefined function name, so I picked an inbuilt with the smallest number of chars. \$\endgroup\$ – Benno Apr 12 '19 at 10:00
1
\$\begingroup\$

C# (Visual C# Interactive Compiler), 48 bytes

Write(1/new Random().Next(6)<9?"I survived!":"")

Try it online!

Throws Attempted to divide by zero. if a random number in the range [0,6) is 0.

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

Python 2, 49 bytes

import os
print["I survived!"][os.urandom(1)<'+']

Try it online!

Utilises the idea from this answer of using os.urandom, but we save some bytes by avoiding the ord call.

os.urandom(n) generates n random bytes. By checking if they are smaller than chr(math.ceil(256.0/6)) (== '+'), we get an approximately 1/6 chance of True (== 1).

\$\endgroup\$
  • \$\begingroup\$ Is the chance one in six though? It's not clear so maybe an explanation will help. \$\endgroup\$ – Shaun Bebbers May 10 '19 at 11:14
  • 1
    \$\begingroup\$ @ShaunBebbers explanation added. Since 256%6 != 0 the chance is not exactly one in six, but many answers here approximate those odds slightly. \$\endgroup\$ – ArBo May 10 '19 at 11:21
0
\$\begingroup\$

Tcl, 64 bytes

puts [expr srand([clock se])*0+int(rand()*6)%6?"I survived":1/0]

Try it online!

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

Microscript II, 20 bytes

6R("I survived!"ph)f
\$\endgroup\$
0
\$\begingroup\$

C++, 105 bytes

#include<iostream>
#include<ctime>
int f(){srand(time(0));delete(int*)!(rand()%6);printf("I survived!");}

In C++, delete behavior is that on 0 ( or nullptr ), nothing occurs

Not as cool ( nor dangerous ) as CommitStrip's russian roulette

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

Forth (gforth), 51 bytes

include random.fs
: f 1 6 random / ." I Survived!";

Try it online!

Explanation

Randomly gets a number between 0 and 5 (inclusive) Divides 1 by the result Crashes with divide by zero error if random number is 0

Code Explanation

include random.fs       \ include the library file necessary for random to work
: f                     \ start a new word definition
  1                     \ place 1 on the stack
  6 random              \ get a random number between 0 and 5 (inclusive)
  /                     \ divide 1 by the result of the random call
  ." I Survived!"       \ print "I Survived!"
;                       \ end word definition
\$\endgroup\$
0
\$\begingroup\$

JVM Bytecode -noverify, 372 bytes

Works by passing a wrong type to the print function if Random.nextInt(6) is 0.

Hexdump of the class:

$ xxd.exe Code.class
00000000: cafe babe 0003 002d 0020 0c00 1900 1f01  .......-. ......
00000010: 0016 285b 4c6a 6176 612f 6c61 6e67 2f53  ..([Ljava/lang/S
00000020: 7472 696e 673b 2956 0100 106a 6176 612f  tring;)V...java/
00000030: 7574 696c 2f52 616e 646f 6d01 0006 3c69  util/Random...<i
00000040: 6e69 743e 0c00 0400 0803 0000 0006 0700  nit>............
00000050: 1001 0003 2829 5607 0014 0100 0443 6f64  ....()V......Cod
00000060: 6501 0004 6d61 696e 0900 0900 0101 000a  e...main........
00000070: 536f 7572 6365 4669 6c65 0100 076e 6578  SourceFile...nex
00000080: 7449 6e74 0c00 1100 1a01 0013 6a61 7661  tInt........java
00000090: 2f69 6f2f 5072 696e 7453 7472 6561 6d01  /io/PrintStream.
000000a0: 0007 7072 696e 746c 6e0a 0013 001d 0700  ..println.......
000000b0: 0301 0010 6a61 7661 2f6c 616e 672f 5379  ....java/lang/Sy
000000c0: 7374 656d 0a00 1300 050a 0007 000f 0100  stem............
000000d0: 0428 4929 4907 000a 0100 036f 7574 0100  .(I)I......out..
000000e0: 1528 4c6a 6176 612f 6c61 6e67 2f53 7472  .(Ljava/lang/Str
000000f0: 696e 673b 2956 0100 0b49 2073 7572 7669  ing;)V...I survi
00000100: 7665 6421 0800 1b0c 000e 0017 0100 0001  ved!............
00000110: 0015 4c6a 6176 612f 696f 2f50 7269 6e74  ..Ljava/io/Print
00000120: 5374 7265 616d 3b00 2000 1800 1300 0000  Stream;. .......
00000130: 0000 0100 0900 0b00 0200 0100 0a00 0000  ................
00000140: 2900 0500 0100 0000 1db2 000c bb00 1359  )..............Y
00000150: b700 1512 06b6 0012 9a00 0812 06a7 0005  ................
00000160: 121c b600 16b1 0000 0000 0001 000d 0000  ................
00000170: 0002 001e                                ....

Jasmin code to generate:

.source ""
.class Code
.super java/util/Random
.method public static main([Ljava/lang/String;)V
    .limit stack 3
    getstatic java/lang/System/out Ljava/io/PrintStream;
    new java/util/Random
    dup 
    invokenonvirtual java/util/Random/<init>()V
    ldc 6
    invokevirtual java/util/Random/nextInt(I)I
    ifne Survive
    ldc 6
    goto Print
    Survive:
    ldc "I survived!"
    Print:
    invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V
    return
.end method

Must to be run with java -noverify to prevent Java from realizing that the class is messed up.

Also it's very wrong this time but CFR output for fun:

/*
 * Decompiled with CFR 0.142.
 */
import java.io.PrintStream;
import java.util.Random;

class Code
extends Random {
    public static void main(String[] arrstring) {
        if (new Random().nextInt(6) != 0) {
            String string = "I survived!";
        }
        System.out.println((String)6);
    }
}
```
\$\endgroup\$
0
\$\begingroup\$

C (gcc), 58 bytes

Floating point exception when rand() is divisible by 6

main(i){i/=(srand(time(0))+rand()%6);puts("I survived!");}

Try it online!

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

GNU Bash -- 37 bytes

! followed by nothing doesn't trigger history substitution. $[...] is alternative syntax for arithmetic. (...) is a subshell.

This solution is portable. bash itself does fork but doesn't exec any other programs.

(exit $[$RANDOM%6])&&echo I survived!
\$\endgroup\$
0
\$\begingroup\$

Perl 6, 34 bytes

(^6 .roll&&say "I survived!")||die

Throws an exception to crash.

Try it online!

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

MathGolf, 15 bytes

6rw/;'I ûÄ%$╦'!

Try it online!

Explanation

6r                push [0, 1, 2, 3, 4, 5]
  w               random item from list
   /              divide implicit zero by the random element
    ;             discard TOS (needed for non-crashes)
     'I           push single character "I"
                  space character
        ûÄ%       push "Ä%"
           $      convert to ordinal (from base 256 to base 10)
            ╦     fetch single dictionary word "survived"
             '!   push single character "!"

With some better handling of dictionary fetches, this could probably be 2-3 bytes shorter, but that's not getting implemented within the immediate future.

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

Octave 33 bytes

{"I_Survived!"}(1/(rand(1)>0.16))

Approx each 6 time, there is a warning: division by zero error: index (inf): subscripts must be either integers 1 to (2^31)-1 or logicals

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

Java, 98 bytes

interface m{static void main(String[]a){System.out.print(Math.random()<.16?1/0:"I survived!");}}

Try it online

Bonus answer that allocates 2^60 bytes of memory instead of dividing by 0:

import sun.misc.Unsafe;import java.lang.reflect.*;interface M{static void main(String[]a)throws Exception{Field f=Unsafe.class.getDeclaredField("theUnsafe");f.setAccessible(1>0);((Unsafe)f.get(null)).allocateMemory(Math.random()<.16?1L<<60:0);System.out.print("I survived!");}}

TIO

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

Commodore C64/128, C64Mini and compatibles, 101 95 tokenised BASIC bytes + 6 penalty bytes for only working in Commodore BASIC

As Commodore keyword abbreviations, you may enter it as follows:

 0a$="i survived":fOi=0to5:a$(i)=a$:nE:a$(rN(.)*6)="":x=6*rN(.)
 1?len(a$(x))/len(a$(x))"{left}{left}"a$(x)

I found a six-tokenised byte saving by not using the INT keyword when assigning a value with RND and CBM BASIC will automatically convert the key value to it's integer by ignoring the decimal places.

Non-obfuscated for explanatory purposes:

 0 let a$="i survived"
 1 for i=0 to 5
 2 let a$(i)=a$
 3 next i
 4 let a$(int(rnd(0)*6)=""
 5 let x=int(rnd(0)*6)
 6 print len(a$(x))/len(a$(x));"{left}{left}";a$(x)

Firstly, we set up a$ as a string and we later use it as an array; in Microsoft [Commodore] BASIC that appeared on the PET, VIC-20, C64 etc... you can set up the first 11 elements of a zero-indexed array without expressly declaring it first, though it saves space on the variable stack if you do and you have fewer than 11 elements.

So our string array of six elements are set to the string literal of i survived. One of those elements is randomly reset to an empty string.

The x variable is then used to select which of the six will be displayed (one of which is empty). Finally, we try to divide the length of that element with itself; usually this would produce an output of 1 except where the string length of the element is 0, so 0/0 will produce an error (one in six chance) and halt the execution of the symbolic listing; otherwise, the print command moves the cursor position back two spaces to overwrite the output with the string literal of the array element x, or i survived.

This answer assumes that the division by zero error reported by BASIC (which halts the programs execution by the interpreter) is acceptable as the program crashing as cited above.

Commodore 64 Russian Roulette

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

Runic Enchantments, 23 bytes

>6'RA0)?;"I survived!"@

Try it online!

Nothing too special here. Just an IP that picks a random number [0-6) and prints the required string if the random value isn't 0.

Required string contains two vs which also creates an IP each that get terminated after 100k execution steps (otherwise TIO would produce instant results and the > wouldn't be needed).

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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