From Wikipedia (https://en.wikipedia.org/wiki/Monty_Hall_problem):
The Monty Hall problem is a brain teaser, in the form of a probability puzzle, loosely based on the American television game show Let's Make a Deal and named after its original host, Monty Hall. The problem was originally posed (and solved) in a letter by Steve Selvin to the American Statistician in 1975.[1][2] It became famous as a question from reader Craig F. Whitaker's letter quoted in Marilyn vos Savant's "Ask Marilyn" column in Parade magazine in 1990:[3]
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. You pick a door, say No. 1, and the host, who knows what's behind the doors, opens another door, say No. 3, which has a goat. He then says to you, "Do you want to pick door No. 2?" Is it to your advantage to switch your choice?
The "correct" answer is to switch. You win with probability $\frac{2}{3}$ if you switch and only win with probability $\frac{1}{3}$ if you choose not to switch. I'll show why this is true below.
Let's say that your strategy is always to switch, and try to show that if you switch you will win with a $\frac{2}{3}$ chance. The following tree shows what happens. The first branching is what the winning door is, and the second branching is what you originally chose. Below each leaf is either "W" or "L" representing winning or losing if you were to switch.
We can see just by counting the "L"s and "W"s that you win $\frac{2}{3}$ of the time and lose $\frac{1}{3}$ of the time if you decide to switch. We can next draw the same tree for deciding not to switch and staying with your original choice. This is the following:
Counting the number of wins and losses for the stay method reveals that you win $\frac{1}{3}$ of the time and lose the remaining $\frac{2}{3}$ of the time. Because the Monty Hall Problem is relatively small, we're able to easily draw the trees and count the wins and losses for both strategies.
Writing out the conditional probabilites, we have:
$P(\text{ win } | \text{ switch }) = \frac{2}{3}$ and $P(\text{ lose } | \text{ switch }) = \frac{1}{3}$
$P(\text{ win } | \text{ not switch }) = \frac{1}{3}$ and $P(\text{ lose } | \text{ not switch }) = \frac{2}{3}$
If still not convinced, we can write a simple python implementation of the game and then play it multiple times, recording the fraction of times you win if you switch and the fraction of times you win if you stay.
import random
def monty_hall(switch):
choices = [1,2,3]
winning_door = choices[random.randint(0,2)]
original_choice = choices[random.randint(0,2)]
if not switch:
return winning_door == original_choice
bad = choices.copy()
for choice in choices:
if choice == winning_door or choice == original_choice:
bad.remove(choice)
revealed = bad[random.randint(0,len(bad)-1)]
choices.remove(revealed)
choices.remove(original_choice)
return choices[0] == winning_door
I'll now run this 1 million times, and then display the probabilities of winning if you use the switch strategy and winning if you use the stay strategy.
total = 1000000
switch = 0
stay = 0
for i in range(total):
switch += 1 if monty_hall(True) else 0
stay += 1 if monty_hall(False) else 0
print(f"Chance of winning using switch strategy: {(switch/total)}")
print(f"Chance of winning using stay strategy: {(stay/total)}")
Chance of winning using switch strategy: 0.666859 Chance of winning using stay strategy: 0.332439
We can see that the $\frac{2}{3}$ and $\frac{1}{3}$ win rates for the respective strategies are what we see when testing this empirically.
The function below is a slightly modified version of the above function that lets a user actually play the Monty Hall Problem and test both strategies.
def play_monty_hall():
choices = [1,2,3]
winning_door = choices[random.randint(0,2)]
original_choice = int(input("Enter a number between 1 and 3 (inclusive): "))
if original_choice < 1 or original_choice > 3:
print("Error understanding input")
return
print(f"You chose door #{original_choice}")
bad = choices.copy()
for choice in choices:
if choice == winning_door or choice == original_choice:
bad.remove(choice)
revealed = bad[random.randint(0,len(bad)-1)]
print(f"Host revealed door #{revealed}")
switch = input("Do you want to switch? (y/n): ")
if switch.lower()[0] == "y":
switch = True
else:
switch = False
print(f"You chose{'' if switch else ' not'} to switch")
if not switch:
if original_choice == winning_door:
print("You win!")
return
print(f"You lose! The prize was behind door #{winning_door}")
choices.remove(revealed)
choices.remove(original_choice)
if choices[0] == winning_door:
print("You win!")
return
print(f"You lose! The prize was behind door #{winning_door}")
play_monty_hall()
Enter a number between 1 and 3 (inclusive): 1 You chose door #1 Host revealed door #3 Do you want to switch? (y/n): y You chose to switch You lose! The prize was behind door #1
play_monty_hall()
Enter a number between 1 and 3 (inclusive): 2 You chose door #2 Host revealed door #3 Do you want to switch? (y/n): y You chose to switch You win!