/* This program simulates the Monty Hall, three-door, three-card puzzle:

	The dealer shuffles three cards, one red and two black, and
	deals them out face down.

	The player choose one of the three cards.

	From the two unchosen cards, the dealer reveals a black one.

	The player is permitted to switch their choice to the
	remaining unrevealed card.

   The number of wins and the number of trials are reported.  The
   number of wins is about two-thirds of the number of trials.

   Copyright 1998 by Eric Postpischil (http://edp.org).  Permission
   is granted to reproduce without alteration for non-profit use.
*/

#include	<stdio.h>
#include	<stdlib.h>
#include	<time.h>


/* This expression is 0, 1, or 2 with nearly equal frequency and
   is effectively random for our purposes.  (It has technical deficiences
   which make it poor for more sophisticated and demanding uses.)
*/
#define	random_card	((int) (3. / (1.+RAND_MAX) * rand()))


int	main(void)
{
	int	first_choice, red, revealed, second_choice, trials, wins;

	srand(time(NULL));	/* Seed the pseudo-random number generator. */

	wins = 0;
	for (trials = 0; trials < 3000; trials++)
	{
		/* Randomly deal a red card to one of the three positions.
		   The other two positions will be black.
		*/
		red = random_card;

		/* The player picks a card. */
		first_choice = random_card;

		/* The dealer reveals a black card.  To be brief and clear,
		   but not efficient, we randomly pick a card until we get one
		   that is neither the red card nor the player's first choice.
		*/
		do
			revealed = random_card;
		while (revealed == red || revealed == first_choice);

		/* Now the player switches from their first choice to the
		   only other unrevealed card.  It's easy to calculate
		   the third card by adding together the numbers of each
		   of the cards and then subtracting the numbers of the
		   first choice and the revealed card, leaving only the
		   number of the third card.
		*/
		second_choice = 0 + 1 + 2 - first_choice - revealed;

		/* If the second choice is red, count a win. */
		if (second_choice == red)
			wins++;
	}

	printf("Switching resulted in %d wins out of %d trials.\n",
		wins, trials);

	return 0;
}

