Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- module Kopapir where
- type Sign = Int
- {-
- validSigns f a b
- | a `elem` signs && b `elem` signs = f a b
- where signs = [1,2,3]
- validSigns _ a b = error $ "validSigns: invalid values: (" ++ show a ++ "," ++ show b ++ ")"
- -}
- validSigns :: (Sign -> Sign -> a) -> Sign -> Sign -> a
- validSigns f a b
- | a >= 0 && a < 3 && b >= 0 && b < 3 = f a b
- validSigns _ a b = error $ "validSigns: invalid values: (" ++ show a ++ "," ++ show b ++ ")"
- beats :: Sign -> Sign -> Bool
- 0 `beats` 2 = True
- 1 `beats` 0 = True
- 2 `beats` 1 = True
- a `beats` b = validSigns f a b
- where f _ _ = False
- isDraw :: Sign -> Sign -> Bool
- isDraw a b = validSigns f a b
- where f x y = x == y
- result :: Sign -> Sign -> Int
- result a b
- | isDraw a b = 0
- | a `beats` b = 1
- | otherwise = -1
- type Play = [Sign]
- type Rounds = (Play, Play)
- tournament :: Rounds -> Int
- tournament (xs, ys)
- | l < 0 = 2
- | l > 0 = 1
- | otherwise = 0
- where
- l = sum $ map (\(x,y) -> result x y) $ zip xs ys
- partitionRounds :: Rounds -> ([Sign], [Sign], [Sign])
- partitionRounds (xs,ys) = ([ b | (a, b) <- r, a == 1], [ b | (a, b) <- r, a == 0], [ b | (a, b) <- r, a == -1])
- where
- r = map (\(x,y) -> (result x y, x)) $ zip xs ys
- next :: Sign -> Sign
- next 0 = 1
- next 1 = 2
- next 2 = 0
- frequency :: Eq a => a -> [a] -> Int
- frequency _ [] = 0
- frequency a (x:xs)
- | x == a = 1 + frequency a xs
- | otherwise = frequency a xs
- mostFrequent :: Ord a => [a] {-nem üres-} -> a
- mostFrequent x = snd $ maximum $ map (\a -> (frequency a x, a)) $ nub x
- type Strategy = Rounds -> Sign -- (Play, Play) -> Sign
- strategy1 :: Strategy
- strategy1 ([],[]) = 0
- strategy1 (x:_, y:_)
- | result x y == 1 = y
- | otherwise = next y
- strategy2 :: Strategy
- strategy2 ([],[]) = 2
- strategy2 (_, ys) = next $ mostFrequent ys
- strategy3 :: Strategy
- strategy3 ([],[]) = 1
- strategy3 rounds
- | length (won r) == length (lost r) = next $ mostFrequent (tie r)
- | length (won r) > length (lost r) = mostFrequent (won r)
- | otherwise = next $ mostFrequent (lost r)
- where
- r = partitionRounds rounds
- won (a,_,_) = a
- tie (_,b,_) = b
- lost (_,_,c) = c
- applyStrategies :: Strategy -> Strategy -> Rounds -> Rounds
- applyStrategies s1 s2 r@(xs,ys) = (s1 r : xs, s2 (ys, xs) : ys)
- play :: Int -> Strategy -> Strategy -> Rounds
- play n s1 s2
- | n <= 0 = ([], [])
- | otherwise = applyStrategies s1 s2 (play (n-1) s1 s2)
- winningStrategy :: Strategy -> [Strategy] -> [Int]
- winningStrategy = winningStrategyN 1
- where
- winningStrategyN :: Int -> Strategy -> [Strategy] -> [Int]
- winningStrategyN _ _ [] = []
- winningStrategyN n s (x:xs)
- | (tournament $ play 10 s x) == 2 = n : winningStrategyN (n+1) s xs
- | otherwise = winningStrategyN (n+1) s xs
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement