Data commit

This commit is contained in:
Ingy döt Net 2023-07-01 11:58:00 -04:00
parent 7387c8f97b
commit cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions

View file

@ -0,0 +1,2 @@
---
from: http://rosettacode.org/wiki/Two_bullet_roulette

View file

@ -0,0 +1,52 @@
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.
To randomize the cylinder's position, the cylinder is spun, which causes the cylinder to take
a random position from 1 to 6 chamber rotations clockwise from its starting position.
When the trigger is pulled the gun will fire if there is a bullet in position 0, which is just
counterclockwise from the loading position.
The gun is unloaded by removing all cartridges from the cylinder.
According to the legend, a suicidal Russian imperial military officer plays a game of Russian
roulette by putting two bullets in a six-chamber cylinder and pulls the trigger twice.
If the gun fires with a trigger pull, this is considered a successful suicide.
The cylinder is always spun before the first shot, but it may or may not be spun after putting
in the first bullet and may or may not be spun after taking the first shot.
Which of the following situations produces the highest probability of suicide?
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.
# Show the results as a percentage of deaths for each type of scenario.
# The hand calculated probabilities are 5/9, 7/12, 5/9, and 1/2. A correct program should produce results close enough to those to allow a correct response to the interview question.
;Reference:
Youtube video on the Russian 1895 Nagant revolver [[https://www.youtube.com/watch?v=Dh1mojMaEtM]]
<br><br>

View file

@ -0,0 +1,64 @@
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))

View file

@ -0,0 +1,51 @@
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
}
}

View file

@ -0,0 +1,128 @@
#include <array>
#include <iomanip>
#include <iostream>
#include <random>
#include <sstream>
class Roulette {
private:
std::array<bool, 6> cylinder;
std::mt19937 gen;
std::uniform_int_distribution<> distrib;
int next_int() {
return distrib(gen);
}
void rshift() {
std::rotate(cylinder.begin(), cylinder.begin() + 1, cylinder.end());
}
void unload() {
std::fill(cylinder.begin(), cylinder.end(), false);
}
void load() {
while (cylinder[0]) {
rshift();
}
cylinder[0] = true;
rshift();
}
void spin() {
int lim = next_int();
for (int i = 1; i < lim; i++) {
rshift();
}
}
bool fire() {
auto shot = cylinder[0];
rshift();
return shot;
}
public:
Roulette() {
std::random_device rd;
gen = std::mt19937(rd());
distrib = std::uniform_int_distribution<>(1, 6);
unload();
}
int method(const std::string &s) {
unload();
for (auto c : s) {
switch (c) {
case 'L':
load();
break;
case 'S':
spin();
break;
case 'F':
if (fire()) {
return 1;
}
break;
}
}
return 0;
}
};
std::string mstring(const std::string &s) {
std::stringstream ss;
bool first = true;
auto append = [&ss, &first](const std::string s) {
if (first) {
first = false;
} else {
ss << ", ";
}
ss << s;
};
for (auto c : s) {
switch (c) {
case 'L':
append("load");
break;
case 'S':
append("spin");
break;
case 'F':
append("fire");
break;
}
}
return ss.str();
}
void test(const std::string &src) {
const int tests = 100000;
int sum = 0;
Roulette r;
for (int t = 0; t < tests; t++) {
sum += r.method(src);
}
double pc = 100.0 * sum / tests;
std::cout << std::left << std::setw(40) << mstring(src) << " produces " << pc << "% deaths.\n";
}
int main() {
test("LSLSFSF");
test("LSLSFF");
test("LLSFSF");
test("LLSFF");
return 0;
}

View file

