Advertisement
Guest User

Untitled

a guest
Jul 20th, 2017
111
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. module Kopapir where
  2.  
  3. type Sign = Int
  4.  
  5. validSigns :: (Sign -> Sign -> a) -> Sign -> Sign -> a
  6. validSigns f a b
  7.   | a >= 0 && a < 3 && b >= 0 && b < 3 = f a b
  8. validSigns _ a b = error $ "validSigns: invalid values: (" ++ show a ++ "," ++ show b ++ ")"
  9.  
  10. beats :: Sign -> Sign -> Bool
  11. 0 `beats` 2 = True
  12. 1 `beats` 0 = True
  13. 2 `beats` 1 = True
  14. a `beats` b = validSigns f a b
  15.    where f _ _ = False
  16.  
  17. isDraw :: Sign -> Sign -> Bool
  18. isDraw a b = validSigns f a b
  19.    where f x y = x == y
  20.  
  21. result :: Sign -> Sign -> Int
  22. result a b
  23.   | isDraw a b  = 0
  24.   | a `beats` b = 1
  25.   | otherwise   = -1
  26.  
  27. type Play = [Sign]
  28. type Rounds = (Play, Play)
  29.  
  30. tournament :: Rounds -> Int
  31. tournament (xs, ys)
  32.  | l < 0     = 2
  33.  | l > 0     = 1
  34.  | otherwise = 0
  35.    where
  36.      l = sum $ map (\(x,y) -> result x y) $ zip xs ys
  37.    
  38. partitionRounds :: Rounds -> ([Sign], [Sign], [Sign])
  39. partitionRounds (xs,ys) = ([ b | (a, b) <- r, a == 1], [ b | (a, b) <- r, a == 0], [ b | (a, b) <- r, a == -1])
  40.     where
  41.       r = map (\(x,y) -> (result x y, x)) $ zip xs ys
  42.  
  43. next :: Sign -> Sign
  44. next 0 = 1
  45. next 1 = 2
  46. next 2 = 0
  47.  
  48. frequency :: Eq a => a -> [a] -> Int
  49. frequency _ []   = 0
  50. frequency a (x:xs)
  51.   | x == a    = 1 + frequency a xs
  52.   | otherwise = frequency a xs
  53.  
  54. mostFrequent :: Ord a => [a] {-nem üres-} -> a
  55. mostFrequent x = snd $ maximum $ map (\a -> (frequency a x, a)) $ nub x
  56.  
  57. type Strategy = Rounds -> Sign -- (Play, Play) -> Sign
  58.  
  59. strategy1 :: Strategy
  60. strategy1 ([],[])    = 0
  61. strategy1 (x:_, y:_)
  62.   | result x y == 1 = y
  63.   | otherwise       = next y
  64.  
  65.  
  66. strategy2 :: Strategy
  67. strategy2 ([],[]) = 2
  68. strategy2 (_, ys) = next $ mostFrequent ys
  69.  
  70. strategy3 :: Strategy
  71. strategy3 ([],[]) = 1
  72. strategy3 rounds
  73.  | length (won r) == length (lost r) = next $ mostFrequent (tie r)
  74.  | length (won r) >  length (lost r) = mostFrequent (won r)
  75.  | otherwise                         = next $ mostFrequent (lost r)  
  76.    where
  77.       r = partitionRounds rounds
  78.       won  (a,_,_) = a
  79.       tie  (_,b,_) = b
  80.       lost (_,_,c) = c
  81.  
  82. applyStrategies :: Strategy -> Strategy -> Rounds -> Rounds
  83. applyStrategies s1 s2 r@(xs,ys) = (s1 r : xs, s2 (ys, xs) : ys)
  84.  
  85. play :: Int -> Strategy -> Strategy -> Rounds
  86. play n s1 s2
  87.   | n <= 0    = ([], [])
  88.   | otherwise = applyStrategies s1 s2 (play (n-1) s1 s2)
  89.  
  90. winningStrategy :: Strategy -> [Strategy] -> [Int]
  91. winningStrategy = winningStrategyN 1
  92.   where
  93.    winningStrategyN :: Int ->  Strategy -> [Strategy] -> [Int]
  94.    winningStrategyN _ _ [] = []
  95.    winningStrategyN n s (x:xs)
  96.      | (tournament $ play 10 s x) == 2 = n : winningStrategyN (n+1) s xs
  97.      | otherwise                       = winningStrategyN (n+1) s xs
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement