Two bullet roulette: Difference between revisions
Added FreeBASIC
(Added FreeBASIC) |
|||
(35 intermediate revisions by 16 users not shown) | |||
Line 1:
{{
The following is supposedly a question given to mathematics graduates seeking jobs on Wall Street:
<blockquote>
A revolver handgun has a revolving cylinder with six chambers for bullets.
It is loaded with the following procedure:
1. Check the first chamber to the right of the trigger for a bullet. If a bullet
is seen, the cylinder is rotated one chamber clockwise and the next chamber
checked until an empty chamber is found.
2. A cartridge containing a bullet is placed in the empty chamber.
3. The cylinder is then rotated one chamber clockwise.
Line 30 ⟶ 33:
A. Spinning the cylinder after loading the first bullet, and spinning again after the first shot.
B. Spinning the cylinder after loading the first bullet only.
C. Spinning the cylinder after firing the first shot only.
D. Not spinning the cylinder either after loading the first bullet or after the first shot.
E. The probability is the same for all cases.
</blockquote>
;Task:
# Run a repeated simulation of each of the above scenario, calculating the percentage of suicide with a randomization of the four spinning, loading and firing order scenarios.
Line 45 ⟶ 52:
Youtube video on the Russian 1895 Nagant revolver [[https://www.youtube.com/watch?v=Dh1mojMaEtM]]
<br><br>
=={{header|11l}}==
{{trans|Go}}
<syntaxhighlight lang="11l">UInt32 seed = 0
F nonrandom(n)
:seed = 1664525 * :seed + 1013904223
R Int(:seed >> 16) % n
V cylinder = [0B] * 6
F rshift()
V t = :cylinder[5]
L(i) (4..0).step(-1)
:cylinder[i + 1] = :cylinder[i]
:cylinder[0] = t
F unload()
L(i) 6
:cylinder[i] = 0B
F load()
L :cylinder[0]
rshift()
:cylinder[0] = 1B
rshift()
F spin()
L 1..nonrandom(6)
rshift()
F fire()
V shot = :cylinder[0]
rshift()
R shot
F method(s)
unload()
L(c) s
S c
‘L’
load()
‘S’
spin()
‘F’
I fire()
R 1
R 0
F mstring(s)
[String] l
L(c) s
S c
‘L’
l [+]= ‘load’
‘S’
l [+]= ‘spin’
‘F’
l [+]= ‘fire’
R l.join(‘, ’)
V tests = 100000
L(m) [‘LSLSFSF’, ‘LSLSFF’, ‘LLSFSF’, ‘LLSFF’]
V sum = 0
L 0 .< tests
sum += method(m)
V pc = Float(sum) * 100 / tests
print(‘#<40 produces #2.3% deaths.’.format(mstring(m), pc))</syntaxhighlight>
{{out}}
<pre>
load, spin, load, spin, fire, spin, fire produces 55.434% deaths.
load, spin, load, spin, fire, fire produces 58.373% deaths.
load, load, spin, fire, spin, fire produces 55.428% deaths.
load, load, spin, fire, fire produces 50.041% deaths.
</pre>
=={{header|AutoHotkey}}==
<syntaxhighlight lang="autohotkey">methods =
(
load, spin, load, spin, fire, spin, fire
load, spin, load, spin, fire, fire
load, load, spin, fire, spin, fire
load, load, spin, fire, fire
)
for i, method in StrSplit(methods, "`n", "`r"){
death := 0
main:
loop 100000 {
sixGun := []
for i, v in StrSplit(StrReplace(method," "), ",")
if %v%()
continue, main
}
output .= Format("{1:0.3f}", death/1000) "% Deaths for : """ method """`n"
}
MsgBox % output
return
load(){
global
if !sixGun.Count()
sixGun := [0,1,0,0,0,0]
else
if sixGun[2]
sixGun[1] := 1
sixGun[2] := 1
}
fire(){
global
if bullet := sixGun[1]
death++
temp := sixGun[6]
loop, 5
sixGun[7-A_Index] := sixGun[6-A_Index]
sixGun[1] := temp
return bullet
}
spin(){
global
Random, rnd, 1, 12
loop, % rnd {
temp := sixGun[6]
loop, 5
sixGun[7-A_Index] := sixGun[6-A_Index]
sixGun[1] := temp
}
}</syntaxhighlight>
{{out}}
<pre>55.478% Deaths for : "load, spin, load, spin, fire, spin, fire"
58.210% Deaths for : "load, spin, load, spin, fire, fire"
55.782% Deaths for : "load, load, spin, fire, spin, fire"
50.280% Deaths for : "load, load, spin, fire, fire"</pre>
=={{header|C}}==
{{trans|Go}}
<
#include <stdio.h>
#include <stdlib.h>
Line 167 ⟶ 308:
return 0;
}</
{{out}}
<pre>load, spin, load, spin, fire, spin, fire produces 55.456% deaths.
Line 176 ⟶ 317:
=={{header|C++}}==
{{trans|C}}
<
#include <iomanip>
#include <iostream>
Line 303 ⟶ 444:
return 0;
}</
{{out}}
<pre>load, spin, load, spin, fire, spin, fire produces 55.487% deaths.
Line 309 ⟶ 450:
load, load, spin, fire, spin, fire produces 55.675% deaths.
load, load, spin, fire, fire produces 50.051% deaths.</pre>
=={{header|EasyLang}}==
{{trans|C}}
<syntaxhighlight>
len cyl[] 6
proc rshift . .
h = cyl[6]
for i = 6 downto 2
cyl[i] = cyl[i - 1]
.
cyl[1] = h
.
proc unload . .
for i = 1 to 6
cyl[i] = 0
.
.
proc load . .
while cyl[1] = 1
rshift
.
cyl[1] = 1
rshift
.
proc spin . .
lim = randint 6
for i = 1 to lim - 1
rshift
.
.
func fire .
shot = cyl[1]
rshift
return shot
.
func method m[] .
unload
for m in m[]
if m = 1
load
elif m = 2
spin
elif m = 3
if fire = 1
return 1
.
.
.
return 0
.
method$[] = [ "load" "spin" "fire" ]
proc test m[] . .
n = 100000
for i = 1 to n
sum += method m[]
.
for i = 1 to len m[]
write method$[m[i]] & " "
.
print "-> " & 100 * sum / n & "% death"
.
test [ 1 2 1 2 3 2 3 ]
test [ 1 2 1 2 3 3 ]
test [ 1 1 2 3 2 3 ]
test [ 1 1 2 3 3 ]
</syntaxhighlight>
=={{header|Factor}}==
{{trans|Julia}}
{{trans|Python}}
<
math random sequences ;
IN: rosetta-code.roulette
Line 350 ⟶ 557:
} [ run-test ] assoc-each ;
MAIN: main</
{{out}}
<pre>"rosetta-code.roulette" run</pre>
Line 359 ⟶ 566:
Method <load, load, spin, fire, fire> produces 49.841% deaths.
</pre>
=={{header|FreeBASIC}}==
{{trans|Wren}}
<syntaxhighlight lang="vbnet">Type Revolver
cylinder(0 To 5) As Integer
End Type
Sub rshift(r As Revolver)
Dim t As Integer = r.cylinder(5)
For i As Integer = 4 To 0 Step -1
r.cylinder(i + 1) = r.cylinder(i)
Next i
r.cylinder(0) = t
End Sub
Sub unload(r As Revolver)
For i As Integer = 0 To 5
r.cylinder(i) = 0
Next i
End Sub
Sub load(r As Revolver)
While r.cylinder(0) <> 0
rshift(r)
Wend
r.cylinder(0) = -1
rshift(r)
End Sub
Sub spin(r As Revolver)
For i As Integer = 1 To Int(Rnd * 6) + 1
rshift(r)
Next i
End Sub
Function fire(r As Revolver) As Integer
Dim As Integer shot = r.cylinder(0)
rshift(r)
Return shot
End Function
Function method(r As Revolver, s As String) As Integer
unload(r)
For i As Integer = 1 To Len(s)
Dim c As String = Mid(s, i, 1)
If c = "L" Then
load(r)
Elseif c = "S" Then
spin(r)
Elseif c = "F" Then
If fire(r) <> 0 Then Return 1
End If
Next i
Return 0
End Function
Function mstring(s As String) As String
Dim As String l = ""
For i As Integer = 1 To Len(s)
Dim As String c = Mid(s, i, 1)
If c = "L" Then
l &= "load, "
Elseif c = "S" Then
l &= "spin, "
Elseif c = "F" Then
l &= "fire, "
End If
Next i
Return Left(l, Len(l) - 2)
End Function
Dim As Revolver rev
Dim As Integer tests = 100000
Dim As String methods(0 To 3) = {"LSLSFSF", "LSLSFF", "LLSFSF", "LLSFF"}
For m As Integer = 0 To 3 'In methods
Dim sum As Integer = 0
For t As Integer = 1 To tests
sum += method(rev, methods(m))
Next t
Print mstring(methods(m)), " produces "; sum * 100.0 / tests; "% deaths."
Next m
Sleep</syntaxhighlight>
{{out}}
<pre>load, spin, load, spin, fire, spin, fire produces 55.385% deaths.
load, spin, load, spin, fire, fire produces 58.204% deaths.
load, load, spin, fire, spin, fire produces 55.372% deaths.
load, load, spin, fire, fire produces 50.052% deaths.</pre>
=={{header|Go}}==
{{trans|Wren}}
Though procedural rather than OO.
<
import (
Line 452 ⟶ 748:
fmt.Printf("%-40s produces %6.3f%% deaths.\n", mstring(m), pc)
}
}</
{{out}}
Line 461 ⟶ 757:
load, load, spin, fire, spin, fire produces 55.405% deaths.
load, load, spin, fire, fire produces 49.889% deaths.
</pre>
=={{header|Java}}==
<syntaxhighlight lang="java">
import java.util.BitSet;
import java.util.concurrent.ThreadLocalRandom;
public class TwoBulletRoulette {
public static void main(String[] aArgs) {
Revolver handgun = new Revolver();
final int simulationCount = 100_000;
for ( Situation situation : Situation.values() ) {
double deaths = 0.0;
for ( int i = 0; i < simulationCount; i++ ) {
ResultState resultState = handgun.operateInMode(situation);
if ( resultState == ResultState.DEAD) {
deaths += 1.0;
}
}
final double deathRate = ( deaths / simulationCount ) * 100;
String percentage = String.format("%4.1f%%", deathRate);
System.out.println("Situation " + situation + " produces " + percentage + " deaths");
}
}
}
enum Situation { A, B, C, D }
enum ResultState { ALIVE, DEAD }
/**
* Representation of a six cylinder revolving chamber pistol.
*/
class Revolver {
public Revolver() {
chambers = new BitSet(chamberCount);
random = ThreadLocalRandom.current();
}
public ResultState operateInMode(Situation aSituation) {
return switch ( aSituation ) {
case A -> useSituationA();
case B -> useSituationB();
case C -> useSituationC();
case D -> useSituationD();
};
}
// PRIVATE //
private void unload() {
chambers.clear();
}
private void load() {
while ( chambers.get(loadingChamber) ) {
rotateClockwise();
}
chambers.set(loadingChamber);
rotateClockwise();
}
private void spin() {
final int spins = random.nextInt(0, chamberCount);
for ( int i = 0; i < spins; i++ ) {
rotateClockwise();
}
}
private boolean fire() {
boolean fire = chambers.get(firingChamber);
chambers.set(firingChamber, false);
rotateClockwise();
return fire;
}
private void rotateClockwise() {
final boolean temp = chambers.get(chamberCount - 1);
for ( int i = chamberCount - 2; i >= 0; i-- ) {
chambers.set(i + 1, chambers.get(i));
}
chambers.set(firingChamber, temp);
}
private ResultState useSituationA() {
unload();
load();
spin();
load();
spin();
if ( fire() ) {
return ResultState.DEAD;
};
spin();
if ( fire() ) {
return ResultState.DEAD;
};
return ResultState.ALIVE;
}
private ResultState useSituationB() {
unload();
load();
spin();
load();
spin();
if ( fire() ) {
return ResultState.DEAD;
};
if ( fire() ) {
return ResultState.DEAD;
};
return ResultState.ALIVE;
}
private ResultState useSituationC() {
unload();
load();
load();
spin();
if ( fire() ) {
return ResultState.DEAD;
};
spin();
if ( fire() ) {
return ResultState.DEAD;
};
return ResultState.ALIVE;
}
private ResultState useSituationD() {
unload();
load();
load();
spin();
if ( fire() ) {
return ResultState.DEAD;
};
if ( fire() ) {
return ResultState.DEAD;
};
return ResultState.ALIVE;
}
private BitSet chambers;
private ThreadLocalRandom random;
private final int firingChamber = 0;
private final int loadingChamber = 1;
private final int chamberCount = 6;
}
</syntaxhighlight>
{{ out }}
<pre>
Situation A produces 55.6% deaths
Situation B produces 58.2% deaths
Situation C produces 55.7% deaths
Situation D produces 49.7% deaths
</pre>
=={{header|JavaScript}}==
<syntaxhighlight lang="javascript">
let Pistol = function(method) {
this.fired = false;
this.cylinder = new Array(6).fill(false);
this.trigger = 0;
this.rshift = function() {
this.trigger = this.trigger == 0 ? 5 : this.trigger-1;
}
this.load = function() {
while (this.cylinder[this.trigger]) this.rshift();
this.cylinder[this.trigger] = true;
this.rshift();
}
// actually we don't need this here: just for completeness
this.unload = function() { this.cylinder.fill(false); }
this.spin = function() { this.trigger = Math.floor(Math.random() * 6); }
this.fire = function() {
if (this.cylinder[this.trigger]) this.fired = true;
this.rshift();
}
this.exec = function() {
if (!method) console.error('No method provided');
else {
method = method.toUpperCase();
for (let x = 0; x < method.length; x++)
switch (method[x]) {
case 'F' : this.fire(); break;
case 'L' : this.load(); break;
case 'S' : this.spin(); break;
case 'U' : this.unload(); break;
default: console.error(`Unknown character in method: ${method[x]}`);
}
return this.fired;
}
}
}
// simulating
const ITERATIONS = 25e4;
let methods = 'lslsfsf lslsff llsfsf llsff'.split(' '),
bodyCount;
console.log(`@ ${ITERATIONS.toLocaleString('en')} iterations:`);
console.log();
for (let x = 0; x < methods.length; x++) {
bodyCount = 0;
for (let y = 1; y <= ITERATIONS; y++)
if (new Pistol(methods[x]).exec()) bodyCount++;
console.log(`${methods[x]}:`);
console.log(`deaths: ${bodyCount.toLocaleString('en')} (${(bodyCount / ITERATIONS * 100).toPrecision(3)} %) `);
console.log();
}
</syntaxhighlight>
{{out}}
Example:
<pre>
@ 250,000 iterations:
lslsfsf:
deaths: 139,030 (55.6 %)
lslsff:
deaths: 145,912 (58.4 %)
llsfsf:
deaths: 138,628 (55.5 %)
llsff:
deaths: 125,268 (50.1 %)
</pre>
=={{header|Julia}}==
{{trans|Python}}
<
function load()
Line 518 ⟶ 1,053:
testmethods()
</
<pre>
Method load, spin, load, spin, fire, spin, fire produces 55.54253 per cent deaths.
Line 528 ⟶ 1,063:
=={{header|Kotlin}}==
{{trans|C}}
<
val cylinder = Array(6) { false }
Line 629 ⟶ 1,164:
test("LLSFSF");
test("LLSFF");
}</
{{out}}
<pre>load, spin, load, spin, fire, spin, fire produces 55.638% deaths.
Line 635 ⟶ 1,170:
load, load, spin, fire, spin, fire produces 55.725% deaths.
load, load, spin, fire, fire produces 49.875% deaths.</pre>
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<syntaxhighlight lang="mathematica">ClearAll[Unload, Load, Spin, Fire]
Unload[] := ConstantArray[False, 6]
Load[state_List] := Module[{s = state},
While[s[[2]],
s = RotateRight[s, 1]
];
s[[2]] = True;
s
]
Spin[state_List] := RotateRight[state, RandomInteger[{1, 6}]]
Fire[state_List] := Module[{shot},
shot = First[state];
{RotateRight[state, 1], shot}
]
ClearAll[LSLSFSF]
LSLSFSF[] := Module[{state, shot},
state = Unload[];
state = Load[state];
state = Spin[state];
state = Load[state];
state = Spin[state];
{state, shot} = Fire[state];
If[shot,
Return[True]
];
state = Spin[state];
{state, shot} = Fire[state];
If[shot,
Return[True]
];
Return[False]
]
ClearAll[LSLSFF]
LSLSFF[] := Module[{state, shot},
state = Unload[];
state = Load[state];
state = Spin[state];
state = Load[state];
state = Spin[state];
{state, shot} = Fire[state];
If[shot,
Return[True]
];
{state, shot} = Fire[state];
If[shot,
Return[True]
];
Return[False]
]
ClearAll[LLSFSF]
LLSFSF[] := Module[{state, shot},
state = Unload[];
state = Load[state];
state = Load[state];
state = Spin[state];
{state, shot} = Fire[state];
If[shot,
Return[True]
];
state = Spin[state];
{state, shot} = Fire[state];
If[shot,
Return[True]
];
Return[False]
]
ClearAll[LLSFF]
LLSFF[] := Module[{state, shot},
state = Unload[];
state = Load[state];
state = Load[state];
state = Spin[state];
{state, shot} = Fire[state];
If[shot,
Return[True]
];
{state, shot} = Fire[state];
If[shot,
Return[True]
];
Return[False]
]
n = 10^5;
Count[Table[LSLSFSF[], n], True]/N[n]
Count[Table[LSLSFF[], n], True]/N[n]
Count[Table[LLSFSF[], n], True]/N[n]
Count[Table[LLSFF[], n], True]/N[n]</syntaxhighlight>
{{out}}
<pre>0.55243
0.58272
0.55423
0.49975</pre>
=={{header|Nim}}==
<
type
Line 681 ⟶ 1,310:
randomize()
for scenario in ["LSLSFSF", "LSLSFF", "LLSFSF", "LLSFF"]:
test(scenario)</
{{out}}
Line 688 ⟶ 1,317:
55.74% deaths for scenario Load, Load, Spin, Fire, Spin, Fire.
50.14% deaths for scenario Load, Load, Spin, Fire, Fire.</pre>
=={{header|Odin}}==
<syntaxhighlight lang="Go">
/* imports */
import "core:fmt"
import "core:strings"
import "core:math/rand"
/* globals */
cylinder := [6]bool{}
/* main block */
main :: proc() {
rand.set_global_seed(42)
tests := 100000
sequence := [?]string{"LSLSFSF", "LSLSFF", "LLSFSF", "LLSFF"}
for m in sequence {
sum := 0
for t in 0 ..< tests {
sum += method(m)
}
pc: f64 = cast(f64)sum * 100 / cast(f64)tests
fmt.printf("%-40s produces %6.3f%% deaths.\n", mstring(m), pc)
}
}
/* definitions */
rshift :: proc() {
t := cylinder[len(cylinder) - 1]
copy(cylinder[1:], cylinder[0:])
cylinder[0] = t
}
unload :: proc() {
cylinder = false // array programming
}
load :: proc() {
for cylinder[0] {
rshift()
}
cylinder[0] = true
rshift()
}
spin :: proc() {
data: []int = {1, 2, 3, 4, 5, 6}
lim := rand.choice(data[:])
for i in 0 ..< lim {
rshift()
}
}
fire :: proc() -> bool {
shot := cylinder[0]
rshift()
return shot
}
method :: proc(s: string) -> int {
unload()
for character in s {
switch character {
case 'L':
load()
case 'S':
spin()
case 'F':
if fire() {
return 1
}
}
}
return 0
}
mstring :: proc(s: string) -> string {
l: [dynamic]string
for character in s {
switch character {
case 'L':
append(&l, "load")
case 'S':
append(&l, "spin")
case 'F':
append(&l, "fire")
}
}
return strings.join(l[:], ", ")
}
</syntaxhighlight>
{{out}}
<pre>
load, spin, load, spin, fire, spin, fire produces 55.771% deaths.
load, spin, load, spin, fire, fire produces 58.313% deaths.
load, load, spin, fire, spin, fire produces 55.487% deaths.
load, load, spin, fire, fire produces 49.972% deaths.
</pre>
=={{header|Perl}}==
{{trans|Raku}}
<
use warnings;
use feature 'say';
Line 742 ⟶ 1,460:
$total += &$ref for 1..$trials;
printf "%7s %.2f%%\n", $ref, $total / $trials * 100;
}</
{{out}}
<pre>LSLSFSF 55.04%
Line 750 ⟶ 1,468:
=={{header|Phix}}==
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">spin</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">revolver</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">count</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">while</span> <span style="color: #000000;">count</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">revolver</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">revolver</span><span style="color: #0000FF;">[$]&</span><span style="color: #000000;">revolver</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..$-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
<span style="color: #000000;">count</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">revolver</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">load</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">revolver</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">while</span> <span style="color: #000000;">revolver</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">revolver</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">spin</span><span style="color: #0000FF;">(</span><span style="color: #000000;">revolver</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #000000;">revolver</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">true</span>
<span style="color: #000000;">revolver</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">spin</span><span style="color: #0000FF;">(</span><span style="color: #000000;">revolver</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">revolver</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">fire</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">revolver</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">bool</span> <span style="color: #000000;">dead</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">revolver</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">then</span> <span style="color: #000000;">dead</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">true</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">revolver</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">spin</span><span style="color: #0000FF;">(</span><span style="color: #000000;">revolver</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">return</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">revolver</span><span style="color: #0000FF;">,</span><span style="color: #000000;">dead</span><span style="color: #0000FF;">}</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">me</span><span style="color: #0000FF;">)</span>
<span style="color: #0000FF;">{</span><span style="color: #004080;">string</span> <span style="color: #000000;">method</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">atom</span> <span style="color: #000000;">expected</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">me</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">deaths</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">limit</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">100_000</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">limit</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">revolver</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #004600;">false</span><span style="color: #0000FF;">,</span><span style="color: #000000;">6</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">bool</span> <span style="color: #000000;">dead</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">false</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">method</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">ch</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">method</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">switch</span> <span style="color: #000000;">ch</span>
<span style="color: #008080;">case</span> <span style="color: #008000;">'L'</span><span style="color: #0000FF;">:</span> <span style="color: #000000;">revolver</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">load</span><span style="color: #0000FF;">(</span><span style="color: #000000;">revolver</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">case</span> <span style="color: #008000;">'S'</span><span style="color: #0000FF;">:</span> <span style="color: #000000;">revolver</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">spin</span><span style="color: #0000FF;">(</span><span style="color: #000000;">revolver</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">rand</span><span style="color: #0000FF;">(</span><span style="color: #000000;">6</span><span style="color: #0000FF;">))</span>
<span style="color: #008080;">case</span> <span style="color: #008000;">'F'</span><span style="color: #0000FF;">:</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">revolver</span><span style="color: #0000FF;">,</span><span style="color: #000000;">dead</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">fire</span><span style="color: #0000FF;">(</span><span style="color: #000000;">revolver</span><span style="color: #0000FF;">,</span><span style="color: #000000;">dead</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">switch</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #000000;">deaths</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">dead</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%s: %5.2f (expected %.2f%%)\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">method</span><span style="color: #0000FF;">,</span><span style="color: #000000;">100</span><span style="color: #0000FF;">*</span><span style="color: #000000;">deaths</span><span style="color: #0000FF;">/</span><span style="color: #000000;">limit</span><span style="color: #0000FF;">,</span><span style="color: #000000;">expected</span><span style="color: #0000FF;">*</span><span style="color: #000000;">100</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Load/Spin/Fire method percentage fatalities:\n"</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">papply</span><span style="color: #0000FF;">({{</span><span style="color: #008000;">"LSLSFSF"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">5</span><span style="color: #0000FF;">/</span><span style="color: #000000;">9</span><span style="color: #0000FF;">},{</span><span style="color: #008000;">"LSLSFF"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">7</span><span style="color: #0000FF;">/</span><span style="color: #000000;">12</span><span style="color: #0000FF;">},{</span><span style="color: #008000;">"LLSFSF"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">5</span><span style="color: #0000FF;">/</span><span style="color: #000000;">9</span><span style="color: #0000FF;">},{</span><span style="color: #008000;">"LLSFF"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">/</span><span style="color: #000000;">2</span><span style="color: #0000FF;">}},</span><span style="color: #000000;">test</span><span style="color: #0000FF;">)</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Load/Spin/Fire method percentage fatalities:
LSLSFSF: 55.
LSLSFF: 58.
LLSFSF: 55.
LLSFF:
</pre>
=={{header|Python}}==
<
import numpy as np
Line 899 ⟶ 1,620:
percentage = 100 * sum([method() for _ in range(TESTCOUNT)]) / TESTCOUNT
print("Method", name, "produces", percentage, "per cent deaths.")
</
<pre>
Method load, spin, load, spin, fire, spin, fire produces 55.652 per cent deaths.
Line 909 ⟶ 1,630:
=={{header|Raku}}==
<syntaxhighlight lang="raku"
my @cyl;
Line 962 ⟶ 1,683:
say "{.fmt('%7s')}: %{(%revolver{$_} / $trials × 100).fmt('%.2f')}"
for <LSLSFSF LSLSFF LLSFSF LLSFF></
{{out|Sample output (default; 6 shooter)}}
<pre>LSLSFSF: %55.37
Line 998 ⟶ 1,719:
Changing the cartridge chamber from an index array to a simple string made the program around '''200%''' faster.
<
parse arg cyls tests seed . /*obtain optional arguments from the CL*/
if cyls=='' | cyls=="," then cyls= 6 /*Not specified? Then use the default.*/
if tests=='' | tests=="," then tests= 100000 /* " " " " " " */
if datatype(seed, 'W') then call random ,,seed /* " " " " " " */
cyls_ = cyls - 1; @0= copies(0,
@abc= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
scenarios= '
#= words(scenarios) /*the number of actions in a scenario. */
/*The scenarios are case insensitive. */
do m=1 for #; q= word(scenarios, m)
do tests;
end /*tests*/
pc= left( (sum * 100 / tests)"%", 7)
say act()
end /*m*/
exit 0 /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
fire: != left(@, 1); @=
load: if left(@, 1) then @=
spin: ?= random(1, cyls); if ?\==cyls then @= substr(@ || @, ? + 1, cyls); return
/*──────────────────────────────────────────────────────────────────────────────────────*/
method: @=
else if y=='F' then if fire() then return 1
end /*a*/;
/*──────────────────────────────────────────────────────────────────────────────────────*/
act: $=;
end /*a*/;
{{out|output|text= when using the default inputs, showing that 2<sup>nd</sup> option '''B''' has the highest probability for a suicide:}}
<pre>
Line 1,039 ⟶ 1,759:
load, load, spin, fire, spin, fire (option C) produces 55.82% deaths.
load, load, spin, fire, fire (option D) produces 50.021% deaths.
</pre>
=={{header|Ruby}}==
Out of morbid interest I added strategy E: load, spin, shoot, load, spin, shoot.
<syntaxhighlight lang="ruby">class Revolver
attr_accessor :strategy
attr_reader :notches, :shot_count
def initialize(strategy = [:load, :spin, :shoot], num_chambers = 6) # default like Deer hunter
@chambers = Array.new(num_chambers) # by default 6 nils
@strategy = strategy
@notches, @shot_count, @loaded_count = 0, 0, 0
end
def load
raise "gun completely loaded " if @chambers.all? :loaded
@chambers.rotate! until @chambers[1] == nil #not sure about this; Raku rotates -1
@chambers[1] = :loaded
@chambers.rotate! #not sure about this; Raku rotates -1
@loaded_count += 1
end
def spin
@chambers.rotate!(rand(1..@chambers.size))
end
def unload
@chambers.fill(nil)
@loaded_count = 0
end
def shoot
@chambers[0] = nil
@chambers.rotate!
end
def play
strategy.each{|action| send(action)}
@shot_count += 1
@notches += 1 unless @chambers.count(:loaded) == @loaded_count # all bullets still there?
unload
end
end
strategies = {:A => [:load, :spin, :load, :spin, :shoot, :spin, :shoot],
:B => [:load, :spin, :load, :spin, :shoot, :shoot],
:C => [:load, :load, :spin, :shoot, :spin, :shoot],
:D => [:load, :load, :spin, :shoot, :shoot],
:E => [:load, :spin, :shoot, :load, :spin, :shoot]}
n = 100_000
puts "simulation of #{n} runs:"
strategies.each do |name, strategy|
gun = Revolver.new(strategy) # Revolver.new(strategy, 10) for a 10-shooter
n.times{gun.play}
puts "Strategy #{name}: #{gun.notches.fdiv(gun.shot_count)}"
end
</syntaxhighlight>
{{out}}
<pre>simulation of 100000 runs:
Strategy A: 0.55728
Strategy B: 0.58316
Strategy C: 0.5598
Strategy D: 0.49876
Strategy E: 0.44323
</pre>
=={{header|V (Vlang)}}==
{{trans|Kotlin}}
<syntaxhighlight lang="v (vlang)">
import rand
__global cylinder = []bool{len:6}
fn main() {
test("LSLSFSF")
test("LSLSFF")
test("LLSFSF")
test("LLSFF")
}
fn test(src string) {
tests := 100000
mut sum := 0
for _ in 0..tests {
sum += method(src)
}
println('${m_string(src)} produces ${100.0 * f32(sum) / f32(tests)}% deaths.')
}
fn rshift() {
t := cylinder[5]
for i := 4; i >= 0; i-- {
cylinder[i+1] = cylinder[i]
}
cylinder[0] = t
}
fn unload() {
for i := 0; i < 6; i++ {
cylinder[i] = false
}
}
fn load() {
for cylinder[0] {
rshift()
}
cylinder[0] = true
rshift()
}
fn spin() {
mut lim := 1 + rand.intn(6) or {exit(1)}
for i := 1; i < lim; i++ {
rshift()
}
}
fn fire() bool {
shot := cylinder[0]
rshift()
return shot
}
fn method(s string) int {
unload()
for c in s {
match c.ascii_str() {
'L' {load()}
'S' {spin()}
'F' {if fire() == true {return 1}}
else {}
}
}
return 0
}
fn m_string(s string) string {
mut l := []string{}
for c in s {
match c.ascii_str() {
'L' {l << "load"}
'S' {l << "spin"}
'F' {l << "fire"}
else {}
}
}
return l.join(', ')
}
</syntaxhighlight>
{{out}}
<pre>
load, spin, load, spin, fire, spin, fire produces 55.795% deaths.
load, spin, load, spin, fire, fire produces 58.453% deaths.
load, load, spin, fire, spin, fire produces 55.468% deaths.
load, load, spin, fire, fire produces 49.868% deaths.
</pre>
=={{header|Wren}}==
{{libheader|Wren-fmt}}
<
import "./fmt" for Fmt
var Rand = Random.new()
Line 1,114 ⟶ 1,992:
for (t in 1..tests) sum = sum + rev.method(m)
Fmt.print("$-40s produces $6.3f\% deaths.", Revolver.mstring(m), sum * 100 / tests)
}</
{{out}}
|