module Exercise02 where import Data.List import Data.Ord import Data.Maybe (fromMaybe) {-H2.1a)-} twoThirdsAverageWinners :: [(String, Int)] -> [String] twoThirdsAverageWinners bs = [ name | (name, value) <- aux bs, value == head ([b | (a, b) <- aux bs])] where aux bs = sortBy (\(_, a) (_, b) -> compare a b) [(name, abs (((2 * (sum vs)`div`length vs) `div` 3) - value)) | (name, value) <- bs] where (ns, vs) = unzip bs {-H2.1b)-} lowestUniqueBidder :: [(String, Int)] -> String lowestUniqueBidder bs = if null bs then "Nobody" else if length (aux bs) > 1 then lowestUniqueBidder ([(name, value) | (name, value) <- bs, name `notElem` aux bs]) else head [n | n <- aux bs] where aux bs = [ name | (name, value) <- sortBy (\(_, a) (_, b) -> compare a b) bs, value == head [b | (a, b) <- sortBy (\(_, a) (_, b) -> compare a b) bs]] {-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 = [x | x <- players tournament, i `elem` dominion tournament x] {-H2.2b)-} covers :: [[Int]] -> Int -> Int-> Bool covers tournament i j = null([xj | xj <- dominion tournament j, xj `notElem` dominion tournament i]) {-2.2c)-} dominant :: [[Int]] -> [Int] -> Bool dominant tournament dom | null dom = False | otherwise = all (isSubset notdom) [xs | (xs, i) <- zip tournament [1..], i `elem` dom] where notdom = filter (`notElem` dom) (players tournament) isSubset :: [Int] -> [Int] -> Bool isSubset xs ys = all (`elem` ys) xs {-WETT-} {-H2.2d)-} copeland :: [[Int]] -> [Int] copeland tournament = [fromMaybe 0 (elemIndex xs tournament) + 1 | xs <- tournament, length xs == maximum (map length tournament)] {-H2.2e)-} uncoveredSet :: [[Int]] -> [Int] uncoveredSet tournament = players tournament \\ [y | y <- players tournament, x <- players tournament \\ [y] , covers tournament x y] {-H2.2f)-} topCycle :: [[Int]] -> [Int] topCycle tournament = aux (copeland tournament) where aux ds = if dominant tournament ds then ds else aux (foldr1 union [dominators tournament y | y <- ds]) {-TTEW-}