module Exercise02 where import Data.List import Data.Ord import qualified Data.List.NonEmpty as NE {-H2.1a)-} twoThirdsAverageWinners :: [(String, Int)] -> [String] twoThirdsAverageWinners gs = [x | (x,y) <- [(x,abs (y - a )) | (x,y) <- gs], y == minimum[y | (_,y) <- [(x,abs (y - a)) | (x,y) <- gs]]] where a = (2*sum [y | (_,y) <- gs]) `div` (3*length gs) {-H2.1b)-} lowestUniqueBidder :: [(String, Int)] -> String lowestUniqueBidder bs |null bs' = "Nobody" |otherwise = head [x | (x,y) <- bs, y == minimum bs'] where bs' = removeDuplicateEntries [y | (_,y) <- bs] removeDuplicateEntries :: [Int] -> [Int] removeDuplicateEntries ns = nub ns \\ (ns \\ nub ns) {-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 = [y | y <- players tournament, i `elem` dominion tournament y] {-H2.2b)-} covers :: [[Int]] -> Int -> Int-> Bool covers _ i j | i == j = False covers tournament i j = null $ dominion tournament j \\ dominion tournament i {-H2.2c)-} dominant :: [[Int]] -> [Int] -> Bool dominant _ [] = False dominant tournament xs = and [null $ (players tournament \\ xs) \\ dominion tournament x | x <- xs] {-WETT-} {-H2.2d)-} copeland :: [[Int]] -> [Int] copeland tournament = NE.toList $ last $ (length . dominion tournament) `NE.groupAllWith` players tournament {-H2.2e)-} --The set of all player minus the set of player who are covered. uncoveredSet :: [[Int]] -> [Int] uncoveredSet tournament = [x | x <- players tournament, not $ or [covers tournament y x | y <- players tournament]] {-MCCOMMENT: I prefer this version, but it's ever so slightly longer uncoveredSet' :: [[Int]] -> [Int] uncoveredSet' tournament = filter (flip all z . ctf) z where x `ctf` y = not $ covers tournament y x; z = players tournament -} {-H2.2f)-} topCycle :: [[Int]] -> [Int] topCycle tournament = topCycleH $ uncoveredSet tournament where topCycleH xs = if tournament `dominant` xs then xs else topCycleH $ xs `union` concatMap (dominators tournament) xs {-TTEW-}