module Exercise02 where import Data.List import Data.Ord (comparing) {-H2.1a)-} twoThirdsAverageWinners :: [(String, Int)] -> [String] twoThirdsAverageWinners gs = select (sortBy (\(a, b) (c, d) -> if b > d then GT else LT) [(w, abs (z - (floor (2.0 * ((toRational (sum [y | (x, y) <- gs]) / toRational (length gs)) / 3.0))))) | (w, z) <- gs]) where select n = [x | (x, y) <- n, y == snd (n !! 0)] {-H2.1b)-} lowestUniqueBidder :: [(String, Int)] -> String lowestUniqueBidder bs = checkLowest (sortBy (\(a, b) (c, d) -> if b > d then GT else LT) bs) 0 ((length bs) -1) where checkLowest xs n l | l == 0 = fst (xs !! n) | n == 0 && (snd (xs !! n) /= snd (xs !! (n + 1))) = fst (xs !! n) | 0 < n && n < l && (snd (xs !! n) /= snd (xs !! (n + 1))) && (snd (xs !! n) /= snd (xs !! (n -1))) = fst (xs !! n) | n == l && (snd (xs !! n) /= snd (xs !! (n -1))) = fst (xs !! n) | n == l = "Nobody" | otherwise = checkLowest xs (n + 1) l {-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 = filter (\player -> player /= i && not (player `elem` dominion tournament i)) (players tournament) {-H2.2b)-} covers :: [[Int]] -> Int -> Int -> Bool covers tournament i j = length [player | player <- (dominion tournament j), not (player `elem` dominion tournament i)] == 0 {-2.2c)-} dominant :: [[Int]] -> [Int] -> Bool dominant tournament xs = length xs /= 0 && length [dominated | dominated <- [player | player <- players tournament, not (player `elem` xs)], dominator <- xs, not (dominated `elem` dominion tournament dominator)] == 0 {-WETT-} {-H2.2d)-} copeland :: [[Int]] -> [Int] copeland tournament = succ <$> maximum dlength `elemIndices` dlength where dlength = map length tournament {-H2.2e)-} uncoveredSet :: [[Int]] -> [Int] uncoveredSet tournament = f `filter` players tournament where f x = length [player | player <- players tournament, covers tournament player x] == 1 {-H2.2f)-} topCycle :: [[Int]] -> [Int] topCycle tournament = recurse $ copeland tournament where recurse rs = if null $ f\\rs then rs else recurse f ++ rs where f = dominators tournament `concatMap` nub rs {-TTEW-}