#!/usr/bin/perl # Here's a Perl script with which to empirically test # the Monty Hall problem. # I'll admit that the results completely blew me away # the first time I ran the program, and I still wonder # if there isn't some odd bug which just happens to # make the numbers look the way they do... # 9 Aug 2001 # -J # Empirical test of the Monty Hall problem # Run with -v to see each game. $iterations = 10; # How many games to play @items = ("goat1", "goat2", "car"); #We'll number the items 0-2 $verbosity = 1 if $ARGV[0] eq "-v"; sub verbose { if($verbosity == 1) { print($_[0]); } } for(1..$iterations) { $door[0] = int rand 3; # What's behind door #1? if($door[0] == 0) { $door[1] = 1 + (int rand 2); # Door #2 gets 1 or 2 if($door[1] == 1) { $door[2] = 2; } else { $door[2] = 1; } } if($door[0] == 1) { $door[1] = 2 * (int rand 2); # Door #2 gets 0 or 2 if($door[1] == 0) { $door[2] = 2; } else { $door[2] = 0; } } if($door[0] == 2) { $door[1] = int rand 2; # Door #2 gets 0 or 1 if($door[1] == 0) { $door[2] = 1; } else { $door[2] = 0; } } verbose( "Door 1: $items[$door[0]] Door 2: $items[$door[1]] Door 3: $items[$door[2]]\n" ); $contestant = int rand 3; verbose( "Contestant chooses door " . ($contestant+1) . ".\n" ); # If the contestant picked the car, Monty picks either other door if($items[$door[$contestant]] eq "car") { $coinflip = int rand 2; if($contestant == 0) { $monty = ($coinflip ? 1 : 2); } if($contestant == 1) { $monty = ($coinflip ? 0 : 2); } if($contestant == 2) { $monty = ($coinflip ? 0 : 1); } } # Otherwise, he picks the other goat if($items[$door[$contestant]] eq "goat1") { if($contestant == 0) { $monty = ($items[$door[1]] eq "goat2" ? 1:2); } if($contestant == 1) { $monty = ($items[$door[0]] eq "goat2" ? 0:2); } if($contestant == 2) { $monty = ($items[$door[0]] eq "goat2" ? 0:1); } } if($items[$door[$contestant]] eq "goat2") { if($contestant == 0) { $monty = ($items[$door[1]] eq "goat1" ? 1:2); } if($contestant == 1) { $monty = ($items[$door[0]] eq "goat1" ? 0:2); } if($contestant == 2) { $monty = ($items[$door[0]] eq "goat1" ? 0:1); } } verbose( "Monty opens door " . ($monty+1) . ".\n" ); $sticker = ($items[$door[$contestant]] eq "car") ? "wins" : "loses"; $switcher = ($items[$door[$contestant]] eq "car") ? "loses" : "wins"; verbose( "Sticker $sticker. Switcher $switcher.\n\n" ); if($sticker eq "wins") { $stickers++ } if($switcher eq "wins") { $switchers++ } } print "\nGrand totals:\nStickers: $stickers\nSwitchers: $switchers\n";