On 01/15/2012 02:42 PM, Willem wrote:
> James Kuyper wrote:
> ) Your simulation is needlessly complicated:
> <snip>
> ) int car = choose3();
> ) int guess = choose3();
> ) if(guess == car)// Host chooses one of the other doors.
> ) keep++; // Sticking with your original choice wins.
> ) else // Host chooses the other door with the goat.
> ) change++; // Switching to the remaining door wins.
>
> Your solution does not replicate the actual circumstances, I.E. it uses
> some of the logic steps that are used to prove the 1/3 result, to simplify
> the code. People who do not believe the proof will likely also not believe
> results from your program.
If you could identify those logic steps, I could complicate the code to
demonstrate their validity. The best-known statement of the problem is
the one from Marilyn vos Savant's "Ask Marilyn" column on page 16 of the
1990-09-09 Parade magazine, and her answer was based on many unstated
assumptions, that strike me as quite reasonable - but a fair fraction of
those who disagreed with her made different assumptions. The problem was
originally posed in a letter by Steve Selvin to the American
Statistician in 1975, but I haven't seen a copy of that letter, so I'm
not sure if it contained the same assumptions.
My program was meant to simulate the standard version of the problem,
with all such assumptions stated explicitly, as specified in
http://www.usd.edu/~xtwang/Papers/MontyHallPaper.pdf. Anyone who objects
to my program because they made different assumptions is, of course,
correct: the original problem was under-specified.
I'm not sure how I should modify the program to make it's validity as a
simulation of the fully-specified problem more obvious. Here's an
attempt. I relies upon a user-defined function:
extern int host_choose_goad(int car, int guess);
This function's two arguments are supposed to each have values of 0, 1,
2; it's behavior if that is not the case is irrelevant. It must not
contain any feature which renders the behavior of the program as a whole
undefined, if passed valid arguments. It must return. It's return value
must be either 0, 1, or 2, and must not be equal to either of its two
arguments. Therefore, if the two arguments are not equal, there is only
one unique return value permitted. Otherwise it must choose between
exactly two possibilities; how it makes that choice is completely
irrelevant. It must do nothing to interfere with the randomness of the
numbers returned by choose3() below, for instance by calling srand().
Here's the rest of the main program:
#include <assert.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
static int choose3(void)
{
int r;
// max is the largest multiple of 3 that is less than or equal to
// RAND_MAX+1
static const int max = 3*((RAND_MAX + 1UL)/3);
// This removes the bias that would otherwise exist due if
// max != RAND_MAX+1
while((r=rand())>= max);
return r/(max/3);
}
#define TRIAL_RUNS ULONG_MAX
int main(void)
{
srand(12345);
unsigned long keep = 0;
unsigned long change = 0;
for(unsigned long i=TRIAL_RUNS; i; i--)
{
int car = choose3();
int guess = choose3();
int goat = host_chooses_goat(car, guess);
assert(0 <= goat < 3);
assert(goat != car && goat != guess);
// If those assertions succeed, this expression gives the
// number of the only remaining unchosen door
int changed_guess = 3-(guess+goat);
if(guess == car)
keep++; // Keeping your original guess wins.
else if(changed_guess == car)
change++; // Changing your guess wins.
}
printf("%lu runs. Keeping wins %lu=%g%%; switching wins %lu=%g%%\n",
TRIAL_RUNS, keep, (double)keep/TRIAL_RUNS,
change, (double)change/TRIAL_RUNS);
return 0;
}
The key logic issue is that, if host_chooses_goat() satisfies the
requirements placed upon it, and if the second condition gets evaluated,
that condition is guaranteed to evaluate to 1. As as result, the second
condition can be optimized away,, rendering host_chooses_goat()
irrelevant, which is how I generated my original version of the code.
> Of course, you can optimize a simulation. But the point is that any
> optimizing step is essentially one of the steps from the mathematical
> proof (that shows that you should switch), so it cannot be used to
> convince anybody that doesn't follow the proof.
Is this version sufficient?
--
James Kuyper