[Swift] 몬티홀의 딜레마 알고리즘으로 증명해보기

2022. 2. 4. 00:00iOS

 

일명 몬티홀 게임은 누구나 한번쯤 들어본 유명한 게임이다.

 

게임의 규칙은 간단한데, 참가자에게 3개의 문이 주어진다. 이 세개의 문 중 하나에 고액의 자동차가 랜덤으로 들어있고 나머지 두개의 문들의 뒤에는 염소가 서있다. 참가자가 하나의 문을 고르면 아직 고르지 않은 두개의 문중 하나를 사회자가 열어준다. 사회자가 열어준 문에는 (당연히) 염소가 서있는데, 이때 사회자는 참가자에게 문을 바꿀 기회를 제공한다.

 

이때 참가자가 문 바꾸기를 받아들인다면 자동차를 얻을 수 있는 확률은 올라갈까?

 

수학적으로는 무조건 문을 바꾸면 무조건 확률이 상승한다고 한다.

 

하지만 직관적으로는 잘 이해가 가지 않는다. 그냥 내가 선택한 문 뒤에 자동차가 들어있을 수도 있지않나?

 

그래서 알고리즘을 한번 짜보기로 했다. 과연 어떤 선택이 옳을까?

 

enum WillIChange: String {
    case YES = "Y"
    case NO = "N"
}

class MontiHallProblem {
    let loop: Double = 100000
    var percentage: Double = 0.0
    var correctCount = 0
    var doors: [Bool] = Array(repeating: false, count: 3)
    var goldDoor: Int = Int.random(in: Range(0...2))
    let willIChange: WillIChange = .YES
    
    init() {
        startGame()
    }
    
    func startGame() {
        for _ in 0..<Int(loop) {
            goldDoor = Int.random(in: Range(0...2))
            doors[goldDoor] = true
            choosePhase(Int.random(in: Range(0...2)))
        }
        resultPhase()
    }
    
    func choosePhase(_ choose: Int) {
        let leftDoors: [Int] = doors.enumerated().map { $0.offset }.filter { $0 != choose }
        let failureDoor: Int = doors.enumerated().map { $0.offset }.filter { $0 != choose && $0 != goldDoor }.first!
        let computerSuggest = leftDoors.filter{ $0 != failureDoor }.randomElement()
        let choose = choose
        matchPhase(choose: choose, computerSuggest: computerSuggest!, whatIChoose: willIChange.rawValue)
    }
    
    func matchPhase(choose: Int, computerSuggest: Int, whatIChoose: String) {
        if whatIChoose == "Y" {
            if computerSuggest == goldDoor {
                correctCount += 1
            }
        } else if whatIChoose == "N" {
            if choose == goldDoor {
                correctCount += 1
            }
        }
    }
    
    func resultPhase() {
        self.percentage = Double((Double(correctCount)/loop)*100)
        print("맞출 확률 \(percentage)%")
        correctCount = 0
    }
}

let monti = MontiHallProblem()

 

놀랍게도 바꾸기를 선택하면 대략 65~67% 확률로 자동차를 가지게 되고,

바꾸지 않기를 선택하면 32~34% 확률로 염소를 가지게 된다.

 

 

평소에 궁금했던것들을 직접 알고리즘화해서 풀어보니 재밌었다