@ -0,0 +1,120 @@
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
static int nextInt(int size) {
return rand() % size;
}
static bool cylinder[6];
static void rshift() {
bool t = cylinder[5];
int i;
for (i = 4; i >= 0; i--) {
cylinder[i + 1] = cylinder[i];
}
cylinder[0] = t;
}
static void unload() {
int i;
for (i = 0; i < 6; i++) {
cylinder[i] = false;
}
}
static void load() {
while (cylinder[0]) {
rshift();
}
cylinder[0] = true;
rshift();
}
static void spin() {
int lim = nextInt(6) + 1;
int i;
for (i = 1; i < lim; i++) {
rshift();
}
}
static bool fire() {
bool shot = cylinder[0];
rshift();
return shot;
}
static int method(const char *s) {
unload();
for (; *s != '\0'; s++) {
switch (*s) {
case 'L':
load();
break;
case 'S':
spin();
break;
case 'F':
if (fire()) {
return 1;
}
break;
}
}
return 0;
}
static void append(char *out, const char *txt) {
if (*out != '\0') {
strcat(out, ", ");
}
strcat(out, txt);
}
static void mstring(const char *s, char *out) {
for (; *s != '\0'; s++) {
switch (*s) {
case 'L':
append(out, "load");
break;
case 'S':
append(out, "spin");
break;
case 'F':
append(out, "fire");
break;
}
}
}
static void test(char *src) {
char buffer[41] = "";
const int tests = 100000;
int sum = 0;
int t;
double pc;
for (t = 0; t < tests; t++) {
sum += method(src);
}
mstring(src, buffer);
pc = 100.0 * sum / tests;
printf("%-40s produces %6.3f%% deaths.\n", buffer, pc);
}
int main() {
srand(time(0));
test("LSLSFSF");
test("LSLSFF");
test("LLSFSF");
test("LLSFF");
return 0;
}

View file

@ -0,0 +1,62 @@
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
call rshift
.
cyl[1] = 1
call rshift
.
proc spin . .
lim = random 6
for i = 1 to lim - 1
call rshift
.
.
proc fire . shot .
shot = cyl[1]
call rshift
.
proc method m[] . shot .
call unload
shot = 0
for m in m[]
if m = 1
call load
elif m = 2
call spin
elif m = 3
call fire shot
if shot = 1
break 1
.
.
.
.
method$[] = [ "load" "spin" "fire" ]
proc test m[] . .
n = 100000
for i = 1 to n
call method m[] shot
sum += shot
.
for i = 1 to len m[]
write method$[m[i]] & " "
.
print "-> " & 100 * sum / n & "% death"
.
call test [ 1 2 1 2 3 2 3 ]
call test [ 1 2 1 2 3 3 ]
call test [ 1 1 2 3 2 3 ]
call test [ 1 1 2 3 3 ]

View file

