The following Perl program computes an approximate solution of the Monty Hall problem by simulation. Two strategies are simulated: stick with initial choice every time, or switch from initial choice every time. The program performs a number of games and counts how many times each strategy wins the game.
The result of the simulation almost always shows that the switch strategy wins about twice as many times as the stick strategy. This is empirical evidence that switching is a better strategy in this game.
#!/usr/bin/perl
# Approximate solution of the Monty Hall problem
# Use -v to see each game. (default: off)
# Use -i # to set number of iterations. (default: 3000)
use strict;
my $iterations = 3000; # How many games to play
my $verbosity = 0;
while (@ARGV) {
my $param = shift @ARGV;
$verbosity = 1 if $param eq '-v';
$iterations = int (shift @ARGV) if $param eq '-i';
}
sub verbose {
print $_[0]."\n" if $verbosity;
}
my $stickers;
my $switchers;
print "Playing $iterations games...\n\n";
for(1..$iterations) {
my @items = qw(goat goat prize); # two goats, one prize
my @door;
while (@items) { # put the @items into the @door array in random order
push (@door, splice (@items, int rand @items, 1));
}
verbose ("Door 0: $door[0]; Door 1: $door[1]; Door 2: $door[2]");
my $contestant = int rand 3, my $monty, my $alternate;
# If the contestant picked the prize, Monty picks another door at random.
if ($door[$contestant] eq 'prize') {
$monty = ($contestant + (int rand 2) + 1) % 3;
}
# Otherwise, he picks the other goat.
else {
$monty = $door [ ($contestant+1) % 3 ] eq 'goat' ? ($contestant+1) % 3 : ($contestant+2) % 3;
}
$alternate = ($contestant + 1) % 3 == $monty ? ($contestant + 2) % 3 : ($contestant + 1) % 3;
verbose ("Contestant opens door $contestant, Monty opens door $monty; alternate is $alternate.");
if ($door[$contestant] eq 'prize') {
verbose ("Sticker wins.");
$stickers++;
}
if ($door[$alternate] eq 'prize') {
verbose ("Switcher wins.");
$switchers++;
}
}
print "Grand totals:
Sticker has won $stickers times
Switcher has won $switchers times
";
Here is the output of a sample run of this program for the default 3000 iterations:
Playing 3000 games...
Grand totals:
Sticker has won 1013 times
Switcher has won 1987 times
External links
- [1] (another simulation, in PHP)