なんだこれは

はてなダイアリーから移転しました。

モンティパイソン問題を普通にCでやってみた

モンティパイソン問題を説明しても、よくわかんねって言われるので、
ソースコードをもって回答とさせていただきます。
gccなどで、コンパイルして実行してみてください。

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

/* モンティパイソン問題を実際にやってみた。 */

#define REAL_DOOR_NUM (3.0)
#define DOOR_NUM (3)
#define WIN (1)
#define LOSE (0)
#define NUMBER_OF_TIME ((MAX_INTGER_TYPE) (ULLONG_MAX-1))

typedef unsigned long long int MAX_INTGER_TYPE;

/* ランダムなドア番号 (0)から(DOOR_NUM-1) を返す */
int get_random_door (void) 
{
  int door = (int) (rand() * ( REAL_DOOR_NUM / (1.0 +RAND_MAX)));
  return(door);
}

/* 2引数のドア番号と一致しないドア番号 (0)から(DOOR_NUM-1) を返す */
int another_door( int door_1st, int door_2nd)
{
  int door;         /* カウンタ */
  int another;      /* 一致しないドア番号 */

  for( door = 0; door < DOOR_NUM ; door++)
  {
    if( (door != door_1st) & (door != door_2nd ) )
    {
      another = door;
    }
  }
  
  return(another);
}

/* 一回のゲームを実行し、未変更、変更の結果 (WIN) または (LOSE) を返す */
void play(int * unchange_result, int * change_result)
{
  int win_door;              /* 当たりドア番号 */
  int select_door;           /* 最初に選ぶドア番号 */
  int open_door;             /* 出題者が見せるはずれのドア番号*/
  int unchange_last_door;    /* ファイナルアンサー(変えない場合)*/
  int change_last_door;      /* ファイナルアンサー(変える場合) */

  /*出題者が当たりを選びました。*/
  win_door = get_random_door();

  /*プレイヤーが選びました。*/
  select_door = get_random_door();   
  
  /*はずれを見せる*/
  open_door = another_door( select_door, win_door);
  
  /* 選択を変える */
  unchange_last_door = select_door;
  change_last_door   = another_door( select_door, open_door);
  
  /* 当たり判定 */
  *unchange_result = ( unchange_last_door == win_door ) ? WIN : LOSE ;
  *change_result   = ( change_last_door   == win_door ) ? WIN : LOSE ;

#ifdef SKIP_PRINT
  /* 結果の表示 */
  printf("win:%d sel:%d ope:%d unchange:%d change:%d res:%d:%d \n", 
	 win_door, select_door, open_door, 
	 unchange_last_door, change_last_door, 
	 *unchange_result, *change_result); 
#endif  
  return;
}

int main(void)
{
  MAX_INTGER_TYPE i;                   /* カウンタ */
  MAX_INTGER_TYPE unchange_record = 0; /* 変更しない場合の全成績 */
  MAX_INTGER_TYPE change_record = 0;   /* 変更する場合の全成績 */
  int unchange;                        /* 変更しない場合の成績(WIN)/(LOSE) */
  int change;                          /* 変更する場合の成績(WIN)/(LOSE)   */
  
  /* 乱数の初期化 */
  srand(time(NULL));         

  /* NUMBER_OF_TIME回 playして記録をとる */
  for( i = 0; i < NUMBER_OF_TIME; i++)
  {
    /* playして結果を返す */
    play(&unchange, &change);
    
    /* 結果を記録 */
    unchange_record += unchange;
    change_record += change;
  }
  
  /* 最終結果を表示 */
  printf(" unchanged play record is %llu / %llu, rate: %f\n", 
	 unchange_record, NUMBER_OF_TIME, 
	 ((double) unchange_record)/ NUMBER_OF_TIME);
  printf("   changed play record is %llu / %llu, rate: %f\n", 
	 change_record, NUMBER_OF_TIME, 
	 ((double) change_record)/ NUMBER_OF_TIME);

  /* おしまい */
  return(0);
} 

ULLONG_MAX回実行するけどな!*1