Testo:
Il paradosso di Monty Hall è un sorprendente quesito di teoria della
probabilità. Si tratta di un paradosso perch´e la sua soluzione è inequivocabile, ma l’intuizione quasi sempre porta a risultati completamente sbagliati. Il problema si può formulare nei termini seguenti.
Supponete di dover scegliere una di tre carte coperte. Le tre carte sono un Asso, un
Cavallo e un Re. Se pescate un Asso vincete un premio, altrimenti dovete pagare voi.
Una volta fatta la scelta e prima di scoprire la carta, il mazziere, che può vedere le
carte, scopre una delle due rimaste facendo attenzione a lasciare coperto, qualora non
sia la carta che avete scelto voi, l’asso. A questo punto avete la possibilità di scegliere se
cambiare carta o di tenere quella che avete scelto inizialmente. Cosa conviene fare?
La maggior parte delle persone pensa che cambiare carta non sia n´e conveniente n´e
sconveniente, poichè ritiene che, a questo punto, ci sia il 50 % di probabilità di aver fatto
la scelta giusta. In realtà conviene cambiare carta, perchè la probabilità di aver scelto la
carta giusta `e solo del 33 % circa (1/3), mentre cambiare carta implica una probabilità
di vincita pari a 2/3.
In questo programma simuliamo il gioco e verifichiamo sperimentalmente quanto sopra.
1. Il programma chiede all’utente quante volte vuole simulare la giocata. Il numero N di
giocate pu`o essere al massimo 10 000.
2. Qualora l’utente immetta un numero non ammesso, il programma deve reiterare la richiesta fino a quando l’utente non rispetta le prescrizioni.
3. Il programma chiede all’utente se deve simulare un giocatore furbo o meno.
4. Attraverso una funzione assign() che riceve in ingresso un array di tre componenti, il
programma distribuisce le carte in modo casuale. Ogni componente dell’array, con indice
0,1,2, rappresenta una carta coperta. Il contenuto dell’array rappresenta il tipo di carta
(Asso, Cavallo, oppure Re). Per esempio, le carte con indice 0, 1 e 2, possono essere un
Asso, un Cavallo e un Re oppure un Re, un Asso e un Cavallo, etc..
5. Il programma, quindi, sceglie casualmente una delle tre carte.
6. Il ruolo del mazziere `e simulato da una funzione change(), che riceve in ingresso la sequenza delle carte e la carta scelta casualmente al punto 4., e suggerisce una carta da
scegliere in alternativa. In sostanza, change() “scopre” una delle due carte ancora coperte, rimuovendola dal gioco, accertandosi che la carta vincente (l’asso) resti tra le alternative. La funzione suggerisce quindi di cambiare la carta scelta originariamente con
quella rimasta.
7. A questo punto, se il giocatore `e furbo si scopre la carta scelta come suggerito da change(),
altrimenti si scopre quella scelta inizialmente. Se la carta `e un asso, il giocatore guadagna
un euro, altrimenti ne perde uno.
8. I punti da 4 a 7 si ripetono fino a quando il numero di giocate raggiunge il numero N scelto
dall’utente oppure se il giocatore ha perso tutto il suo budget. Inizialmente il giocatore
possiede un budget di 100 euro-
Mia esecuzione :
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
void assign(int v[]);
int change(int v[], int ch);
int main() {
int N;
srand(time(NULL));
do {
printf("Quante volte si vuole simulare la giocata? ");
scanf("%d",&N);
if (N <= 0 || N > 10000)
printf("ERRORE: il numero di giocate deve appartenere all'intervallo (0,10000]\n");
} while (N <= 0 || N > 10000);
int giocatore;
do {
printf("Il programma deve simulare un giocatore 'furbo' o meno?\n");
printf("Se si vuole simulare un giocatore 'furbo' digitare 1\n");
printf("Se si vuole simulare un giocatore poco 'furbo' digitare 2\n");
scanf("%d", &giocatore);
if (giocatore != 1 && giocatore != 2)
printf("ERRORE: il numero da inserire e' 1 oppure 2\n");
} while (giocatore != 1 && giocatore != 2);
int card[3], choice, rc, j, euro = 100, i;
for (i = 0; i < N; i++) {
assign(card);
choice = rand()/((double)RAND_MAX)*2;
printf("Hai scelto la carta %d\n", choice+1);
j = change(card,choice);
if (giocatore == 1) {
rc = j;
printf("\nEffettuo il cambiamento\n");
}
else {
rc = choice;
printf("\nNon effettuo il cambiamento\n");
}
if (card[rc] == 1) {
printf("Hai vinto e' un asso!\n");
euro += 1;
}
else {
euro -= 1;
}
printf("Ti rimangono %d euro\n\n", euro);
if (euro <= 0) {
printf("Hai perso tutti i soldi\n");
exit(0);
}
}
}
void assign(int v[]) {
int a, b, c;
a = rand()/((double)RAND_MAX)*2;
do {
c = rand()/((double)RAND_MAX)*2;
b = rand()/((double)RAND_MAX)*2;
} while (c == a || c == b || b == a);
v[0] = a;
v[1] = b;
v[2] = c;
}
int change(int v[], int ch) {
int i, j;
do {
i = rand()/((double)RAND_MAX)*2;
} while (i == ch || v[i] == 1);
printf("Scarto la carta n.%d\n", i+1);
do {
j = rand()/((double)RAND_MAX)*2;
} while(j == ch || j == i);
printf("Perche' non cambi la carta n. %d, con la carta n. %d?", ch+1, j+1);
return j;
}
Il programma sembra non funzionare correttamente, innanzitutto non esce la carta numero 3, sebbene rand() sembra impostato correttamente, e poi la funzione change non cambia correttamente le carte, qualcuno sa dirmi perchè?