Introduction
New to the monty hall problem?
In short, the problem is:
In the game show, there are 3 doors. 1 has a car, 2 have sheep. You pick a door, and get whatever is behind the door you picked.
The game show host knows which door has the car, and which doors have sheep.
When you choose a door, the host opens a sheep door, and shows you that it has sheep.
Now, you are given a choice:
- Stick to the door you picked
- Switch to the other remaining door
What has a higher probability of winning the car, sticking or changing?
Need more details? read it its wikipedia article
The math says that before the reveal, your probability of winning was 33%. But after the reveal, if you switch your door - your probability of winning becomes 66%.
This is absolutely mind bending. I looked at the math. But was not really convinced.
You know what's better than modelling the problem in math, solving it, and coming up with the final probabilities? Programming a simulation, running it a million times, and directly looking at the probabilities. Now this is a method that I automatically trust.
I am average at math, but I'm great at directly looking at the results with my own eyes.
Simulation and result
Result: it is true. Changing the door gives a higher chance of winning.
normal_probability: 0.334064
stick_door_probability: 0.334064
change_door_probability: 0.665936
The entire program, if you want it:
# Usual warning: code was written in 2-3 minutes.
# It is not clean (again, wrote it in 2-3 minutes)
import random
iterations = 1_000_000
# generate door simulations
simulations = np.full((iterations, 3), False)
# generate column of true
index_of_true = np.random.randint(3, size=iterations)
# set true values
simulations[range(iterations), index_of_true] = True
simulations_array = simulations.tolist()
simulations_array
normal_results = []
change_door_results = []
stick_door_results = []
for simulation in simulations_array:
# pick a random door
# check if door is correct or wrong
chosen_door = random.randint(0, 2)
normal_results.append(simulation[chosen_door])
# flippable door situration
# eliminate a false door other than chosen door
# pick a closed door
all_doors = [0,1,2]
all_doors.remove(chosen_door)
non_chosen_doors = all_doors
sheep_doors_in_non_chosen_doors = []
for door_index in non_chosen_doors:
if not simulation[door_index]:
sheep_doors_in_non_chosen_doors.append(door_index)
# choose a random sheep door to eliminate
door_eliminated = random.choice(sheep_doors_in_non_chosen_doors)
# don't change door, and check if guess was right
stick_door_results.append(simulation[chosen_door])
# change door, and check if guess was right
all_doors = [0, 1, 2]
all_doors.remove(chosen_door)
all_doors.remove(door_eliminated)
other_door_index = all_doors[0]
changed_chosen_door = other_door_index
change_door_results.append(simulation[changed_chosen_door])
# calculate probability of winning
normal_probability = sum(normal_results) / len(normal_results)
stick_door_probability = sum(stick_door_results) / len(stick_door_results)
change_door_probability = sum(change_door_results) / len(change_door_results)
print(f"normal_probability: {normal_probability}"")
print(f"stick_door_probability: {stick_door_probability_}")
print(f"change_door_probability: {change_door_probability}")
That's the fun of programming. You can quickly simulate most probability based problems and see things for yourself.