Start New Discussion within our Software Development Community

Hello everyone,

I stumbled upon a video about the monty hall problem, which I found very well explained, and a lot of comments below the video that were against the conclusion that it is better to switch. To clarify, I wrote this small program that simulates the game and allows everyone to test it for themselves.

I got the following results:

+ Calculation Preferences +

Enter the amount of repetitions:        3000
Do you want to switch choice? [Y/N]     y

+ Calculation Results +

Amount of repetitions:  3000
Correct choices:        2008
Wrong choices:          992
Winpercentage:          66.933333

and:

+ Calculation Preferences +

Enter the amount of repetitions:        3000
Do you want to switch choice? [Y/N]     n

+ Calculation Results +

Amount of repetitions:  3000
Correct choices:        1013
Wrong choices:          1987
Winpercentage:          33.766667

So the conclusion is really self-explanatory :)

~G

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

int mt_rand(int, int);

int main()
{

    // Character used for clearing buffer:
    int   ch;

    // Amount of repetitions:
    int repetitions = 0;

    // Whether or not to switch choice:
    int switch_choice = 0;

    // Text input to switch choice:
    char txt_sw_ch = 'Y';

    // Asking user for repetitions input:
    printf("+ Calculation Preferences +\n\nEnter the amount of repetitions:\t");
    scanf("%d", &repetitions);

    // Clear buffer:
    while ((ch = getchar()) != '\n' && ch != EOF);

    // Asking user for switch choice input:
    printf("Do you want to switch choice? [Y/N]\t");
    scanf("%c", &txt_sw_ch);

    // Clear buffer:
    while ((ch = getchar()) != '\n' && ch != EOF);

    // Translating the character into a choice:
    if (txt_sw_ch == 'Y' || txt_sw_ch == 'y') {
        switch_choice = 1;
    } else {
        switch_choice = 0;
    }

    // Initializing random number generator:
    srand((unsigned)time(0));

    // Keeps track of amount of wins:
    int wins = 0;

    // Repetitions
    int i = 0;
    for (i = 0; i < repetitions; i++) {

        // The correct number:
        int correct = mt_rand(0, 2);

        // The choice made:
        int choice = mt_rand(0, 2);

        // The number that will be removed:
        int removement;

        if (choice == correct) {

            // If the choice is correct:
            if (choice == 0) {
                if (mt_rand(0, 1) == 0) {
                    removement = 1;
                } else {
                    removement = 2;
                }
            } else if (choice == 1) {
                if (mt_rand(0, 1) == 0) {
                    removement = 0;
                } else {
                    removement = 2;
                }
            } else {
                if (mt_rand(0, 1) == 0) {
                    removement = 0;
                } else {
                    removement = 1;
                }
            }
        } else {

            // If the choice is incorrect:
            if (choice == 0 && correct == 1) {
                removement = 2;
            } else if (choice == 0 && correct == 2) {
                removement = 1;
            } else if (choice == 1 && correct == 0) {
                removement = 2;
            } else if (choice == 1 && correct == 2) {
                removement = 0;
            } else if (choice == 2 && correct == 0) {
                removement = 1;
            } else if (choice == 2 && correct == 1) {
                removement = 0;
            }
        }

        // Switch the choice if that is wanted:
        if (switch_choice) {
            if (choice == 0 && removement == 1) {
                choice = 2;
            } else if (choice == 0 && removement == 2) {
                choice = 1;
            } else if (choice == 1 && removement == 0) {
                choice = 2;
            } else if (choice == 1 && removement == 2) {
                choice = 0;
            } else if (choice == 2 && removement == 0) {
                choice = 1;
            } else if (choice == 2 && removement == 1) {
                choice = 0;
            }
        }

        if (choice == correct) {
            wins++;
        }

    }

    // Showing end result:
    printf("\n+ Calculation Results +\n\nAmount of repetitions:\t%d\nCorrect choices:\t%d\nWrong choices:\t\t%d\nWinpercentage:\t\t%f\%\n\nPress any key to end program...", repetitions, wins, repetitions - wins, (((float) wins / (float) repetitions) * (float) 100) );

    // Program end pause:
    scanf("%c", &ch);

    return 0;

}

/*
 * This function returns a random number between and including the lowest and highest parameter.
 *
 * @param int: Lowest  - The lowest bound
 * @param int: Highest - The highest bound
*/
int mt_rand( int lowest, int highest ) {

    // The actual range:
    int range = (highest-lowest) + 1;

    // The random integer:
    return (lowest + (int) ( range * rand() / (RAND_MAX + 1.0) ));

}

In addition, if all you want to do is test if switching is better, all you really need is:

Loop:
    get random number 0-2          ; 1 of possible 3 'doors' chosen
    if number = 0                  ; 0 is defined as the good door
        switchNo = switchNo + 1    ; count no switch condition
      else
        switchYes = switchYes + 1  ; count switch condition
    End Loop 

    Print switchNo switchYes

This assumes door 0 is always the correct door, and one door is randomly chosen.
In the Monty Hall Problem, the moment a door is chosen, the swich condition is immediately known. Showing an unchosen poor choice has no bearing on this switch condition -- it's a red herring to 'confuse' the (L)user.

The article starter has earned a lot of community kudos, and such articles offer a bounty for quality replies.