O jogador escolhe uma das portas, após a escolha o apresentador abre uma das duas outras portas e mostra uma cabra (eliminando uma má resposta). A pergunta do problema de Monty-Hall consiste em saber se o jogador tem algum interesse em mudar de escolha após a eliminação da má resposta.
O programa seguinte supõe que o jogador muda sempre de opinião e conta o número de vezes que este ganha. Para mostrar que a boa estratégia consiste em mudar de opinião um pequeno cálculo elementar mostra que nesse caso se ganha com probabilidade 2/3. O programa ilustra experimentalmente este resultado e serve de bom exemplo para o chamado Método de Monte-Carlo que consiste em simular a realidade mediante a utilização de um gerador de números aleatórios.
Neste caso concreto o programa usa a função uniform01 que tira á sorte un número entre 0 e 1 segundo a lei de distribuição uniforme. Depois distribui o carro e as cabras usando um vector de dimensão 3, se o número for < 1/3 a cabra estará na primeira porta, se estiver entre 1/3 e 2/3 estará na segunda porta e se for > 2/3 estará na última porta. Supomos que o jogador escolhe sempre a primeira porta depois eliminamos uma cabra (escolhida também á sorte) e devolvemos o conteúdo da porta que não foi eliminada.
Finalmente a função main lê o número de experiências a realizar e conta o número de carros.
Este programa compila em qualquer bom compilador de linguagem C, em gcc a linha de comando é:
gcc -o monty_hall monty_hall.c
e para executar 100 000 simulações:
./monty_hall 100000
O código seguinte deve ser copiado para um ficheiro chamado monty_hall.c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef unsigned char boolean;
#define FERRARI 1
#define CABRA 0
double uniform01()
{
return ( (double)rand() / ((double)(RAND_MAX)+1.) );
}
boolean simulacao(double rnd1, double rnd2)
{
/* Supomos que se escolhe sempre a primeira porta */
boolean portas[3];
int i;
if ( 3.*rnd1 < 1. )
{
portas[0]=FERRARI;
portas[1]=CABRA;
portas[2]=CABRA;
}
else if ( 3.*rnd1 < 2. )
{
portas[0]=CABRA;
portas[1]=FERRARI;
portas[2]=CABRA;
}
else
{
portas[0]=CABRA;
portas[1]=CABRA;
portas[2]=FERRARI;
}
/* Se ha duas cabras eliminar uma delas */
if (portas[1] == portas[2])
{
/*
Escolher a porta a eliminar aleatoriamente e devolver o
valor da outra.
*/
i=1;
if ( rnd2 < 0.5 )
{
i=2;
}
}
/* Eliminar a porta com a cabra */
else if ( portas[1] == CABRA )
{
i=2;
}
/* Eliminar a porta com a cabra */
else
{
i=1;
}
return portas[i];
}
int main(int argc, char *argv[])
{
int num_simul=1000;
int num_ferrari=0;
int i=0;
srand((unsigned int)time(NULL));
if ( argc > 1 )
{
num_simul=atoi(argv[1]);
}
for ( i=0; i<num_simul; i++)
{
num_ferrari += simulacao(uniform01(),uniform01());
}
printf("Numero de simulacoes: %15d\n", num_simul);
printf("Numero de Ferraris: %15d\n", num_ferrari);
printf("Fraccao de Ferraris: %15.13lf\n",
(double)num_ferrari/(double)num_simul);
return 0;
}