Monty Hall問題 #1
問題に沿って素直に書いてみる。
#include <stdio.h> #include <stdlib.h> int main(void) { int i, iter, n_car[2], n_goat[2]; for (i = 0; i < 2; i++) n_car[i] = n_goat[i] = 0; srand48(20111222L); for (iter = 0; iter < 1000000; iter++) { int car = (int)(drand48() * 3); int select = (int)(drand48() * 3); int open, switches, choice; if (select == car) { open = ((int)(drand48() * 2) + select + 1) % 3; } else { open = ((select + 1) % 3 == car ? select + 2 : select + 1) % 3; } switches = (int)(drand48() * 2); if (switches) { choice = ((select + 1) % 3 == open ? select + 2 : select + 1) % 3; } else { choice = select; } if (choice == car) { n_car[switches]++; } else { n_goat[switches]++; } } for (i = 0; i < 2; i++) printf("%d %d %d\n", n_car[i], n_goat[i], n_car[i] + n_goat[i]); printf("%d %d %d\n", n_car[0] + n_car[1], n_goat[0] + n_goat[1], n_car[0] + n_goat[0] + n_car[1] + n_goat[1]); return 0; }
ドアに0, 1, 2の番号を振る。
carは当たりのドア番号、selectは最初に解答者が選んだドア番号、
carとselectから決定されるopenは出題者が開いた外れのドア番号、
switchesは0か1を取り、最初の選択を変える(1)か変えない(0)かの解答者による選択、
choiceは最終的に解答者が選んだドア番号、を表している。
とりあえず100万回ほどこれを繰り返したときに、
n_car[0]とn_goat[0]が解答者が最初の選択を変えなかった時の当たりと外れの回数、
n_car[1]とn_goat[1]が解答者が最初の選択を変えた時の当たりと外れの回数、これらをカウントする。
乱数の種も適当に。
結果は、
166817 332732 499549 333403 167048 500451 500220 499780 1000000
最初の選択を変えなかった場合に当たった割合は0.334、変えた場合に当たった割合は0.666になる。