module Exercise02 where import Data.List import Data.Maybe import Data.Ord {-H2.1a)-} twoThirdsAverageWinners :: [(String, Int)] -> [String] twoThirdsAverageWinners gs = twoThirdsAverageWinners' gs [] a d where a = div (sum (map snd gs) * 2) (length gs * 3) d = minDiff gs a 100 twoThirdsAverageWinners' :: [(String, Int)] -> [String] -> Int -> Int -> [String] twoThirdsAverageWinners' gs ns a d | null gs = ns | otherwise = twoThirdsAverageWinners' (tail gs) (if abs (a - snd (head gs)) == d then ns ++ [fst (head gs)] else ns) a d minDiff :: [(String, Int)] -> Int -> Int -> Int minDiff gs a min | null gs = min | otherwise = minDiff (tail gs) a (if newMin < min then newMin else min) where newMin = abs (a - snd (head gs)) {-H2.1b)-} lowestUniqueBidder :: [(String, Int)] -> String lowestUniqueBidder bs | null uniqueNum = "Nobody" | otherwise = fst (head bs') where bs2 = map snd bs uniqueNum = [e | e <- bs2, e `notElem` (bs2 \\ nub bs2)] bs' = [e | e <- bs, snd e == minimum uniqueNum] {-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 = delete i (players tournament) \\ dominion tournament i {-H2.2b)-} covers :: [[Int]] -> Int -> Int -> Bool covers tournament i j = intersect (dominion tournament i) dj == dj where dj = dominion tournament j {-2.2c)-} dominant :: [[Int]] -> [Int] -> Bool dominant tournament xs | null xs = False | players tournament == xs = True | otherwise = null (union' (map (dominion tournament) (players tournament \\ xs)) `intersect` xs) where union' [] = [] union' xxs = head xxs `union` union' (tail xxs) {-WETT-} {-H2.2d)-} copeland :: [[Int]] -> [Int] copeland tournament = map (+ 1) (elemIndices (maximum l) l) where l = map length tournament {-H2.2e)-} uncoveredSet :: [[Int]] -> [Int] uncoveredSet tournament = p \\ [x | x <- p, y <- p, x /= y, covers tournament y x] where p = players tournament {-H2.2f)-} topCycle :: [[Int]] -> [Int] topCycle tournament = topCycle' tournament tournament where topCycle' tournament remaining = if dominant tournament set then set else topCycle' tournament (delete (maximumBy (comparing length) remaining) remaining) where set = map (\x -> 1 + fromJust (elemIndex x tournament)) (tournament \\ remaining) {-TTEW-}