module Exercise02 where import Data.List import Data.Ord {-H2.1a)-} twoThirdsAverageWinners :: [(String, Int)] -> [String] twoThirdsAverageWinners gs = let bids = [ x | (s, x) <- gs ] avg = div (2 * sum bids) (3 * length bids) merr = minimum [ abs (x - avg) | x <- bids ] in [ s | (s, x) <- gs, abs (x - avg) == merr ] {-H2.1b)-} lowestUniqueBidder :: [(String, Int)] -> String lowestUniqueBidder bs = let uqBids = unique [ x | (s, x) <- bs ] lowUniq = minimum $ uqBids in if null uqBids then "Nobody" else head [ s | (s, x) <- bs, x == lowUniq ] unique :: [Int] -> [Int] unique [] = [] unique [x] = [x] unique (x:xs) = if elem x xs then unique $ removeItem x xs else x : unique xs removeItem :: Int -> [Int] -> [Int] removeItem x xs = [ n | n <- xs, n /= x ] {-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 = let ps = players tournament di = dominion tournament i in [ j | j <- ps, j /= i, j `notElem` di ] {-H2.2b)-} covers :: [[Int]] -> Int -> Int-> Bool covers tournament i j = let dj = dominion tournament j di = dominion tournament i in and [ x `elem` di | x <- dj ] {-H2.2c)-} dominant :: [[Int]] -> [Int] -> Bool dominant _ [] = False dominant tournament xs = let ps = players tournament losers = [ p | p <- ps, p `notElem` xs ] in and [ and [ l `elem` dominion tournament x | l <- losers ] | x <- xs ] {-WETT-} {-H2.2d)-} copeland :: [[Int]] -> [Int] copeland tournament = let w = maximum $ map length tournament in filter (\x -> length (dominion tournament x) == w) (players tournament) {-H2.2e)-} uncoveredSet :: [[Int]] -> [Int] uncoveredSet tournament = let ps = players tournament in filter (\i -> and [ not $ covers tournament j i | j <- ps, j /= i ]) ps {-H2.2f)-} topCycle :: [[Int]] -> [Int] topCycle tournament = sort $ aux $ copeland tournament where aux xs | dominant tournament xs = xs | otherwise = aux $ nub $ concat $ map (dominators tournament) xs {-TTEW-}