R
robspyke
Dear All,
I am learning c at the moment - for recreational purposes really more
than anything else - and I was just wondering if I could pick your
collective wisdom on how best to code a problem.
Basically I am certain some of you have heard of the monty hall
probablity puzzle. To recap:
1. Game show. 3 doors, Car behind door. 1 x donkey each behind others.
2. Contestant has to pick the winning door (the one with the car!)
3. Contestant picks one door (say door A)
4. Host (who knows what's behind all doors) will then open one of the
remaining unchosen doors, say door B, which he knows has a donkey
behind.
5. Remaining closed doors, door A which contestant picked, and door C.
6. Host then asks contestant if he wants to make a switch for door C.
Probabilistically it makes most sense to switch in the long run, but I
found this concept difficult to grasp initially and so have others. To
prove it (besides algebraically) I wrote the program below to run a
simulation of an arbitrary no. of iterations. It should (hopefully) be
clear to most of you what the code does.
I am trying to learn is how to code C efficiently and correctly and
optimally etc. So if you can improve on the code please do chip in.
Oh, just in case some of you are wondering... this is NOT
homework/coursework etc - purely recreational. I fortunately do not
depend on this to earn a living either I'm just demented enough to
be wanting to learn C.
I've paid most attention to the algorithm, so if the rest of the
supporting bits are crap... well that's entirely my fault
Code starts below:
--- montyhall.c ---
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
// macro to return a random no from 1 - n
#define random(n) (1 + rand()%n)
// constant declarations used to reference the 4 int array
// containing the frequencies of the outcome of the simulation
#define switchdoor_correct 0
#define switchdoor_wrong 1
#define no_switchdoor_correct 2
#define no_switchdoor_wrong 3
// function prototypes
int * monty_create ();
void monty_calc (int *freq, int interations);
void monty_display (int *freq);
void setup ();
int main (int argc, char *argv[])
{
int * results;
setup();
if (argc !=2)
{
printf("Usage: Monty x\n\nWhere x = no of iteratons.\n");
exit(1);
}
results = monty_create();
monty_calc(results,atoi(argv[1]));
monty_display(results);
free (results);
}
int *monty_create()
{
int *array;
array = (int *) malloc (sizeof(int)*4);
return array;
}
void monty_calc (int *freq, int counter)
{
int x, actual, guess, switchdoor, index;
// zero out array passed to function
for (x=0; x<4;*(freq+x)=0, x++)
;
// do stated no. of iterations in counter
for (x=0;x < counter; x++)
{
actual = random (3); // prize is behind this door
guess = random (3); // contestant's guess
// contestant's decision to switch or not 50:50
switchdoor = rand() %2 ; //true = switch
//the logic is here - calcs contestant guesing
index = (actual == guess) ?
( (switchdoor) ? (switchdoor_wrong):
(no_switchdoor_correct)
)
:
( (switchdoor) ? (switchdoor_correct):
(no_switchdoor_wrong)
);
++*(freq+index);
}
} // all events recorded in frequency array returned by
reference.
void monty_display( int * freq)
{
printf("Switching the door: Correct=%d, Wrong=%d\n",
freq[switchdoor_correct], freq[switchdoor_wrong]);
printf("Not switching... : Correct=%d, Wrong=%d\n",
freq[no_switchdoor_correct], freq[no_switchdoor_wrong]);
printf("\nTotal no of iterations: %d\n",
freq[0]+freq[1]+freq[2]+ freq[3]);
printf("Probability of prize (switching) : %f\n",
freq[switchdoor_correct]/(float)(freq[switchdoor_wrong]+freq[switchdoor_correct]));
printf("Probability of prize (no switch) : %f\n",
freq[no_switchdoor_correct]/(float)
(freq[no_switchdoor_correct]+freq[no_switchdoor_wrong]));
}
void setup()
{
printf ("Monty Hall Simulator \n\n");
srand( (unsigned int) time(NULL)/ 2 );
}
I am learning c at the moment - for recreational purposes really more
than anything else - and I was just wondering if I could pick your
collective wisdom on how best to code a problem.
Basically I am certain some of you have heard of the monty hall
probablity puzzle. To recap:
1. Game show. 3 doors, Car behind door. 1 x donkey each behind others.
2. Contestant has to pick the winning door (the one with the car!)
3. Contestant picks one door (say door A)
4. Host (who knows what's behind all doors) will then open one of the
remaining unchosen doors, say door B, which he knows has a donkey
behind.
5. Remaining closed doors, door A which contestant picked, and door C.
6. Host then asks contestant if he wants to make a switch for door C.
Probabilistically it makes most sense to switch in the long run, but I
found this concept difficult to grasp initially and so have others. To
prove it (besides algebraically) I wrote the program below to run a
simulation of an arbitrary no. of iterations. It should (hopefully) be
clear to most of you what the code does.
I am trying to learn is how to code C efficiently and correctly and
optimally etc. So if you can improve on the code please do chip in.
Oh, just in case some of you are wondering... this is NOT
homework/coursework etc - purely recreational. I fortunately do not
depend on this to earn a living either I'm just demented enough to
be wanting to learn C.
I've paid most attention to the algorithm, so if the rest of the
supporting bits are crap... well that's entirely my fault
Code starts below:
--- montyhall.c ---
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
// macro to return a random no from 1 - n
#define random(n) (1 + rand()%n)
// constant declarations used to reference the 4 int array
// containing the frequencies of the outcome of the simulation
#define switchdoor_correct 0
#define switchdoor_wrong 1
#define no_switchdoor_correct 2
#define no_switchdoor_wrong 3
// function prototypes
int * monty_create ();
void monty_calc (int *freq, int interations);
void monty_display (int *freq);
void setup ();
int main (int argc, char *argv[])
{
int * results;
setup();
if (argc !=2)
{
printf("Usage: Monty x\n\nWhere x = no of iteratons.\n");
exit(1);
}
results = monty_create();
monty_calc(results,atoi(argv[1]));
monty_display(results);
free (results);
}
int *monty_create()
{
int *array;
array = (int *) malloc (sizeof(int)*4);
return array;
}
void monty_calc (int *freq, int counter)
{
int x, actual, guess, switchdoor, index;
// zero out array passed to function
for (x=0; x<4;*(freq+x)=0, x++)
;
// do stated no. of iterations in counter
for (x=0;x < counter; x++)
{
actual = random (3); // prize is behind this door
guess = random (3); // contestant's guess
// contestant's decision to switch or not 50:50
switchdoor = rand() %2 ; //true = switch
//the logic is here - calcs contestant guesing
index = (actual == guess) ?
( (switchdoor) ? (switchdoor_wrong):
(no_switchdoor_correct)
)
:
( (switchdoor) ? (switchdoor_correct):
(no_switchdoor_wrong)
);
++*(freq+index);
}
} // all events recorded in frequency array returned by
reference.
void monty_display( int * freq)
{
printf("Switching the door: Correct=%d, Wrong=%d\n",
freq[switchdoor_correct], freq[switchdoor_wrong]);
printf("Not switching... : Correct=%d, Wrong=%d\n",
freq[no_switchdoor_correct], freq[no_switchdoor_wrong]);
printf("\nTotal no of iterations: %d\n",
freq[0]+freq[1]+freq[2]+ freq[3]);
printf("Probability of prize (switching) : %f\n",
freq[switchdoor_correct]/(float)(freq[switchdoor_wrong]+freq[switchdoor_correct]));
printf("Probability of prize (no switch) : %f\n",
freq[no_switchdoor_correct]/(float)
(freq[no_switchdoor_correct]+freq[no_switchdoor_wrong]));
}
void setup()
{
printf ("Monty Hall Simulator \n\n");
srand( (unsigned int) time(NULL)/ 2 );
}