@ -0,0 +1,38 @@
USING: accessors assocs circular formatting fry kernel literals
math random sequences ;
IN: rosetta-code.roulette
CONSTANT: cyl $[ { f f f f f f } <circular> ]
: cylinder ( -- seq ) cyl [ drop f ] map! ;
: load ( seq -- seq' )
0 over nth [ dup rotate-circular ] when
t 0 rot [ set-nth ] [ rotate-circular ] [ ] tri ;
: spin ( seq -- seq' ) [ 6 random 1 + + ] change-start ;
: fire ( seq -- ? seq' )
[ 0 swap nth ] [ rotate-circular ] [ ] tri ;
: LSLSFSF ( -- ? ) cylinder load spin load spin fire spin fire drop or ;
: LSLSFF ( -- ? ) cylinder load spin load spin fire fire drop or ;
: LLSFSF ( -- ? ) cylinder load load spin fire spin fire drop or ;
: LLSFF ( -- ? ) cylinder load load spin fire fire drop or ;
: percent ( ... n quot: ( ... -- ... ? ) -- ... x )
0 -rot '[ _ call( -- ? ) 1 0 ? + ] [ times ] keepd /f 100 * ; inline
: run-test ( description quot -- )
100,000 swap percent
"Method <%s> produces %.3f%% deaths.\n" printf ;
: main ( -- )
{
{ "load, spin, load, spin, fire, spin, fire" [ LSLSFSF ] }
{ "load, spin, load, spin, fire, fire" [ LSLSFF ] }
{ "load, load, spin, fire, spin, fire" [ LLSFSF ] }
{ "load, load, spin, fire, fire" [ LLSFF ] }
} [ run-test ] assoc-each ;
MAIN: main

View file

@ -0,0 +1,90 @@
package main
import (
"fmt"
"math/rand"
"strings"
"time"
)
var cylinder = [6]bool{}
func rshift() {
t := cylinder[5]
for i := 4; i >= 0; i-- {
cylinder[i+1] = cylinder[i]
}
cylinder[0] = t
}
func unload() {
for i := 0; i < 6; i++ {
cylinder[i] = false
}
}
func load() {
for cylinder[0] {
rshift()
}
cylinder[0] = true
rshift()
}
func spin() {
var lim = 1 + rand.Intn(6)
for i := 1; i < lim; i++ {
rshift()
}
}
func fire() bool {
shot := cylinder[0]
rshift()
return shot
}
func method(s string) int {
unload()
for _, c := range s {
switch c {
case 'L':
load()
case 'S':
spin()
case 'F':
if fire() {
return 1
}
}
}
return 0
}
func mstring(s string) string {
var l []string
for _, c := range s {
switch c {
case 'L':
l = append(l, "load")
case 'S':
l = append(l, "spin")
case 'F':
l = append(l, "fire")
}
}
return strings.Join(l, ", ")
}
func main() {
rand.Seed(time.Now().UnixNano())
tests := 100000
for _, m := range []string{"LSLSFSF", "LSLSFF", "LLSFSF", "LLSFF"} {
sum := 0
for t := 1; t <= tests; t++ {
sum += method(m)
}
pc := float64(sum) * 100 / float64(tests)
fmt.Printf("%-40s produces %6.3f%% deaths.\n", mstring(m), pc)
}
}

View file

@ -0,0 +1,156 @@
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;
}

View file

@ -0,0 +1,51 @@
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();
}

View file

@ -0,0 +1,53 @@
const cyl = zeros(Bool, 6)
function load()
while cyl[1]
cyl .= circshift(cyl, 1)
end
cyl[1] = true
cyl .= circshift(cyl, 1)
end
spin() = (cyl .= circshift(cyl, rand(1:6)))
fire() = (shot = cyl[1]; cyl .= circshift(cyl, 1); shot)
function LSLSFSF()
cyl .= 0
load(); spin(); load(); spin()
fire() && return true
spin(); return fire()
end
function LSLSFF()
cyl .= 0
load(); spin(); load(); spin()
fire() && return true
return fire()
end
function LLSFSF()
cyl .= 0
load(); load(); spin()
fire() && return true
spin(); return fire()
end
function LLSFF()
cyl .= 0
load(); load(); spin()
fire() && return true
return fire()
end
function testmethods(N = 10000000)
for (name, method) in [("load, spin, load, spin, fire, spin, fire", LSLSFSF),
("load, spin, load, spin, fire, fire", LSLSFF),
("load, load, spin, fire, spin, fire", LLSFSF),
("load, load, spin, fire, fire", LLSFF)]
percentage = 100 * sum([method() for _ in 1:N]) / N
println("Method $name produces $percentage per cent deaths.")
end
end
testmethods()

View file

@ -0,0 +1,102 @@
import kotlin.random.Random
val cylinder = Array(6) { false }
fun rShift() {
val t = cylinder[cylinder.size - 1]
for (i in (0 until cylinder.size - 1).reversed()) {
cylinder[i + 1] = cylinder[i]
}
cylinder[0] = t
}
fun unload() {
for (i in cylinder.indices) {
cylinder[i] = false
}
}
fun load() {
while (cylinder[0]) {
rShift()
}
cylinder[0] = true
rShift()
}
fun spin() {
val lim = Random.nextInt(0, 6) + 1
for (i in 1..lim) {
rShift()
}
}
fun fire(): Boolean {
val shot = cylinder[0]
rShift()
return shot
}
fun method(s: String): Int {
unload()
for (c in s) {
when (c) {
'L' -> {
load()
}
'S' -> {
spin()
}
'F' -> {
if (fire()) {
return 1
}
}
}
}
return 0
}
fun mString(s: String): String {
val buf = StringBuilder()
fun append(txt: String) {
if (buf.isNotEmpty()) {
buf.append(", ")
}
buf.append(txt)
}
for (c in s) {
when (c) {
'L' -> {
append("load")
}
'S' -> {
append("spin")
}
'F' -> {
append("fire")
}
}
}
return buf.toString()
}
fun test(src: String) {
val tests = 100000
var sum = 0
for (t in 0..tests) {
sum += method(src)
}
val str = mString(src)
val pc = 100.0 * sum / tests
println("%-40s produces %6.3f%% deaths.".format(str, pc))
}
fun main() {
test("LSLSFSF");
test("LSLSFF");
test("LLSFSF");
test("LLSFF");
}

View file

@ -0,0 +1,87 @@
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]

View file

@ -0,0 +1,44 @@
import algorithm, random, sequtils, strformat, strutils, tables
type
Revolver = array[6, bool]
Action {.pure.} = enum Load, Spin, Fire, Error
const Actions = {'L': Load, 'S': Spin, 'F': Fire}.toTable
func spin(revolver: var Revolver; count: Positive) =
revolver.rotateLeft(-count)
func load(revolver: var Revolver) =
while revolver[1]:
revolver.spin(1)
revolver[1] = true
revolver.spin(1)
func fire(revolver: var Revolver): bool =
result = revolver[0]
revolver.spin(1)
proc test(scenario: string) =
let actions = scenario.mapIt(Actions.getOrDefault(it, Error))
var deaths = 0
var count = 100_000
for _ in 1..count:
var revolver: Revolver
for action in actions:
case action
of Load:
revolver.load()
of Spin:
revolver.spin(rand(1..6))
of Fire:
if revolver.fire():
inc deaths
break
of Error:
raise newException(ValueError, "encountered an unknown action.")
echo &"""{100 * deaths / count:5.2f}% deaths for scenario {actions.join(", ")}."""
randomize()
for scenario in ["LSLSFSF", "LSLSFF", "LLSFSF", "LLSFF"]:
test(scenario)

View file

@ -0,0 +1,52 @@
use strict;
use warnings;
use feature 'say';
my @cyl;
my $shots = 6;
sub load {
push @cyl, shift @cyl while $cyl[1];
$cyl[1] = 1;
push @cyl, shift @cyl
}
sub spin { push @cyl, shift @cyl for 0 .. int rand @cyl }
sub fire { push @cyl, shift @cyl; $cyl[0] }
sub LSLSFSF {
@cyl = (0) x $shots;
load, spin, load, spin;
return 1 if fire;
spin;
fire
}
sub LSLSFF {
@cyl = (0) x $shots;
load, spin, load, spin;
fire or fire
}
sub LLSFSF {
@cyl = (0) x $shots;
load, load, spin;
return 1 if fire;
spin;
fire
}
sub LLSFF {
@cyl = (0) x $shots;
load, load, spin;
fire or fire
}
my $trials = 10000;
for my $ref (<LSLSFSF LSLSFF LLSFSF LLSFF>) {
no strict 'refs';
my $total = 0;
$total += &$ref for 1..$trials;
printf "%7s %.2f%%\n", $ref, $total / $trials * 100;
}

View file

@ -0,0 +1,48 @@
(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>
<!--

View file

@ -0,0 +1,94 @@
""" Russian roulette problem """
import numpy as np
class Revolver:
""" simulates 6-shot revolving cylinger pistol """
def __init__(self):
""" start unloaded """
self.cylinder = np.array([False] * 6)
def unload(self):
""" empty all chambers of cylinder """
self.cylinder[:] = False
def load(self):
""" load a chamber (advance til empty if full already), then advance once """
while self.cylinder[1]:
self.cylinder[:] = np.roll(self.cylinder, 1)
self.cylinder[1] = True
def spin(self):
""" spin cylinder, randomizing position of chamber to be fired """
self.cylinder[:] = np.roll(self.cylinder, np.random.randint(1, high=7))
def fire(self):
""" pull trigger of revolver, return True if fired, False if did not fire """
shot = self.cylinder[0]
self.cylinder[:] = np.roll(self.cylinder, 1)
return shot
def LSLSFSF(self):
""" load, spin, load, spin, fire, spin, fire """
self.unload()
self.load()
self.spin()
self.load()
self.spin()
if self.fire():
return True
self.spin()
if self.fire():
return True
return False
def LSLSFF(self):
""" load, spin, load, spin, fire, fire """
self.unload()
self.load()
self.spin()
self.load()
self.spin()
if self.fire():
return True
if self.fire():
return True
return False
def LLSFSF(self):
""" load, load, spin, fire, spin, fire """
self.unload()
self.load()
self.load()
self.spin()
if self.fire():
return True
self.spin()
if self.fire():
return True
return False
def LLSFF(self):
""" load, load, spin, fire, fire """
self.unload()
self.load()
self.load()
self.spin()
if self.fire():
return True
if self.fire():
return True
return False
if __name__ == '__main__':
REV = Revolver()
TESTCOUNT = 100000
for (name, method) in [['load, spin, load, spin, fire, spin, fire', REV.LSLSFSF],
['load, spin, load, spin, fire, fire', REV.LSLSFF],
['load, load, spin, fire, spin, fire', REV.LLSFSF],
['load, load, spin, fire, fire', REV.LLSFF]]:
percentage = 100 * sum([method() for _ in range(TESTCOUNT)]) / TESTCOUNT
print("Method", name, "produces", percentage, "per cent deaths.")

View file

@ -0,0 +1,34 @@
/*REXX pgm simulates scenarios for a two─bullet Russian roulette game with a 6 cyl. gun.*/
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, cyls) /*shortcut placeholder for cylinders-1 */
@abc= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' /*indices for the various options used.*/
scenarios= 'LSLSFsF LSLSFF LLSFSF LLSFF' /*the list of scenarios to be tested. */
#= words(scenarios) /*the number of actions in a scenario. */
/*The scenarios are case insensitive. */
do m=1 for #; q= word(scenarios, m) /*test each of the scenarios specified.*/
sum= 0 /*initialize the sum to zero. */
do tests; sum= sum + method() /*added the sums up for the percentages*/
end /*tests*/
pc= left( (sum * 100 / tests)"%", 7)
say act() ' (option' substr(@abc, m, 1)") produces " pc ' deaths.'
end /*m*/
exit 0 /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
fire: != left(@, 1); @= right(@, cyls_)left(@, 1); /* ◄──── next cyl.*/ return !
load: if left(@, 1) then @= right(@, cyls_)left(@, 1); @= 1||right(@, cyls_); return
spin: ?= random(1, cyls); if ?\==cyls then @= substr(@ || @, ? + 1, cyls); return
/*──────────────────────────────────────────────────────────────────────────────────────*/
method: @= @0; do a=1 for length(q); y= substr(q, a, 1)
if y=='L' then call load
else if y=='S' then call spin
else if y=='F' then if fire() then return 1
end /*a*/; return 0
/*──────────────────────────────────────────────────────────────────────────────────────*/
act: $=; do a=1 for length(q); y= substr(q, a, 1)
if y=='L' then $= $", load"
if y=='S' then $= $", spin"
if y=='F' then $= $", fire"
end /*a*/; return right( strip( strip($, , ",") ), 45)

