module Exercise02 where import Data.List import Data.Ord {-H2.1a)-} twoThirdsAverageWinners :: [(String, Int)] -> [String] twoThirdsAverageWinners gs = map fst (filter (\x -> snd x >= nearest && abs (snd x - avg) == abs (nearest - avg)) gs) where nearest = findNearest (map snd gs) avg avg = (sum (map snd gs) * 2) `div` (3 * length gs) findNearest :: [Int] -> Int -> Int findNearest gs avg | minimum gs >= avg = minimum gs | maximum gs < avg = maximum gs | otherwise = if abs (maximum (filter (<= avg) gs) - avg) <= (minimum (filter (> avg) gs) - avg) then maximum (filter (<= avg) gs) else minimum (filter (> avg) gs) {-H2.1b)-} lowestUniqueBidder :: [(String, Int)] -> String lowestUniqueBidder bs | null filteredBs = "Nobody" | otherwise = fst (head (head filteredBs)) where sortedBs = sortOn snd bs filteredBs = filter (\x -> length x == 1) (groupBy (\x y -> snd x == snd y) sortedBs) {-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 = union (dominion tournament i) (dominion tournament j) == dominion tournament i {-2.2c)-} dominant :: [[Int]] -> [Int] -> Bool dominant tournament xs | null xs = False | otherwise = not (any (`notElem` xs) (nub (concat [dominators tournament x | x <- xs]))) --sort ([def | def <- nub (concat [dominion tournament x | x <- xs]), def `notElem` xs]) == sort ([d | d <- players tournament, d `notElem` xs]) {-WETT-} {-H2.2d)-} copeland :: [[Int]] -> [Int] copeland tournament = map (+1) $ elemIndices (maximum wins) wins where wins = map length tournament {-H2.2e)-} uncoveredSet :: [[Int]] -> [Int] uncoveredSet tournament = topCycle tournament \\ [ x | x <- topCycle tournament, y <- topCycle tournament, x /= y , covers tournament y x] {-H2.2f)-} topCycle :: [[Int]] -> [Int] topCycle tournament = addDominators tournament startNodes startNodes where startNodes = copeland tournament addDominators :: [[Int]] -> [Int] -> [Int] -> [Int] addDominators tournament toAdd dom | null toAdd = dom | otherwise = addDominators tournament newToAdd $ dom ++ newToAdd where newToAdd = nub (concatMap (dominators tournament) toAdd) \\ dom {-TTEW-}