Monty Hall Problem - solved with an Arduino

Following on from this thread I thought, "enough with making LEDs blink, time for some probability!".

Taking the Monty Hall Problem from: http://marilynvossavant.com/game-show-problem/

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?

Putting aside the mathematical treatment, let's try some code:

/*

Monty-Hall problem.

Author: Nick Gammon
Date:   25 August 2013

See: http://en.wikipedia.org/wiki/Monty_hall_problem
and: http://marilynvossavant.com/game-show-problem/

*/

const bool change = false;  // whether or not to switch doors
const int seed = 1234;
const unsigned long rounds = 2000;

unsigned long wins;

void  doOneRound ()
  {
  bool car [3];
  for (byte i = 0; i < 3; i++)
    car [i] = false;  
  
  // choose which door has the car
  car [random (0, 3)] = true;
  
  // contestant makes a random choice
  byte choice = random (0, 3);
  
  // host chooses another door
  byte hosts_choice;
 
  // don't choose contestant's door
  // also don't reveal the car
  do 
    {
    hosts_choice = random (0, 3);
    } while (hosts_choice == choice || car [hosts_choice]);

  // change choice if desired
  
  if (change)
    {
    if (choice != 0 && hosts_choice != 0)
      choice = 0;
    else if (choice != 1 && hosts_choice != 1)
      choice = 1;
    else 
      choice = 2;
    }  // end if

  // did we win the car?
  if (car [choice])
    wins++;
  
  }  // end of doOneRound
  
void setup ()
  {
  Serial.begin (115200);
  Serial.println ();    
  randomSeed (seed);
  
  // do as many rounds as desired
  for (unsigned long round = 0; round < rounds; round++)
    doOneRound ();
    
  Serial.print ("You won ");
  Serial.print (100UL * wins / rounds);
  Serial.println ("% of the time");    
    
  }  // end of setup

void loop () { }

Before running it, do you predict:

You won 33% of the time
You won 50% of the time
You won 66% of the time
<something else>

(Or thereabouts, depending on the exact numbers from the random number generator).

You can change the line:

const bool change = false;  // whether or not to switch doors

Make it "true" to change your decision about whether to switch doors, and see if it makes a difference.

Also see: Monty Hall problem - Wikipedia

Good idea. You seed the random number generator with a constant, would it not be better to use something that changes e.g. base it on time?

enough with making LEDs blink, time for some probability!

With three buttons and three RGB LEDs you could play the game for real.

... would it not be better to use something that changes e.g. base it on time?

Without a clock? How?

In any case, I suggest that the results will be (nearly) the same, regardless of the seed.

This must be the most obscure use of an arduino I have seen yet, to determine if I win a car or a goat. XD

Riva:
This must be the most obscure use of an arduino I have seen yet, to determine if I win a car or a goat. XD

Quite important as that helps you to decide what your next Arduino project will be, a remote garage door opener, or a goat milk temperature monitor :wink:

Without a clock? How?

You could just ask the user to type in the time.
The results will always come out roughly the same regardless of the seed but if you use the same seed you will always be playing with the same sequence of numbers.

Good idea, Nick! I'm a big fan of the brute force method myself! :smiley:

radman:
You seed the random number generator with a constant, would it not be better to use something that changes e.g. base it on time?

No. Using a good quality generator and running the simulation long enough eliminate any need to randomize the initial value. Using a constant makes it possible to determine if the code or the generator is to blame if something goes wrong.

Much more fun with beer -

James May's Man Lab did a Russian Roulette version of this with beer cans called, wait for it, "The Beer Hunter." The rules were simple: there would be three cans, two of which were shaken up. James would pick one can, but always change his mind after Tom took away a "dangerous" can, and Simmy would be left with the one that James originally picked. They would then hold the cans next to their face and open the cans together. They did this for one hundred rounds; along with getting hypothermia and minor carbon dioxide poisoning, James also proved this version true by winning 40:60.