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

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.

- The
*persistent strategy*never switches the door and always sticks to the door chosen first. - 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 [ ]:
```