How to resolve the algorithm Monty Hall problem step by step in the Haskell programming language

Published on 7 June 2024 03:52 AM

How to resolve the algorithm Monty Hall problem step by step in the Haskell programming language

Table of Contents

Problem Statement

Suppose you're on a game show and you're given the choice of three doors. Behind one door is a car; behind the others, goats. The car and the goats were placed randomly behind the doors before the show.

After you have chosen a door, the door remains closed for the time being. The game show host, Monty Hall, who knows what is behind the doors, now has to open one of the two remaining doors, and the door he opens must have a goat behind it. If both remaining doors have goats behind them, he chooses one randomly. After Monty Hall opens a door with a goat, he will ask you to decide whether you want to stay with your first choice or to switch to the last remaining door. Imagine that you chose Door 1 and the host opens Door 3, which has a goat. He then asks you "Do you want to switch to Door Number 2?"

Is it to your advantage to change your choice?

The player may initially choose any of the three doors (not just Door 1), that the host opens a different door revealing a goat (not necessarily Door 3), and that he gives the player a second choice between the two remaining unopened doors.

Run random simulations of the Monty Hall game. Show the effects of a strategy of the contestant always keeping his first guess so it can be contrasted with the strategy of the contestant always switching his guess. Simulate at least a thousand games using three doors for each strategy and show the results in such a way as to make it easy to compare the effects of each strategy.

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Monty Hall problem step by step in the Haskell programming language

The provided Haskell program simulates the Monty Hall problem, which is a famous puzzle in probability theory. In this problem, a contestant is presented with three doors, one of which hides a car (the prize) and the other two hide goats. The contestant initially chooses a door, and the host, who knows what's behind each door, opens one of the other two doors to reveal a goat. The contestant is then given the option to switch to the other unopened door or stay with their original choice. The question is whether it is more advantageous to switch or stay.

The program simulates the game multiple times (specified by the trials constant) and tracks the number of times the contestant wins the car using two different strategies: switching and staying.

Here's a breakdown of the code:

  1. Data Type (Door):

    • data Door = Car | Goat deriving Eq: This defines a data type called Door that represents the two possible outcomes behind the doors: Car or Goat. They can be compared for equality (deriving Eq).
  2. play Function (State Monad):

    • This function simulates a single game of the Monty Hall problem using the state monad.
    • It takes a Bool parameter switch to indicate whether the contestant chooses to switch or stay and a StdGen (a type representing a random number generator) as input.
    • It generates a random number i to choose one of the three doors.
    • Based on the switch flag, it determines whether to return the initially chosen door (d1) or the other unopened door (the prize).
  3. cars Function:

    • This function runs multiple simulations of the game, keeping track of the number of times the contestant wins the car.
    • It takes the number of trials (n), the switch flag, and a StdGen as input.
    • It uses the f helper function to perform the simulations recursively.
    • Each simulation involves playing the game once, determining the prize, and incrementing a counter if the contestant wins.
  4. main Function:

    • This function is the entry point of the program.
    • It generates a random number generator g using getStdGen.
    • It runs cars with the switch and stay strategies multiple times to count the number of wins for each strategy.
    • Finally, it prints out the percentage of wins for each strategy using the msg function.
  5. rand Function (State Monad):

    • This function generates a random number using the state monad.
    • It gets the current StdGen from the state, generates a random number using randomR, and updates the state with the new StdGen.
  6. Additional Functions:

    • msg: formats a message with strategy and win percentage.
    • percent: calculates the win percentage as a string.

The program simulates the Monty Hall problem multiple times and demonstrates that switching doors leads to a higher win percentage compared to staying with the original choice.

Source code in the haskell programming language

import System.Random (StdGen, getStdGen, randomR)

trials :: Int
trials = 10000

data Door = Car | Goat deriving Eq

play :: Bool -> StdGen -> (Door, StdGen)
play switch g = (prize, new_g)
  where (n, new_g) = randomR (0, 2) g
        d1 = [Car, Goat, Goat] !! n
        prize = case switch of
            False -> d1
            True  -> case d1 of
                Car  -> Goat
                Goat -> Car

cars :: Int -> Bool -> StdGen -> (Int, StdGen)
cars n switch g = f n (0, g)
  where f 0 (cs, g) = (cs, g)
        f n (cs, g) = f (n - 1) (cs + result, new_g)
          where result = case prize of Car -> 1; Goat -> 0
                (prize, new_g) = play switch g

main = do
    g <- getStdGen
    let (switch, g2) = cars trials True g
        (stay, _) = cars trials False g2
    putStrLn $ msg "switch" switch
    putStrLn $ msg "stay" stay
  where msg strat n = "The " ++ strat ++ " strategy succeeds " ++
            percent n ++ "% of the time."
        percent n = show $ round $
            100 * (fromIntegral n) / (fromIntegral trials)


import Control.Monad.State

play :: Bool -> State StdGen Door
play switch = do
    i <- rand
    let d1 = [Car, Goat, Goat] !! i
    return $ case switch of
        False -> d1
        True  -> case d1 of
            Car  -> Goat
            Goat -> Car
  where rand = do
            g <- get
            let (v, new_g) = randomR (0, 2) g
            put new_g
            return v

cars :: Int -> Bool -> StdGen -> (Int, StdGen)
cars n switch g = (numcars, new_g)
  where numcars = length $ filter (== Car) prize_list
        (prize_list, new_g) = runState (replicateM n (play switch)) g


The switch strategy succeeds 67% of the time.
The stay strategy succeeds 34% of the time.


  

You may also check:How to resolve the algorithm First-class functions step by step in the Tcl programming language
You may also check:How to resolve the algorithm URL decoding step by step in the VBScript programming language
You may also check:How to resolve the algorithm Gapful numbers step by step in the RPL programming language
You may also check:How to resolve the algorithm Case-sensitivity of identifiers step by step in the Sidef programming language
You may also check:How to resolve the algorithm Last letter-first letter step by step in the Clojure programming language