In [ ]:
%autosave 0
from IPython.core.display import HTML, display
display(HTML('<style>.container { width:100%; !important } </style>'))

The Monty Hall Problem

The Monty Hall problem is a famous probability puzzle that is based on the TV show Let's Make a Deal, which was aired in the US from the sixties through the seventies. The host of this show was Monty Hall. In his show, a player had to choose one of three doors. Monty Hall had placed goats behind two of the doors but there was a shiny new car behind the third door. Of course, the player did not know the location of the door with the car.
Once the player had told Monty Hall the door she had chosen, Monty Hall would open one of the other two doors. However, Monty Hall would never open the door with the car behind it. Therefore, if the player had chosen the door with the car, Monty Hall would have randomly chosen a door leading to a goat. If, instead, the player had chosen a door leading to a goat, Monty Hall would have opened the door showing the other goat. In either case, after opening the door Monty Hall would ask the player whether she wanted to stick with her first choice or whether, instead, she wanted to pick the remaining closed door. In order to better understand the problem you can try the animation at http://math.ucsd.edu/~crypto/Monty/monty.html. The question now is whether it is a good strategy to stick with the door chosen first or whether it is a better idea to switch doors.

Mathematically, the reasoning is quite simple: As there are three doors initially and the probability that the car is behind any of them is the same, the probability that the door chosen first leads to the car is $$\frac{1}{3}.$$
Therefore, the probability that the car is behind the other unopened door has to be $$\frac{2}{3},$$ as the two probabilities have to add up to $1$. Hence the best strategy is to switch the door. Although the reasoning given above is straightforward, many people don't believe it, as is shown by this article. In order to convince them, the best thing is to run a Monte Carlo simulation.

The function $\texttt{arb}(S)$ returns an arbitrary element from the set $S$.

In [ ]:
def arb(S):
for x in S: return x

In [ ]:
import random as rnd

The function calculate_chances simulates the game of Monty Hall $n$ times and keeps track how often two different strategies win.

1. The persistent strategy never switches the door and always sticks to the door chosen first.
2. The wavering strategy always switches the door.

In [ ]:
def calculate_chances(n):
success_persistent = 0
success_wavering   = 0
for _ in range(n):
car    = rnd.randint(1, 3)
choice = rnd.randint(1, 3)
opened = rnd.choice(list({1,2,3} - {choice,car}))
last   = arb({ 1, 2, 3 } - { choice, opened })
if car == choice:
success_persistent += 1
if car == last:
success_wavering  += 1
print(f'The persistent strategy wins {success_persistent} cars.')
print(f'The wavering   strategy wins {success_wavering  } cars.')

In [ ]:
%%time
calculate_chances(1000000)

In [ ]: