Monty Hall problem: Difference between revisions
(Better statement of problem.) |
Underscore (talk | contribs) (Added Haskell; moved "Problem Statement" into lead) |
||
Line 2: | Line 2: | ||
Run random simulations of the [http://en.wikipedia.org/wiki/Monty_Hall_problem Monty Hall] game. Show the effects of a strategy of the contestant always keeping his first guess so it can be contrasted with the strategy of the contestant always switching his guess. |
Run random simulations of the [http://en.wikipedia.org/wiki/Monty_Hall_problem Monty Hall] game. Show the effects of a strategy of the contestant always keeping his first guess so it can be contrasted with the strategy of the contestant always switching his guess. |
||
==Problem Statement== |
|||
:Suppose you're on a game show and you're given the choice of three doors. Behind one door is a car; behind the others, goats. The car and the goats were placed randomly behind the doors before the show. The rules of the game show are as follows: After you have chosen a door, the door remains closed for the time being. The game show host, Monty Hall, who knows what is behind the doors, now has to open one of the two remaining doors, and the door he opens must have a goat behind it. If both remaining doors have goats behind them, he chooses one randomly. After Monty Hall opens a door with a goat, he will ask you to decide whether you want to stay with your first choice or to switch to the last remaining door. Imagine that you chose Door 1 and the host opens Door 3, which has a goat. He then asks you "Do you want to switch to Door Number 2?" Is it to your advantage to change your choice? ([[#refKraussandWang2003|Krauss and Wang 2003:10]])}} |
:Suppose you're on a game show and you're given the choice of three doors. Behind one door is a car; behind the others, goats. The car and the goats were placed randomly behind the doors before the show. The rules of the game show are as follows: After you have chosen a door, the door remains closed for the time being. The game show host, Monty Hall, who knows what is behind the doors, now has to open one of the two remaining doors, and the door he opens must have a goat behind it. If both remaining doors have goats behind them, he chooses one randomly. After Monty Hall opens a door with a goat, he will ask you to decide whether you want to stay with your first choice or to switch to the last remaining door. Imagine that you chose Door 1 and the host opens Door 3, which has a goat. He then asks you "Do you want to switch to Door Number 2?" Is it to your advantage to change your choice? ([[#refKraussandWang2003|Krauss and Wang 2003:10]])}} |
||
Line 80: | Line 79: | ||
Algorithm switch: prize count = 6655, = 66.55% |
Algorithm switch: prize count = 6655, = 66.55% |
||
Algorithm random: prize count = 4991, = 49.91% |
Algorithm random: prize count = 4991, = 49.91% |
||
bash$ |
bash$</pre> |
||
</pre> |
|||
=={{header|Haskell}}== |
|||
<pre>import Random (StdGen, getStdGen, randomR) |
|||
trials = 10000 |
|||
data Door = Car | Goat |
|||
play :: Bool -> StdGen -> (Door, StdGen) |
|||
play switch g = (prize, new_g) |
|||
where (n, new_g) = randomR (0, 2) g |
|||
d1 = [Car, Goat, Goat] !! n |
|||
prize = case switch of |
|||
False -> d1 |
|||
True -> case d1 of |
|||
Car -> Goat |
|||
Goat -> Car |
|||
cars :: Int -> Bool -> StdGen -> (Int, StdGen) |
|||
cars n switch g = f n (0, g) |
|||
where f 0 (cs, g) = (cs, g) |
|||
f n (cs, g) = f (n - 1) (cs + result, new_g) |
|||
where result = case prize of Car -> 1; Goat -> 0 |
|||
(prize, new_g) = play switch g |
|||
main = do |
|||
g <- getStdGen |
|||
let (switch, g2) = cars trials True g |
|||
(stay, _) = cars trials False g2 |
|||
putStrLn $ msg "switch" switch |
|||
putStrLn $ msg "stay" stay |
|||
where msg strat n = "The " ++ strat ++ " strategy succeeds " ++ |
|||
percent n ++ "% of the time." |
|||
percent n = show $ round $ |
|||
100 * (fromIntegral n) / (fromIntegral trials)</pre> |
|||
=={{header|Python}}== |
=={{header|Python}}== |
||
<python> |
<python> |
Revision as of 19:27, 10 August 2008
You are encouraged to solve this task according to the task description, using any language you may know.
Run random simulations of the Monty Hall game. Show the effects of a strategy of the contestant always keeping his first guess so it can be contrasted with the strategy of the contestant always switching his guess.
- Suppose you're on a game show and you're given the choice of three doors. Behind one door is a car; behind the others, goats. The car and the goats were placed randomly behind the doors before the show. The rules of the game show are as follows: After you have chosen a door, the door remains closed for the time being. The game show host, Monty Hall, who knows what is behind the doors, now has to open one of the two remaining doors, and the door he opens must have a goat behind it. If both remaining doors have goats behind them, he chooses one randomly. After Monty Hall opens a door with a goat, he will ask you to decide whether you want to stay with your first choice or to switch to the last remaining door. Imagine that you chose Door 1 and the host opens Door 3, which has a goat. He then asks you "Do you want to switch to Door Number 2?" Is it to your advantage to change your choice? (Krauss and Wang 2003:10)}}
Note that the player may initially choose any of the three doors (not just Door 1), that the host opens a different door revealing a goat (not necessarily Door 3), and that he gives the player a second choice between the two remaining unopened doors.
Simulate at least a thousand games using three doors for each strategy and show the results in such a way as to make it easy to compare the effects of each strategy.
AWK
#!/bin/gawk -f # Monty Hall problem BEGIN { srand() doors = 3 iterations = 10000 # Behind a door: EMPTY = "empty"; PRIZE = "prize" # Algorithm used KEEP = "keep"; SWITCH="switch"; RAND="random"; # } function monty_hall( choice, algorithm ) { # Set up doors for ( i=0; i<doors; i++ ) { door[i] = EMPTY } # One door with prize door[int(rand()*doors)] = PRIZE chosen = door[choice] del door[choice] #if you didn't choose the prize first time around then # that will be the alternative alternative = (chosen == PRIZE) ? EMPTY : PRIZE if( algorithm == KEEP) { return chosen } if( algorithm == SWITCH) { return alternative } return rand() <0.5 ? chosen : alternative } function simulate(algo){ prizecount = 0 for(j=0; j< iterations; j++){ if( monty_hall( int(rand()*doors), algo) == PRIZE) { prizecount ++ } } printf " Algorithm %7s: prize count = %i, = %6.2f%%\n", \ algo, prizecount,prizecount*100/iterations } BEGIN { print "\nMonty Hall problem simulation:" print doors, "doors,", iterations, "iterations.\n" simulate(KEEP) simulate(SWITCH) simulate(RAND) }
Sample output:
bash$ ./monty_hall.awk Monty Hall problem simulation: 3 doors, 10000 iterations. Algorithm keep: prize count = 3411, = 34.11% Algorithm switch: prize count = 6655, = 66.55% Algorithm random: prize count = 4991, = 49.91% bash$
Haskell
import Random (StdGen, getStdGen, randomR) trials = 10000 data Door = Car | Goat play :: Bool -> StdGen -> (Door, StdGen) play switch g = (prize, new_g) where (n, new_g) = randomR (0, 2) g d1 = [Car, Goat, Goat] !! n prize = case switch of False -> d1 True -> case d1 of Car -> Goat Goat -> Car cars :: Int -> Bool -> StdGen -> (Int, StdGen) cars n switch g = f n (0, g) where f 0 (cs, g) = (cs, g) f n (cs, g) = f (n - 1) (cs + result, new_g) where result = case prize of Car -> 1; Goat -> 0 (prize, new_g) = play switch g main = do g <- getStdGen let (switch, g2) = cars trials True g (stay, _) = cars trials False g2 putStrLn $ msg "switch" switch putStrLn $ msg "stay" stay where msg strat n = "The " ++ strat ++ " strategy succeeds " ++ percent n ++ "% of the time." percent n = show $ round $ 100 * (fromIntegral n) / (fromIntegral trials)
Python
<python> I could understand the explanation of the Monty Hall problem but needed some more evidence
References:
http://www.bbc.co.uk/dna/h2g2/A1054306 http://en.wikipedia.org/wiki/Monty_Hall_problem especially: http://en.wikipedia.org/wiki/Monty_Hall_problem#Increasing_the_number_of_doors
from random import randrange, shuffle
doors, iterations = 3,100000 # could try 100,1000
def monty_hall(choice, switch=False, doorCount=doors):
# Set up doors door = [False]*doorCount # One door with prize door[randrange(0, doorCount)] = True
chosen = door[choice]
unpicked = door del unpicked[choice]
# Out of those unpicked, the alterantive is either: # the prize door, or # an empty door if the initial choice is actually the prize. alternative = True in unpicked
if switch: return alternative else: return chosen
print "\nMonty Hall problem simulation:" print doors, "doors,", iterations, "iterations.\n"
print "Not switching allows you to win", print [monty_hall(randrange(3), switch=False)
for x in range(iterations)].count(True),
print "out of", iterations, "times." print "Switching allows you to win", print [monty_hall(randrange(3), switch=True)
for x in range(iterations)].count(True),
print "out of", iterations, "times.\n" </python> Sample output:
Monty Hall problem simulation: 3 doors, 100000 iterations. Not switching allows you to win 33337 out of 100000 times. Switching allows you to win 66529 out of 100000 times.