Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

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

More than 5 years have passed since last update.

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

アメリカの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倍になります。

BYODKM
TypeScriptばかり書いています / インターネッツ合同会社・代表 / 共著書に『HTML5読本』
https://github.com/BYODKM
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away