モンティ・ホール問題

モンティ・ホール問題についてくわしくは Wikipedia を読んでもらうとして、モンティがあけなかった扉を選んだ時に、もとの扉のままの二倍の勝率になる、ということをモンテカルロ法によって確認できないかとざっとコードを書いてみた。
自分が選んだ最初の扉の選択を変えなかった時の勝ち回数を i_win に、そうでなくてモンティが開かなかった残りの扉にヤギがいた場合の回数を m_win に入れた。
最初は、自分が選んだ扉にヤギがいて、モンティが残りを開く場合は半々の確率でヤギのいないふたつの扉のどちらかを開き、自分の選んだ扉にヤギがいなかった場合、残りのふたつの扉のうちモンティが開く扉は決まっていて…などという場合分けを書いていたんだけど、あれこれ考えているうちにそんな難しく書かなくてもいいんじゃないかな?という結果が次のコード。ていうかこのロジックがほんとうに正しかったら勝率は 1:2 になって扉を変えた方がいいことになる。
なにしろモンティはヤギのいない扉を開く、という知識でもって確率を変動させてくれるのだから。

#include <fcntl.h>
#include <unistd.h>
#include <iostream>

int main()
{
  int fd = open("/dev/urandom", O_RDONLY);
  if(-1 == fd) return -1;

  static const size_t NR_TRY = 1000000;
  size_t i_win = 0; // nr of i won prize
  size_t m_win = 0; // nr of monti's side door is hide the goat
  for (size_t i = 0; i < NR_TRY; ++i)
  {
    bool ds[3] = { false, false, false };
    char rs[2];
    read(fd, rs, 2); // get random value from /dev/urandom

    ds[rs[0] % 3] = true; // set goat door

    size_t my_choose = rs[1] % 3; // my door number

    /* if the door i selected hide the goat,
       i won the prize and monti loose.
       or the other doors hide the goat,
       my first choice is never won the prize
       and the door monti not opened is hide
       the goat. */
    ds[my_choose] ? ++i_win : ++m_win;
  }
  close(fd);

  std::cout << "the ratio of not change the door v.s. change the door is "
            << i_win << ":" << m_win << std::endl;
  return 0;
}

で、結果:

the ratio of not change the door v.s. change the door is 444778:555222

二倍にはなっていなくて44:56くらいの比率でうっすらと扉を変えた方が勝率があがる結果となった。
なんかもういろいろツッコミ歓迎。