hpastetwo

Programming Praxis: Let's Make A Deal

author
Andy Gimblett
age
371 days
language
haskell
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
module LetsMakeADeal where

{- Fairly naive attack on
   http://programmingpraxis.com/2009/07/24/lets-make-a-deal/

> ghci LetsMakeADeal.hs
*LetsMakeADeal> rounds 100000
0.66252

-}

import Control.Monad
import Data.List
import System.Random

-- Pick a random element from a list.  Maybe there's a nicer way?
chooseFrom :: [a] -> IO a
chooseFrom xs = do which <- getStdRandom $ randomR (0, length xs-1)
                   return $ xs !! which

-- Play one round of the game.  Returns True if player should switch.
play :: IO Bool
play = do car <- chooseFrom doors -- Place the car.
          guess <- chooseFrom doors -- Player makes a first guess.
          -- Show them a goat.  It can't be behind the door hiding the
          -- car, and it can't be the door they picked.
          shown <- chooseFrom $ delete guess $ delete car doors
          -- Player should switch if the other (non-guessed,
          -- non-shown) door is the right one.
          return $ car == head (delete guess $ delete shown doors)
    where doors = [0,1,2]

-- Play n rounds of the game and work out how many times switching was
-- the right thing to do.
rounds :: Int -> IO Double
rounds n = do outcomes <- replicateM n play
              let shouldHave = filter id outcomes
              return (fromIntegral (length shouldHave) / fromIntegral n)

.

author
.
age
370 days
language
haskell
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
module LetsMakeADeal where

{- Fairly naive attack on
   http://programmingpraxis.com/2009/07/24/lets-make-a-deal/

> ghci LetsMakeADeal.hs
*LetsMakeADeal> rounds 100000
0.66252

By Andy Gimblett
http://gimbo.org.uk/blog/2009/07/25/a-monte-hall-problem-solved-in-haskell/

-}

import Control.Monad
import Data.List
import System.Random

-- Pick a random element from a list.  Maybe there's a nicer way?
chooseFrom :: [a] -> IO a
chooseFrom xs = do which <- getStdRandom $ randomR (0, length xs-1)
                   return $ xs !! which

-- Play one round of the game.  Returns True if player should switch.
play :: IO Bool
play = do car <- chooseFrom doors -- Place the car.
          guess <- chooseFrom doors -- Player makes a first guess.
          -- Show them a goat.  It can't be behind the door hiding the
          -- car, and it can't be the door they picked.
          shown <- chooseFrom $ delete guess $ delete car doors
          -- Player should switch if the other (non-guessed,
          -- non-shown) door is the right one.
          return $ car == head (delete guess $ delete shown doors)
    where doors = [0,1,2]

-- Play n rounds of the game and work out how many times switching was
-- the right thing to do.
rounds :: Int -> IO Double
rounds n = do outcomes <- replicateM n play
              let shouldHave = filter id outcomes
              return (fromIntegral (length shouldHave) / fromIntegral n)

Programming Praxis: Let's Make A Deal

author
Andy Gimblett
age
370 days
language
haskell
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
module LetsMakeADeal where

{- Fairly naive attack on
   http://programmingpraxis.com/2009/07/24/lets-make-a-deal/

> ghci LetsMakeADeal.hs
*LetsMakeADeal> rounds 100000
0.66252

By Andy Gimblett
http://gimbo.org.uk/blog/2009/07/25/a-monte-hall-problem-solved-in-haskell/

-}

import Control.Monad
import Data.List
import System.Random

-- Pick a random element from a list.  Maybe there's a nicer way?
chooseFrom :: [a] -> IO a
chooseFrom xs = do which <- getStdRandom $ randomR (0, length xs-1)
                   return $ xs !! which

-- Play one round of the game.  Returns True if player should switch.
play :: IO Bool
play = do car <- chooseFrom doors -- Place the car.
          guess <- chooseFrom doors -- Player makes a first guess.
          -- Show them a goat.  It can't be behind the door hiding the
          -- car, and it can't be the door they picked.
          shown <- chooseFrom $ delete guess $ delete car doors
          -- Player should switch if the other (non-guessed,
          -- non-shown) door is the right one.
          return $ car == head (delete guess $ delete shown doors)
    where doors = [0,1,2]

-- Play n rounds of the game and work out how many times switching was
-- the right thing to do.
rounds :: Int -> IO Double
rounds n = do outcomes <- replicateM n play
              let shouldHave = filter id outcomes
              return (fromIntegral (length shouldHave) / fromIntegral n)