module Exercise02 where import Data.List import Data.Ord {-H2.1a)-} twoThirdsAverageWinners :: [(String, Int)] -> [String] twoThirdsAverageWinners gs = [fst g | g <- gs, abs (avg - snd g) == minimum [abs (avg - snd g) | g <- gs]] where avg = floor $ (2 / 3) * fromIntegral (sum [snd g | g <- gs]) / fromIntegral (length gs) {-H2.1b)-} lowestUniqueBidder :: [(String, Int)] -> String lowestUniqueBidder bs = head $ [fst b | b <- ls, snd b == minimum [snd b | b <- ls, length (filter (\t -> snd t == snd b) ls) == 1]] where ls = bs ++ [("Nobody", 101)] {-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 = [p | p <- players tournament, i `elem` dominion tournament p] {-H2.2b)-} covers :: [[Int]] -> Int -> Int -> Bool covers tournament i j = [p | p <- dominion tournament j, p `elem` dominion tournament i] == dominion tournament j {-2.2c)-} dominant :: [[Int]] -> [Int] -> Bool dominant tournament gs = not (null gs) && [g | g <- gs, dominion tournament g \\ gs == players tournament \\ gs] == gs {-WETT-} {-H2.2d)-} copeland :: [[Int]] -> [Int] copeland tournament = (\p -> maximum (map length tournament) == length (dominion tournament p)) `filter` players tournament {-H2.2e)-} uncoveredSet :: [[Int]] -> [Int] uncoveredSet tournament = (\p -> all (\x -> not $ covers tournament x p) (p `delete` players tournament)) `filter` players tournament {-H2.2f)-} topCycle :: [[Int]] -> [Int] topCycle tournament = tournament `helper2` length tournament helper2 :: [[Int]] -> Int -> [Int] helper2 tournament 0 = copeland tournament helper2 tournament i = xs `union` concatMap (tournament `dominators`) xs where xs = helper2 tournament (i -1) {-MCCOMMENT --slow but short :/ topCycle :: [[Int]] -> [Int] topCycle tournament = shortest $ filter (tournament `dominant`) (subsequences $ players tournament) -} {-TTEW-}