Skip to content

Instantly share code, notes, and snippets.

@robwierzbowski
Last active October 23, 2017 23:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save robwierzbowski/ed4749d05c075520e607670bc83d8cf9 to your computer and use it in GitHub Desktop.
Save robwierzbowski/ed4749d05c075520e607670bc83d8cf9 to your computer and use it in GitHub Desktop.
Quick Monty Hall example in JS
// Not the most expressive code, but it does the trick.
// Run with swap = true to test swapping doors.
const montyBurns = function (swap = false) {
let wins = 0;
for (let i = 0; i < 10000; i++) {
const doors = {
1: false,
2: false,
3: false,
};
const ball = Math.ceil(Math.random() * 3);
const choice = Math.ceil(Math.random() * 3);
doors[ball] = true;
// Find a door that isn't choice and isn't ball. Always chooses the first
// door if there are two empty non-choice doors (i.e., if the choice is
// correct). Note: This code is poo :P
const noBall = Object.keys(doors).filter((key) => {
const keyInt = parseInt(key, 10);
return keyInt !== ball && keyInt !== choice;
})[0];
// Remove one door
delete doors[noBall];
if (swap) {
// Throw away your choice and see what's left
delete doors[choice];
if (Object.values(doors)[0] === true) {
wins++;
}
}
else if (ball === choice) {
wins++;
}
}
return wins;
};
@robwierzbowski
Copy link
Author

robwierzbowski commented Oct 23, 2017

Revised to use arrays and string values (just for fun). Code is a bit shorter, less method calls, less mutation. Not sure how much more understandable it is.

See this revision for object version.

@robwierzbowski
Copy link
Author

robwierzbowski commented Oct 23, 2017

This array implementation helped me understand the problem, especially why the switch gives us 2 in 3 odds instead of 1 in 2.

Choosing a door without switching gives us 1 in 3 odds. When we run the script without switching we get about 1/3 wins.

When switching, we remove an empty door. But in the code the array value for the door is never really removed. This helped me imagine that we are still choosing out of 3, but the problem becomes "pick any two doors out of three, see if you get the ball". We actively pick one, the host in the Monty Hall example (or the JavaScript code here) picks the other one. The one that's chosen for us is guaranteed empty, so if the ball is behind one of our two doors it's guaranteed to be behind our choice.

When we run the script and switch, we get about 2/3 wins.

I haven't read too deeply into the problem, so this could be technically wrong :P. Comments welcome.

@laboon
Copy link

laboon commented Oct 23, 2017

The best way I have found is thinking it is the following:

Imagine there are a million doors. You pick one, Monty Hall opens up one of the non-picked doors to show a goat. You now have the choice to stay or switch to the set of all remaining doors (so - 1 picked; 1 open with a goat; 999,998 unopened/unpicked). Of course here it makes sense to switch.

Or you can exhaustively go through the possibilities. Assume you pick Door A, there are three scenarios (calling a door "A" is arbitrary, it just indicates whatever door you picked)

Possibilities:
Car behind Door A - Monty picks either B or C to open. Stay: Win, Switch: Lose
Car behind Door B - Monty opens Door C to show you a goat. Stay: Lose, Switch: Win
Car behind Door C - Monty opens Door B to show you a goat. Stay: Lose, Switch: Win

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment