LoginSignup
10
10

More than 5 years have passed since last update.

モンティ・ホール問題をCoffeeScriptで検証

Last updated at Posted at 2015-10-25

モンティ・ホール問題とは

アメリカのTV番組で行われたあるゲームについての論争のこと。

  1. 司会者側がドアを三枚用意し、その内ふたつにはヤギを、残りの一枚には新車を隠す。
  2. 回答者はドアを一枚選ぶ。
  3. 司会者は回答者の選んでいないドアから一枚を開けて、ヤギを見せる。
  4. 司会者は回答者にドアを選び直したいか質問する。
  5. この時、回答者はドアを選び直した方が確率的には新車を得やすくなる(その差は2倍)。

確率が直感に反するため、議論になったそうです。
モンティ・ホール問題 - Wikipedia

検証

CoffeeScript
class MontyHall

  setDoor = (int)->
    arr = []
    while int
      arr.push('empty')
      int--
    return arr

  putCar = (doors)->
    int = parseInt(Math.random() * doors.length)
    arr = []
    for door, index in doors
      if index is int then arr.push('car') else arr.push('goat')
    return arr

  openDoor = (doors, firstChoice)->
    opened = false
    arr = []
    for door, index in doors
      if door is 'car' or index is firstChoice
        arr.push(door)
      else if !opened
        arr.push('opened')
        opened = true
      else
        arr.push('goat')
    return arr

  changeMind = (doors, firstChoice)->
    int = 0
    for door, index in doors
      unless index is firstChoice or door is 'opened'
        int = index
        break
    return int

  constructor: (@obj)->

  log: ()->
    conf =
      doors: if @obj and @obj.doors and typeof @obj.doors is 'number' then parseInt(@obj.doors) else 3
      tests: if @obj and @obj.tests and typeof @obj.tests is 'number' then parseInt(@obj.tests) else 2000
    tests = TESTS = conf.tests
    doors = setDoor(conf.doors)
    firstChoiceIsCorrect = secondChoiceIsCorrect = 0
    while tests
      doors = putCar(doors)
      firstChoice = parseInt(Math.random() * doors.length)
      doors = openDoor(doors, firstChoice)
      if doors[firstChoice] is 'car' then firstChoiceIsCorrect++
      secondChoice = changeMind(doors, firstChoice)
      if doors[secondChoice] is 'car' then secondChoiceIsCorrect++
      tests--
    console.log('firstChoiceIsCorrect', parseInt(firstChoiceIsCorrect / TESTS * 1000) / 10 + '%')
    console.log('secondChoiceIsCorrect', parseInt(secondChoiceIsCorrect / TESTS * 1000) / 10 + '%')
    return

new MontyHall
  doors: 3
  tests: 2000
.log()

結果

ドア3枚で、2000回のテスト結果です。

firstChoiceIsCorrect – "33.2%"
secondChoiceIsCorrect – "66.7%"

確率が2倍になりました。
ちなみに「ドアを4つに増やして、ヒントをひとつ与える」場合でも同様に、確率が2倍になります。

解説

3つドアがある場合、新車を当てる確率は1/3。ハズす確率は2/3。
ドアを選び直すことによって損をするのは、1/3の確率。
ドアを選び直すことによって得をするのは、その逆なので2/3の確率。
ということで、66%ほどの割合で新車をゲット。元の確率の2倍になります。

10
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
10