The Monty Hall Problem: A Programmer’s approach

This article is about Actionscript and was originally posted on my personal blog 6 years ago.

I’ve always enjoyed mind games, but there was always one riddle that I just couldn’t wrap my head around. You may or may not have heard about 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 sportscar; behind the others, goats. You pick a door, say No. 1, 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?

The answers is: Yes. switching to another door will double your chances of winning the sportscar (from 33% to 66%). Now this may strike you as very peculiar, because after all, if there are only 2 options left (in this case door No.1 & door No. 2), then the chances to win the car are 50% right ?
If you are already outraged by now, it might bring a little solace to know that you are not alone. Nobel prize winners and Professors around the world alike have made the same mistake. I concluded there was only one way to find out who was right, and using my weapon of choice (AS3), I recreated the setting of the gameshow and simulated 1.000.000 games.

The results were pretty convincing: Staying with your original door yielded a favorable result 33% of the time, whilst switching doors won you the car 66% of the time. And it was only when I was coding this little simulation, that I understood how exactly this is possible. Let’s have a look at some the code involved.

private function startLongGame(doSwitch:Boolean):Boolean
{
doors = [0, 1, 2];
var winningDoor = randomRange(0, 2);
var doorChosen:int = randomRange(0, 2);
if(doorChosen == winningDoor && doSwitch) return false;
	var doorGiven:int = giveDoor(doorChosen, winningDoor);
	if (doSwitch) {
doors.splice(doors.indexOf(doorChosen), 1);
doors.splice(doors.indexOf(doorGiven), 1);
doorChosen = doors[0];
}
	if (winningDoor == doorChosen) return true;
return false;
}
private function giveDoor(chosen:int,winner:int):int
{
var tempDoors:Array = [0, 1, 2];
tempDoors.splice(tempDoors.indexOf(chosen), 1);
tempDoors.splice(tempDoors.indexOf(winner), 1);
return tempDoors[randomRange(0,tempDoors.length-1)]; // if there are two doors left, choose one random door.
}

This is a very long but readable way of simulating the problem. There is a random ‘winningDoor’, I choose a random door ‘doorChosen’ , and according to these variables, the method ‘giveDoor’ returns a door that the host will open. Depending on my boolean ‘doSwitch’, I change my mind or stay with my original choice. Pretty straightforward, and the results are correct: switching wins the car 66% of the time, not switching only 33%.

But when you think about this a little more, you’ll see that there is a much shorter way of coding all this. You can skip the whole giveDoor part, because the matter of fact is, it doesn’t matter which door the host gives you, because it will always be a goat. If you chose a winning door, and you switch, you always lose. if you chose a goat, and you switch, you always win. Since you choose a goat 66% of the time, switching gives you a car 66% of the time ;-)

private function startShortGame(doSwitch:Boolean):Boolean
{
var doYouGetACar:Boolean;
var winningDoor = randomRange(0, 2);
var doorChosen:int = randomRange(0, 2);

if(winningDoor != doorChosen){ // this happens 66% of the time
doYouGetACar = (doSwitch)? true:false;
}
	if(winningDoor == doorChosen){ // this happens 33% of the time
doYouGetACar = (doSwitch)? true:false;
}
	return doYouGetACar;
}

If you don’t take my word for it, take a look at the simulation below, or download the AS Class and check it out!

Like this post ? Follow me on Twitter !