[フレーム]
Last Updated: January 09, 2017
·
8.958K
· thedispossessed

The Monty Hall Problem in Python

Again, this is another coding exercise in Dream.In.Code. Well, it is actually a challenge but since my submission pales compared to the others, I don't prefer to call it as one.

What is the Monty Hall Problem?

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 [but the door is not opened], 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?

Read more here:
http://www.dreamincode.net/forums/topic/292496-prove-the-monty-hall-problem-via-simulation/
http://en.wikipedia.org/wiki/Monty_Hall_problem

Basically, you need to prove that switching doors when asked to switch will improve your chances by 2/3 as opposed to the 1/3 chance if you don't switch doors.

Here's what I cooked up:

Door Creation

def addDoors():
picker = randint(0,1)
if picker == 1:
 door1,door2,door3 = "dragon","goat","goat"
else:
 door1 = "goat"
 picker = randint(0,1)
 if picker == 1:
 door2,door3 = "dragon","goat"
 else:
 door2,door3 = "goat","dragon"
return [door1,door2,door3]

Goat Door Opener

def openGoatDoor(doors):
 door = ""
 while door != "goat":
 doorNumber = randint(0,2)
 door = doors[doorNumber]
 return doorNumber

The Monty Hall Simulation

def montyhall(doorNumber,switchOk):
 doors = addDoors()
 goatDoor = addDoors()
 while goatDoor == doorNumber:
 goatDoor = openGoatDoor(doors)
 if switchOk == "yes":
 doorNumber = [y for y in range(2) if y not in [doorNumber,goatDoor]]
 return doors[doorNumber[0]]
 else:
 return doors[doorNumber]

The Tester

def testMontyHall(playTimes,switch):
 wondragon,wonGoat = 0,0
 for i in range(playTimes):
 prize = montyhall(randint(0,2),switch)
 if prize == "dragon":
 wondragon += 1
 else:
 wonGoat += 1
 print "Dragons:",wondragon
 print "Goat:",wonGoat

The Results
>>> testMontyHall(1000000,"no")
Dragons: 332961
Goat: 667039
>>> testMontyHall(1000000,"yes")
Dragons: 666757
Goat: 333243

And this concludes The Monty Hall show. Hope you enjoyed it.

1 Response
Add your response

Here's mine, yours is a bit fancier!
Functions:

#monty_hall.py
def gen_doors():
 doors = [0,1,2]
 car = random.randrange(3)
 doors[car] = "Car"
 goats = list(range(3))
 del goats[car]
 for i in goats:
 doors[i] = "Goat"
 return doors

def random_play(doors = ["Goat","Car","Goat"], switch = True):
 goats = []
 [goats.append(i) for i in range(3) if doors[i] == "Goat"]
 pick = random.randrange(3)
 if switch == True:
 if pick in goats:
 return "Car"
 else: return "Goat"
 else:
 if pick in goats:
 return "Goat"
 else: return "Car"
#sim.py
import monty_hall
plays = 100000

# With Switch:
n_goats = 0
n_cars = 0
for i in range(plays):
 if monty_hall.random_play(monty_hall.gen_doors(), True) == "Goat": n_goats += 1
 else: n_cars += 1
print("With Switching:\nGoats: ", n_goats, "\n", "Cars: ", n_cars, "\n")

n_goats = 0
n_cars = 0
# Without Switch:
for i in range(plays):
 if monty_hall.random_play(monty_hall.gen_doors(), False) == "Goat": n_goats +=1
 else: n_cars +=1
print("Without Switching:\nGoats: ", n_goats, "\n", "Cars: ", n_cars)

[Out]
With Switching:
Goats: 33210
Cars: 66790

Without Switching:
Goats: 66812
Cars: 33188

over 1 year ago ·

AltStyle によって変換されたページ (->オリジナル) /