Monty Hall Problem

There’s one old very nice mind crashing puzzle that I really like: Monty Hall Problem. It is amazing because of how counterintuitive the answer is. You won’t just believe it’s true until you triple-check it, read the proof and even after that you will likely keep thinking that there should be a catch somewhere. So here is the problem as quoted from Wikipedia:

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?

So is it better to switch your choice, to stick with your first one or it doesn’t matter? If you are like me and majority of other people the most intuitive answer will be: switching a door won’t make a difference and the chance of winning is still the same. Right?

The truth is switching will give you 2/3 chance of winning while sticking with your choice is only 1/3 chance. Why? When you are picking one of 3 doors your chance to get a car is 1/3, while your chance to get a goat is 2/3. The chance that a car behind one of the 2 doors you didn’t chose is also 2/3. When one of the 2 doors is opened for you and you know there’s a goat so you won’t pick it, the chance that the car is behind the last door is still 2/3. Still doesn’t sounds right? Let’s run a programming experiment and generate 1000 choices for every scenario.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import pandas as pd
from pylab import *
from random import randrange

def boxes():
    b = ["goat"]*3
    b[randrange(0, 3)] = "car"
    return b

def gen_choices(num, switch = True):
    results = []
    for _ in range(num):
        b = boxes()
        choice1 = randrange(0, 3)
        c = range(3)
        c.remove(choice1)

        choice2 = c[0] if b[c[0]] == "car" else c[1]
        prize = b[choice2] if switch else b[choice1]

        results.append(prize)

    return results


fig, axes = plt.subplots(nrows=1, ncols=2)
fig.set_figheight(5)
fig.set_figwidth(8)

# generate choices with switching
switch = pd.Series(gen_choices(1000, True)).value_counts()
switch.plot(ax=axes[0], kind='bar', title="switched", color='y')

# generate choices without switching
noswitch = pd.Series(gen_choices(1000, False)).value_counts()
noswitch.plot(ax=axes[1], kind='bar', title="didn't switch", color='r')
plt.show()

Yup. Switching is winning. Isn’t it amazing?

Comments