Skip to content

Commit 3b1b11c

Browse files
committed
Add the Monty Hall problem
1 parent 58392bc commit 3b1b11c

File tree

5 files changed

+138
-0
lines changed

5 files changed

+138
-0
lines changed
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
//: Playground - noun: a place where people can play
2+
3+
import Foundation
4+
5+
func random(n: Int) -> Int {
6+
return Int(arc4random_uniform(UInt32(n)))
7+
}
8+
9+
let numberOfDoors = 3
10+
11+
var rounds = 0
12+
var winOriginalChoice = 0
13+
var winChangedMind = 0
14+
15+
func playRound() {
16+
// The door with the prize.
17+
let prizeDoor = random(numberOfDoors)
18+
19+
// The door the player chooses.
20+
let chooseDoor = random(numberOfDoors)
21+
22+
// The door that Monty opens. This must be empty and not the one the player chose.
23+
var openDoor = -1
24+
repeat {
25+
openDoor = random(numberOfDoors)
26+
} while openDoor == prizeDoor || openDoor == chooseDoor
27+
28+
// What happens when the player changes his mind and picks the other door.
29+
var changeMind = -1
30+
repeat {
31+
changeMind = random(numberOfDoors)
32+
} while changeMind == openDoor || changeMind == chooseDoor
33+
34+
// Figure out which choice was the winner.
35+
if chooseDoor == prizeDoor {
36+
winOriginalChoice += 1
37+
}
38+
if changeMind == prizeDoor {
39+
winChangedMind += 1
40+
}
41+
42+
rounds += 1
43+
}
44+
45+
// Run the simulation a large number of times.
46+
for i in 1...5000 {
47+
playRound()
48+
}
49+
50+
let stubbornPct = Double(winOriginalChoice)/Double(rounds)
51+
let changedMindPct = Double(winChangedMind)/Double(rounds)
52+
53+
print(String(format: "Played %d rounds, stubborn: %g%% vs changed mind: %g%%", rounds, stubbornPct, changedMindPct))
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2+
<playground version='5.0' target-platform='osx'>
3+
<timeline fileName='timeline.xctimeline'/>
4+
</playground>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<Timeline
3+
version = "3.0">
4+
<TimelineItems>
5+
</TimelineItems>
6+
</Timeline>

Monty Hall Problem/README.markdown

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# The Monty Hall Problem
2+
3+
Congrats! You've reached the final round of the popular [Monty Hall game show](https://en.wikipedia.org/wiki/Let%27s_Make_a_Deal). Monty, the show host, gives you the choice between 3 doors. Behind one of the doors is a prize (a new car? a trip to Hawaii? a microwave oven?), the other two are empty.
4+
5+
After you make your choice, Monty decides to make things a bit more interesting and opens one of the two doors that you didn't pick. Of course, the one he opens is empty. There are now two doors left, behind one of which is the coveted prize.
6+
7+
Now Monty gives you the opportunity to change your mind. Should you stick with your original choice, should you pick the other door, or doesn't it matter?
8+
9+
You'd think that changing your answer wouldn't improve your chances... but it does!
10+
11+
This is a very nonintuitive result. Maybe you have trouble believing this is true. Don't worry, when this problem was first proposed many mathematicians didn't believe it either, so you're in good company.
12+
13+
There's a simple way to verify this claim: we can write a program to test it out! We should be able to show who wins more often by playing the game a large number of times.
14+
15+
Here's the code (see the [playground](MontyHall.playground/Contents.swift) for the full thing). First, we randomly choose the door that has the prize:
16+
17+
```swift
18+
let prizeDoor = random(3)
19+
```
20+
21+
We also randomly pick the choice of the player:
22+
23+
```swift
24+
let chooseDoor = random(3)
25+
```
26+
27+
Next, Monty opens one of the empty doors. Obviously, he won't choose the door that the player chose or the one with the prize.
28+
29+
```swift
30+
var openDoor = -1
31+
repeat {
32+
openDoor = random(numberOfDoors)
33+
} while openDoor == prizeDoor || openDoor == chooseDoor
34+
```
35+
36+
There are only two closed doors left, one of which has the prize. What happens when the player changes his mind and picks the other door?
37+
38+
```swift
39+
var changeMind = -1
40+
repeat {
41+
changeMind = random(3)
42+
} while changeMind == openDoor || changeMind == chooseDoor
43+
```
44+
45+
Now we see which choice was the right one:
46+
47+
```swift
48+
if chooseDoor == prizeDoor {
49+
winOriginalChoice += 1
50+
}
51+
if changeMind == prizeDoor {
52+
winChangedMind += 1
53+
}
54+
```
55+
56+
If the prize is behind the player's original door choice, we increment `winOriginalChoice`. If the prize is behind the other door, then the player would have won if he changed his mind, and so we increment `winChangedMind`.
57+
58+
And that's all there is to it.
59+
60+
If you run the above code 1000 times or so, you'll find that the probability of choosing the prize without changing your mind is about 33%. But if you *do* change your mind, the probability of winning is 67% -- that is twice as large!
61+
62+
Try it out in the playground if you still don't believe it. ;-)
63+
64+
Here's why: When you first make a choice, your chances of picking the prize are 1 out of 3, or 33%
65+
66+
After Monty opens one of the doors, this gives you new information. However, it doesn't change the probability of your original choice being the winner. That chance remains 33% because you made that choice when you didn't know yet what was behind this open door.
67+
68+
Since probabilities always need to add up to 100%, the chance that the prize is behind the other door is now 100 - 33 = 67%. So, as strange as it may sound, you're better of switching doors!
69+
70+
This is hard to wrap your head around, but easily shown using a simulation that runs a significant number of times. Probability is weird.
71+
72+
[Monty Hall Problem on Wikipedia](https://en.wikipedia.org/wiki/Monty_Hall_problem)
73+
74+
*Written for Swift Algorithm Club by Matthijs Hollemans*

README.markdown

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ A lot of software developer interview questions consist of algorithmic puzzles.
169169

170170
- [Two-Sum Problem](Two-Sum Problem/)
171171
- [Fizz Buzz](Fizz Buzz/)
172+
- [Monty Hall Problem](Monty Hall Problem/)
172173

173174
## Learn more!
174175

0 commit comments

Comments
 (0)