Skip to content

Commit bf1ba83

Browse files
committed
doc: Monty Hall simulation for std::rand
A larger example for std::rand
1 parent d114dda commit bf1ba83

File tree

1 file changed

+103
-0
lines changed

1 file changed

+103
-0
lines changed

src/libstd/rand/mod.rs

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,109 @@ use std::rand;
7171
let tuple = rand::random::<(f64, char)>();
7272
println!("{}", tuple)
7373
```
74+
75+
This is a simulation of the [Monty Hall Problem][]:
76+
77+
> Suppose you're on a game show, and you're given the choice of three doors:
78+
> Behind one door is a car; behind the others, goats. You pick a door, say No. 1,
79+
> and the host, who knows what's behind the doors, opens another door, say No. 3,
80+
> which has a goat. He then says to you, "Do you want to pick door No. 2?"
81+
> Is it to your advantage to switch your choice?
82+
83+
The rather unintuitive answer is that you will have a 2/3 chance of winning if
84+
you switch and a 1/3 chance of winning of you don't, so it's better to switch.
85+
86+
This program will simulate the game show and with large enough simulation steps
87+
it will indeed confirm that it is better to switch.
88+
89+
[Monty Hall Problem]: http://en.wikipedia.org/wiki/Monty_Hall_problem
90+
91+
```
92+
use std::rand;
93+
use std::rand::Rng;
94+
use std::rand::distributions::{IndependentSample, Range};
95+
96+
struct SimulationResult {
97+
win: bool,
98+
switch: bool
99+
}
100+
101+
// Run a single simulation of the Monty Hall problem.
102+
fn simulate<R: Rng>(rng: &mut R) -> SimulationResult {
103+
let random_door = Range::new(0u, 3);
104+
let car = random_door.ind_sample(rng);
105+
106+
// This is our initial choice
107+
let mut choice = random_door.ind_sample(rng);
108+
109+
// The game host opens a door
110+
let open = game_host_open(car, choice, rng);
111+
112+
// Shall we switch?
113+
let switch = rng.gen();
114+
if switch {
115+
choice = switch_door(choice, open);
116+
}
117+
118+
SimulationResult { win: choice == car, switch: switch }
119+
}
120+
121+
// Returns the door the game host opens given our choice and knowledge of
122+
// where the car is. The game host will never open the door with the car.
123+
fn game_host_open<R: Rng>(car: uint, choice: uint, rng: &mut R) -> uint {
124+
let choices = free_doors(vec![car, choice]);
125+
rand::sample(rng, choices.move_iter(), 1)[0]
126+
}
127+
128+
// Returns the door we switch to, given our current choice and
129+
// the open door. There will only be one valid door.
130+
fn switch_door(choice: uint, open: uint) -> uint {
131+
free_doors(vec![choice, open])[0]
132+
}
133+
134+
fn free_doors(blocked: Vec<uint>) -> Vec<uint> {
135+
range(0u, 3).filter(|x| !blocked.contains(x)).collect()
136+
}
137+
138+
fn main() {
139+
// The estimation will be more accuraty with more simulations
140+
let num_simulations = 10000u;
141+
142+
let mut rng = rand::task_rng();
143+
144+
let (mut switch_wins, mut switch_losses) = (0u, 0u);
145+
let (mut keep_wins, mut keep_losses) = (0u, 0u);
146+
147+
println!("Running {} simulations...", num_simulations);
148+
for _ in range(0, num_simulations) {
149+
let result = simulate(&mut rng);
150+
151+
match (result.win, result.switch) {
152+
(true, true) => switch_wins += 1,
153+
(true, false) => keep_wins += 1,
154+
(false, true) => switch_losses += 1,
155+
(false, false) => keep_losses += 1,
156+
}
157+
}
158+
159+
let total_switches = switch_wins + switch_losses;
160+
let total_keeps = keep_wins + keep_losses;
161+
162+
println!("Switched door {} times with {} wins and {} losses",
163+
total_switches, switch_wins, switch_losses);
164+
165+
println!("Kept our choice {} times with {} wins and {} losses",
166+
total_keeps, keep_wins, keep_losses);
167+
168+
// With a large number of simulations, the values should converge to
169+
// 0.667 and 0.333 respectively.
170+
println!("Estimated chance to win if we switch: {}",
171+
switch_wins as f32 / total_switches as f32);
172+
println!("Estimated chance to win if we don't: {}",
173+
keep_wins as f32 / total_keeps as f32);
174+
}
175+
```
176+
74177
*/
75178

76179
#![experimental]

0 commit comments

Comments
 (0)