module Exercise02 where import Data.List import Data.Ord {-H2.1a)-} twoThirdsAverageWinners :: [(String, Int)] -> [String] twoThirdsAverageWinners xs = [n | (n, b) <- xs, dis b == minimum [dis b | (_, b) <- xs]] where a = realToFrac (sum [b | (_, b) <- xs]) / realToFrac (length xs) wv = floor ((2.0 * a) / 3.0) dis x = abs $ wv - x {-H2.1b)-} lowestUniqueBidder :: [(String, Int)] -> String lowestUniqueBidder xs = getwinner $ sortOn snd xs where getwinner [] = "Nobody" getwinner [(n, _)] = n getwinner ((n1, b1) : (_, b2) : xs) | b1 /= b2 = n1 | otherwise = getwinner $ dropWhile isb1 xs where isb1 (_, b) = b == b1 --Test [("a",30),("b",30),("c",20),("d",19),("e",30)] {-H2-} -- returns the shortest list in a list of lists shortest :: [[Int]] -> [Int] shortest = minimumBy (comparing length) -- returns the set of all players in a tournament players :: [[Int]] -> [Int] players tournament = [1 .. length tournament] -- returns the dominion of player i dominion :: [[Int]] -> Int -> [Int] dominion tournament i = tournament !! (i - 1) {-H2.2a)-} dominators :: [[Int]] -> Int -> [Int] dominators tournament i = aux tournament 1 where aux [] _ = [] aux (x : xs) a | i `elem` x = a : aux xs (a + 1) | otherwise = aux xs (a + 1) {-H2.2b)-} covers :: [[Int]] -> Int -> Int -> Bool covers tournament i j = aux $ dominion tournament j where aux [] = True aux (x : xs) = x `elem` dominion tournament i && aux xs {-2.2c)-} -- a enthat b dominant :: [[Int]] -> [Int] -> Bool dominant _ [] = False dominant tournament xs = aux xs where notin = [p | p <- players tournament, p `notElem` xs] aux [] = True aux (x : xs) = notin == intersect (dominion tournament x) notin && aux xs {-WETT-} {-H2.2d)-} copeland :: [[Int]] -> [Int] copeland tournament = [p | p <- players tournament, length (dominion tournament p) == length (maximumBy (comparing length) tournament)] --ugly version: copeland tournament = filter ((length (maximumBy (comparing length) tournament) ==) . (length . dominion tournament)) $ players tournament {-H2.2e)-} uncoveredSet :: [[Int]] -> [Int] uncoveredSet tournament = [p | p <- players tournament, not $ or [p /= p2 && covers tournament p2 p | p2 <- players tournament]] {-H2.2f)-} topCycle :: [[Int]] -> [Int] topCycle tournament = aux $ uncoveredSet tournament where aux xs = if dominant tournament xs then xs else aux $ filter (flip notElem $ foldl intersect (players tournament) $ map (dominion tournament) xs) $ players tournament -- slow version: topCycle tournament = shortest $ filter (dominant tournament) $ subsequences $ players tournament {-TTEW-}