Skip to content

Instantly share code, notes, and snippets.

@jlp78
Last active February 13, 2024 23:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jlp78/74b2e96bdf3d11000ff672a60e7a5fc2 to your computer and use it in GitHub Desktop.
Save jlp78/74b2e96bdf3d11000ff672a60e7a5fc2 to your computer and use it in GitHub Desktop.
Simple implementation of the statistics Monty Hall problem.
#! /usr/bin/perl
# implement the monty hall problem, run it a while, calculate percentages
sub make_doors {
my($car, @door, $i);
$car = int(rand(3));
for ($i = 0; $i < 3; $i++) {
$door[$i] = ($i == $car);
}
$car_door[$car]++; # keep some additional stats
return(@door);
}
sub guess1 {
my($pick);
$pick = int(rand(3));
$guess_door[$pick]++;
return($pick);
}
sub guess2 {
my($oldpick, $montyshow) = @_;
my($i);
for ($i = 0; $i < 3; $i++) {
return($i) unless $oldpick == $i or $montyshow == $i;
}
}
sub monty {
my($pick, @door) = @_;
my($i, @montyshow, $montyshow);
for ($i = 0; $i < 3; $i++) {
next if $i == $pick;
push(@montyshow, $i) unless $door[$i];
}
$montyshow = $montyshow[int(rand($#montyshow))];
return($montyshow);
}
sub find_car {
my(@door) = @_;
my($i);
for ($i = 0; $i < 3; $i++) {
return($i) if $door[$i];
}
}
sub play_one {
my(@doors, $mypick, $monty, $mynewpick, $car);
@doors = &make_doors;
$mypick = &guess1;
$monty = &monty($mypick, @doors);
$mynewpick = &guess2($mypick, $monty);
$car = &find_car(@doors);
if ($car == $mynewpick) {
$pick = "NEW";
$newct++;
} else {
$pick = "OLD";
$oldct++;
}
$totalct++;
# columns are: first pick, monty's show, second pick, car location
printf "%10d: %2d %2d %2d %2d %s\n", $totalct, $mypick+1, $monty+1,
$mynewpick+1, $car+1, $pick;
}
$max = shift;
$max = 20 unless defined($max);
print "this is the monty hall problem. FP is the player's first pick,\n";
print "MP is what door monty shows you, SP is the player's second pick,\n";
print "AT shows which door the car is actually behind. also shown is\n";
print "if the player SHOULD have kept their OLD choice or gone with the\n";
print "NEW one.\n\n";
print " trial num: FP MP SP AT\n";
for ($i = 0; $i < $max; $i++) {
&play_one;
}
printf "played %d games: NEW: %d (%2d%%) OLD: %d (%2d%%)\n",
$totalct, $newct, int($newct * 100 / $totalct),
$oldct, int($oldct * 100 / $totalct);
3812 bash$ ./monty.pl
this is the monty hall problem. FP is the player's first pick,
MP is what door monty shows you, SP is the player's second pick,
AT shows which door the car is actually behind. also shown is
if the player SHOULD have kept their OLD choice or gone with the
NEW one.
trial num: FP MP SP AT
1: 3 2 1 1 NEW
2: 1 2 3 3 NEW
3: 2 1 3 2 OLD
4: 1 3 2 2 NEW
5: 1 3 2 2 NEW
6: 3 1 2 2 NEW
7: 2 1 3 2 OLD
8: 2 1 3 2 OLD
9: 2 3 1 1 NEW
10: 2 1 3 3 NEW
11: 2 3 1 1 NEW
12: 1 3 2 2 NEW
13: 3 1 2 2 NEW
14: 2 3 1 1 NEW
15: 3 2 1 1 NEW
16: 3 1 2 2 NEW
17: 2 1 3 3 NEW
18: 1 2 3 3 NEW
19: 2 3 1 1 NEW
20: 2 1 3 3 NEW
played 20 games: NEW: 17 (85%) OLD: 3 (15%)
3813 bash$ ./monty.pl 100000 | grep played
played 100000 games: NEW: 66606 (66%) OLD: 33394 (33%)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment