Advertisement
Guest User

Prisoners.hs

a guest
Mar 14th, 2014
177
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.80 KB | None | 0 0
  1. import Data.List.Extras.Argmax
  2.  
  3. data Choice = PickRed | PickGreen | Abstain deriving (Show,Eq)
  4. data Results = PilloriedInScience | EatenByTigers | Freed deriving (Eq,Show)
  5. data Color = Red | Green deriving (Show,Eq)
  6.  
  7. -- to simplify things, let's assume choices are only predicated upon
  8. -- the number of bits that go one way or the other
  9. -- (numRed, numGreen)
  10. -- Note that ChoiceFunctions are a function of the SEEN input, so the sum
  11. -- of the numRed and numGreen that they get should be one less than the total.
  12. type BoothInput = (Int,Int)
  13. type ChoiceFunction = BoothInput -> Choice
  14.  
  15. generateAllInputs :: Int -> [[Color]]
  16. generateAllInputs 1 = [[Red],[Green]]
  17. generateAllInputs n = let rec = generateAllInputs (n-1) in
  18. (map (\x-> Red:x) rec) ++ (map (\x-> Green:x) rec)
  19.  
  20. generateAllChoiceLists :: Int -> [[Choice]]
  21. generateAllChoiceLists 1 = [[PickRed],[PickGreen],[Abstain]]
  22. generateAllChoiceLists n = let rec = generateAllChoiceLists (n-1) in
  23. (map (\x->PickRed:x) rec) ++ (map (\x-> PickGreen:x) rec) ++ (map (\x-> Abstain:x) rec)
  24.  
  25. generateAllChoiceFuncs :: Int -> [ChoiceFunction]
  26. generateAllChoiceFuncs 0 = []
  27. generateAllChoiceFuncs n =
  28. let
  29. allChoiceLists = generateAllChoiceLists n
  30. inputs = map (\x-> (x,n-1-x)) [0..(n-1)]
  31. in
  32. map (graphToFunc . (zip inputs)) allChoiceLists
  33.  
  34. -- very unsafe and unoptimized, but whatevs. yay lazy languages
  35. graphToFunc :: (Eq a, Show a) => [(a,b)] -> (a->b)
  36. graphToFunc [] = \x -> error ("Didn't handle input: " ++ (show x))
  37. graphToFunc ((x,fx):tail) = \y -> if y == x then fx else graphToFunc tail y
  38.  
  39. showChoiceFunction :: ChoiceFunction -> Int -> String
  40. showChoiceFunction f n =
  41. let
  42. domain = map (\x->(x,n-1-x)) [0..(n-1)]
  43. itemDec = map (\(x,y) -> "\t("++(show x)++" Red,"++(show y)++" Green) -> "++(show$f(x,y))++"\n") domain
  44. in
  45. (foldl (++) "{\n" itemDec) ++ "}\n"
  46.  
  47. choiceFuncGoodness :: ChoiceFunction -> [[Color]] -> Float
  48. choiceFuncGoodness func inputs =
  49. let
  50. goodResults = filter (\x->x==Freed) (map (getResults func . numRedGreen) inputs)
  51. in
  52. (fromIntegral $ length goodResults) / (fromIntegral $ length inputs)
  53.  
  54. getBestFunc :: [ChoiceFunction] -> [[Color]] -> ChoiceFunction
  55. getBestFunc funcs inputs = argmax (\x -> choiceFuncGoodness x inputs) funcs
  56.  
  57. getResults :: ChoiceFunction -> BoothInput -> Results
  58. getResults choiceFunc input =
  59. endResult $
  60. (replicate (fst input) $ (choiceFunc (seenInput Red input), Red))
  61. ++ (replicate (snd input) $ (choiceFunc (seenInput Green input), Green))
  62.  
  63. numRedGreen :: [Color] -> BoothInput
  64. numRedGreen [] = (0,0)
  65. numRedGreen (Red:tail) = let rec = numRedGreen tail in (1+fst rec, snd rec)
  66. numRedGreen (Green:tail) = let rec = numRedGreen tail in (fst rec, 1+snd rec)
  67.  
  68.  
  69. seenInput :: Color -> BoothInput -> BoothInput
  70. seenInput Red (x,y) = (x-1,y)
  71. seenInput Green (x,y) = (x,y-1)
  72.  
  73. endResult :: [(Choice,Color)] -> Results
  74. endResult [] = EatenByTigers
  75. endResult ((Abstain,_):tail) = endResult tail
  76. endResult ((PickRed,Red):tail) = case endResult tail of
  77. PilloriedInScience -> PilloriedInScience
  78. _ -> Freed
  79. endResult ((PickGreen,Green):tail) = endResult ((PickRed,Red):tail)
  80. endResult _ = PilloriedInScience
  81.  
  82. bestFuncForSize :: Int -> ChoiceFunction
  83. bestFuncForSize n = getBestFunc (generateAllChoiceFuncs n) (generateAllInputs n)
  84.  
  85. showFuncWithGoodness :: Int -> ChoiceFunction -> String
  86. showFuncWithGoodness n f =
  87. let
  88. funcRep = showChoiceFunction f n
  89. funcVal = choiceFuncGoodness f (generateAllInputs n)
  90. output = funcRep ++ "\nChance of escape: " ++ (show funcVal) ++ "\n"
  91. in
  92. output
  93.  
  94. main =
  95. let
  96. numBooths = 5
  97. bestFunc = bestFuncForSize numBooths
  98. in
  99. putStr $ showFuncWithGoodness numBooths bestFunc
  100. --putStr $ foldl (++) "" $ map (showFuncWithGoodness numBooths) (generateAllChoiceFuncs numBooths)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement