Skip to content

Instantly share code, notes, and snippets.

@kiriappeee
Created December 17, 2012 09:03
Show Gist options
  • Save kiriappeee/4316871 to your computer and use it in GitHub Desktop.
Save kiriappeee/4316871 to your computer and use it in GitHub Desktop.
Testing the Monty Hall Problem
"""As much as I understood the theorems of the monty hall problem
my brain simply refused to take it in and accept, so I wrote a very quick (and dirty) script to just test it out.
The script randomly generates two goats (designated as 0) and a car (designated by 1) for three doors (stored in a dictionary. I don't know why I
chose that. Anyway. Here's the script... And it works. Funnily enough when writing the program I kept having snippets of thoughts on how staying
with your old choice would leave you at 33% anyways since you didn't take advantage of the situation of knowing one door which had a goat behind it
That prompted me to write the normal test where based on intuition, you'd stick with the door you picked originally. And yes, everything checks out.
Edit: I also thought of the case of what if the game host reveals a door behind which there is a goat BEFORE you make your first pick.
Isn't that like the first scenario but the order just reversed? Apparently not. The results move down to 50-50. My mind has been blown.
In the face of math, trust not your intuition I guess. Oh, and I included results at the bottom.
"""
import random
"""this is the standard monty test. Works as follows
Pick a random door.
Host reveals a door behind which there is a goat
You are mathematical genius so you switch doors
Resulted in ~66% win ratio
"""
def montyTest():
wins = 0
losses = 0
for i in range(0,100000):
random.seed()
doors = {1:0,2:0,3:0}
doors[1] = random.randint(0,1)
if doors[1] == 1:
doors[2] = doors[3] = 0
else:
doors[2] = random.randint(0,1)
doors[3] = 1 - doors[2]
#print ('door 1: %d , door 2: %d, door 3: %d' % (doors.get(1),doors.get(2),doors.get(3)))
#logic for picking the door here
#randomly pick the first door
pick = random.randint(1,3)
"""if doors[pick] == 1:
print 'first door was car'
else:
print 'first door was goat'"""
#since the monty hall problem means we discard our first choice anyway, we pop it out of the list
doors.pop(pick)
#search for a door with a goat behind in and remove that door (the host of the show does this in the monty hall problem)
for k in doors.keys():
if doors[k] == 0:
doors.pop(k)
break
#which leaves us with the only door remaining. For all we know we could have discarded a car in the first one.
if doors.get(doors.keys()[0]) == 1:
wins += 1
else:
losses += 1
print 'wins: ' + str(wins)
print 'losses: ' + str(losses)
"""This is the monty hall test for non mathematicians
Pick a door at random
Host revelas a door behind which there is a goat
You are stubborn and don't switch because of your intuition
Resulted in ~33% win ratio
"""
def normalTest():
wins = 0
losses = 0
for i in range(0,100000):
random.seed()
doors = {1:0,2:0,3:0}
doors[1] = random.randint(0,1)
if doors[1] == 1:
doors[2] = doors[3] = 0
else:
doors[2] = random.randint(0,1)
doors[3] = 1 - doors[2]
#print ('door 1: %d , door 2: %d, door 3: %d' % (doors.get(1),doors.get(2),doors.get(3)))
#logic for picking the door here
#randomly pick the first door
pick = random.randint(1,3)
"""if doors[pick] == 1:
print 'first door was car'
else:
print 'first door was goat'"""
#in this one, since we are going to stick with the door choice anyway, we stop the test here.
if doors.get(pick) == 1:
wins += 1
else:
losses += 1
print 'wins: ' + str(wins)
print 'losses: ' + str(losses)
"""This may or may not fall under a monty hall scenario but it was an interesting discussion. Scenario is as follows
Before you pick at random, the host reveals a door behind which there is a goat
You pick a door at random
Resulted in ~50% win ratio
Note - Even if you changed logic where if you randomly picked a door behind which there was a goat then you win and vice versa (the equivalent of picking
two doors... sort of) you'd still end up with ~50% win ratio.
"""
def abnormalTest():
wins = 0
losses = 0
for i in range(0,100000):
random.seed()
doors = {1:0,2:0,3:0}
doors[1] = random.randint(0,1)
if doors[1] == 1:
doors[2] = doors[3] = 0
else:
doors[2] = random.randint(0,1)
doors[3] = 1 - doors[2]
for k in doors.keys():
if doors[k] == 0:
doors.pop(k)
break
if doors.get(doors.keys()[random.randint(0,1)]) == 1:
wins += 1
else:
losses+= 1
print 'wins: ' + str(wins)
print 'losses: ' + str(losses)
"""results of the tests are as follows.
Python 2.7.2 (default, Jun 12 2011, 14:24:46) [MSC v.1500 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import monty
>>> monty.montyTest()
wins: 66598
losses: 33402
>>> monty.abnormalTest()
wins: 50253
losses: 49747
>>> monty.abnormalTest()
wins: 50070
losses: 49930
>>> monty.abnormalTest()
wins: 49719
losses: 50281
>>> monty.abnormalTest()
wins: 49791
losses: 50209
>>> monty.normalTest()
wins: 33317
losses: 66683
>>>
"""
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment