A Monte Carlo simulation of the Monty Hall Problem

Consider the following game. You have a choice of three doors. Behind one door is a car. Behind the other two doors are goats. After you pick your door, the host, Monty Hall, will show you what is behind one of the other two doors. Should you switch your door at this point?

Marilyn vos Savant, who had the higher IQ on record, asserted that you should switch your door. Legions of mathematics Ph.D. dissented.

Who was right? Let's do a Monte Carlo simulation to find out!

Case 1

The case where you don't switch! In this case, it's really easy. It doesn't matter which door Monty shows us because we stay with our original choice.

In [2]:
function monty_hall_stay()
    door_car = rand(1:3)
    door_pick = rand(1:3)
    if door_pick == door_car
        return 1
    else
        return 0
    end
end
Out[2]:
monty_hall_stay (generic function with 1 method)
In [3]:
wins = 0
ntrials = 10000
for i=1:ntrials
    wins += monty_hall_stay()
end
wins/ntrials
Out[3]:
0.3348

Case 2

The case where you do switch! In this case, we have to be careful about what goes where. The setdiff function helps us remove choices. It's like set subtraction. So setdiff([1;2;3],door_car) removes the element door_car from the set 1,2,3, which tells us exactly where the goats are.

In [19]:
function monty_hall_switch()
    door_car = rand(1:3)
    door_pick = rand(1:3)
    door_goats = setdiff([1;2;3],door_car)
    if door_pick == door_car
        door_show = rand(door_goats)
    else
        door_show = setdiff(door_goats,door_pick)
    end
    door_switch = setdiff([1;2;3],[door_pick;door_show])[1]
    #@show door_car, door_pick, door_show, door_goats, door_switch
    door_pick = door_switch
    if door_pick == door_car
        return 1
    else
        return 0
    end
end
Out[19]:
monty_hall_switch (generic function with 1 method)
In [27]:
wins = 0
ntrials = 10000
for i=1:ntrials
    wins += monty_hall_switch()
end
wins/ntrials
Out[27]:
0.6655