Hey guys. In my Data Structures Class today somehow we ended up talking about the Monty Hall Problem for a little while. Anyways I got bored and wrote code to statistically check if it is correct (even thought I know it is).

For those of you who don't know what the problem is it goes something like this:

You are on a game show and have to pick one of three doors. Behind one door is a brand new car and the other two have nothing behind them. You make your selection. After you make your selection the game show host opens one of the doors that you did not select and reveals that there is nothing behind it. Now the host gives you the option to switch your answer to the other remaining door or keep the door you selected in the first place. Should you switch is does it not matter? Check the code to see the answer for yourself! (hint... ten million trials usually gets the exact percentages although it takes a few seconds to run)

Here is the code... please check to make sure I did it correctly. Also I know it may not be the most efficient way to write the code but I was in a rush and that's the best way I could think to write it at the time.

import java.util.*;

public class MontyHall 
{
	public static void main(String[] args)
	{
		Scanner key = new Scanner(System.in);
		Random gen = new Random();

		System.out.print("Enter number of trials to run: ");
		int NUMOFTRIALS = key.nextInt();
		System.out.print("Stay Always (1) or Switch Always (2): ");
		int choice = key.nextInt();
		int numCorrect = 0;
		int pick,ans,show;
		ArrayList<Integer> doors = new ArrayList<Integer>();

		if(choice == 1) // always stay
		{
			for(int i = 0; i < NUMOFTRIALS; i++)
			{
				doors.clear();
				doors.add(1);
				doors.add(2);
				doors.add(3);

				pick = gen.nextInt(3);
				ans = gen.nextInt(3);

				doors.remove(ans);

				if(!doors.contains(pick)) show = doors.get(0);
				else
				{
					if(doors.get(0) == pick) show = doors.get(1);
					else show = doors.get(0);
				}

				if(show == pick) System.out.println("Something is wrong!!!");
				if(pick == ans) numCorrect++;
			}
		}
		else if(choice == 2) // always switch
		{
			int other = 22;
			for(int i = 0; i < NUMOFTRIALS; i++)
			{
				doors.clear();
				doors.add(0);
				doors.add(1);
				doors.add(2);

				pick = gen.nextInt(3);
				ans = gen.nextInt(3);

				doors.remove(ans);

				if(!doors.contains(pick)) 
				{
					int ran = gen.nextInt(2);
					show = doors.get(ran);
					
					if(ran == 1)
						other = doors.get(0);
					if(ran == 0)
						other = doors.get(1);
				}
				else
				{
					if(doors.get(0) == pick) 
					{
						show = doors.get(1);
						other = ans;
						
					}
					else
					{
						show = doors.get(0);
						other = ans;
						
					}

				}

				if(show == pick || other == 22) System.out.println("Something is wrong!!!");

				pick = other;

				if(pick == ans)numCorrect++;
			}
		}
		double percCorr = (double)numCorrect/(double)NUMOFTRIALS;
		System.out.printf("\n%.2f%s correct answers.", percCorr*100, "%");
	}
}

Recommended Answers

All 6 Replies

You're getting the right answers and the logic seems OK. If you're looking for a critique of the code, I'd use more descriptive variable names and add comments so people can follow the logic more easily. In particular, you have a variable that you call other and initialize to 22, which is a value that will be illegal. I'd have it be -999999 or something that stands out more and stick some comment in explaining what -999999 stands for. I was puzzling over what a value of 22 might represent for a while before I realized it was a bogus flag value, set intentionally to be a bogus flag value. -999999 stands out right away as a flag value.

Like Vernon says, but also you can make a "bogus" value totally clear at zero overhead by declaring it as static final:
public static final int BOGUS = -999999;
then:
var = BOGUS;
if (var == BOGUS) { ...
etc

Von Savant problem? I might have spelled her name wrong. I don't remember the reasoning and this problem is actually tricky, but I think I remember the answer: yes you should switch. My guess at the reasoning would be that after the host showing the one door, you now have a 50% chance of choosing the right one, which is up from your previous 33% chance. [update: this is wrong, if you read the wiki on the subject the picture clearly depicts why] Either way, this problem caused quite an uproar in the mathematical community with mathematicians who said she was wrong, and then it turned out that they were wrong.

Von Savant problem? I might have spelled her name wrong. I don't remember the reasoning and this problem is actually tricky, but I think I remember the answer: yes you should switch. My guess at the reasoning would be that after the host showing the one door, you now have a 50% chance of choosing the right one, which is up from your previous 33% chance. [update: this is wrong, if you read the wiki on the subject the picture clearly depicts why] Either way, this problem caused quite an uproar in the mathematical community with mathematicians who said she was wrong, and then it turned out that they were wrong.

The mathematicians weren't wrong, in my view. The way the original problem is phrased leaves out a key assumption (that the host MUST show a bad door and allow the contestant to switch). If that's the RULE, then yes, she's right. Here's the original question:

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 #1, and the host, who knows what's behind the doors, opens another door, say #3, which has a goat. He says to you, "Do you want to pick door #2?" Is it to your advantage to switch your choice of doors?

Craig F. Whitaker
Columbia, Maryland

Nothing in the original question states that the host is REQUIRED to show you a losing door and allow you to switch. She's reading into it that the host IS required to, but that was never stated.


Here is Marilyn's later explanation.

Good heavens! With so much learned opposition, I'll bet this one is going to keep math classes all over the country busy on Monday.

My original answer is correct. But first, let me explain why your answer is wrong. The winning odds of 1/3 on the first choice can't go up to 1/2 just because the host opens a losing door. To illustrate this, let's say we play a shell game. You look away, and I put a pea under one of three shells. Then I ask you to put your finger on a shell. The odds that your choice contains a pea are 1/3, agreed? Then I simply lift up an empty shell from the remaining other two. As I can (and will) do this regardless of what you've chosen, we've learned nothing to allow us to revise the odds on the shell under your finger.

The red part is the invalid assumption. If the host is trying to make you lose, he/she might only offer you the option of switching if you pick the right door the first time. Nothing in the original game rules stipulate that the host always has to let you switch, so her analysis is invalid. If the host DOES have to show you a losing door and let you switch, then she would be right.

So in my view, the mathematicians were right, she was wrong.

http://www.marilynvossavant.com/articles/gameshow.html

My take on the problem was that the host MUST show you an empty door after you make your first choice EVERY time reguardless of if you picked correctly the first time. This assumes that the host is not trying to make you lose.

If you have these assumptions then you can difinitivly answer saying that you should switch everytime because:

- the first time you select a door you have a 1/3 chance of being correct.
- this means there is a 1/3 chance of the other two doors being empty.
- and by contrast a 2/3 chance of ONE of the other doors containing the car.
- therefore if the host shows you one of the empty doors there is a 2/3 chance that the other door has the car behind it.

My program demonstrates this with about 66% winning percentage when selecting "Switch Always" and about a 33% winning percentage when selecting "Stay always"

I saw this problem in a movie (I think its name was 21) and I never thought about it. After I saw it here this morning I started to think about it. I had worked on it for 12 hours and I finally figured it out half an hour ago in the shower. thank you for posting it here. I think I will try to write the program myself. If I write it I'll post the link here. (man figuring that out made me really happy :) )

commented: Kudos for spending 12 hours on a problem just for learning's sake. +16
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.