View file

@ -0,0 +1,54 @@
unit sub MAIN ($shots = 6);
my @cyl;
sub load () {
@cyl.=rotate(-1) while @cyl[1];
@cyl[1] = 1;
@cyl.=rotate(-1);
}
sub spin () { @cyl.=rotate: (^@cyl).pick }
sub fire () { @cyl.=rotate; @cyl[0] }
sub LSLSFSF {
@cyl = 0 xx $shots;
load, spin, load, spin;
return 1 if fire;
spin;
fire
}
sub LSLSFF {
@cyl = 0 xx $shots;
load, spin, load, spin;
fire() || fire
}
sub LLSFSF {
@cyl = 0 xx $shots;
load, load, spin;
return 1 if fire;
spin;
fire
}
sub LLSFF {
@cyl = 0 xx $shots;
load, load, spin;
fire() || fire
}
my %revolver;
my $trials = 100000;
for ^$trials {
%revolver<LSLSFSF> += LSLSFSF;
%revolver<LSLSFF> += LSLSFF;
%revolver<LLSFSF> += LLSFSF;
%revolver<LLSFF> += LLSFF;
}
say "{.fmt('%7s')}: %{(%revolver{$_} / $trials × 100).fmt('%.2f')}"
for <LSLSFSF LSLSFF LLSFSF LLSFF>

View file

@ -0,0 +1,53 @@
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

View file

@ -0,0 +1,80 @@
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(', ')
}

View file

@ -0,0 +1,72 @@
import "random" for Random
import "/fmt" for Fmt
var Rand = Random.new()
class Revolver {
construct new() {
_cylinder = List.filled(6, false)
}
rshift() {
var t = _cylinder[-1]
for (i in 4..0) _cylinder[i+1] = _cylinder[i]
_cylinder[0] = t
}
unload() {
for (i in 0..5) _cylinder[i] = false
}
load() {
while (_cylinder[0]) rshift()
_cylinder[0] = true
rshift()
}
spin() {
for (i in 1..Rand.int(1, 7)) rshift()
}
fire() {
var shot = _cylinder[0]
rshift()
return shot
}
method(s) {
unload()
for (c in s) {
if (c == "L") {
load()
} else if (c == "S") {
spin()
} else if (c == "F") {
if (fire()) return 1
}
}
return 0
}
static mstring(s) {
var l = []
for (c in s) {
if (c == "L") {
l.add("load")
} else if (c == "S") {
l.add("spin")
} else if (c == "F") {
l.add("fire")
}
}
return l.join(", ")
}
}
var rev = Revolver.new()
var tests = 100000
for (m in ["LSLSFSF", "LSLSFF", "LLSFSF", "LLSFF"]) {
var sum = 0
for (t in 1..tests) sum = sum + rev.method(m)
Fmt.print("$-40s produces $6.3f\% deaths.", Revolver.mstring(m), sum * 100 / tests)
}