module Exercise02 where import Data.List import Data.Ord import Test.QuickCheck {-H2.1a)-} twoThirdsAverageWinners :: [(String, Int)] -> [String] twoThirdsAverageWinners gs = let twothirds = div (sum [bid | (name, bid) <- gs] * 2) (length gs * 3) in [name | (name, bid) <- gs, abs (bid - twothirds) == minimum [abs (twothirds - bid) | (name, bid) <- gs]] --I'm so sorry if a human ever has to read this, I'm not yet that comfortable with functional programing {-H2.1b)-} lowestUniqueBidder :: [(String, Int)] -> String lowestUniqueBidder bs | null uniques = "Nobody" | otherwise = fst $ minimumBy (comparing snd) uniques where uniques = [x | x <- bs, isUnique (snd x) bs] isUnique :: Int -> [(String, Int)] -> Bool isUnique val list = length [name | (name, bid) <- list, val == bid] == 1 {-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, x `notElem` dominion tournament i && x /= i] {-H2.2b)-} covers :: [[Int]] -> Int -> Int -> Bool covers tournament i j = all (\x -> x `elem` dominion tournament i) (dominion tournament j) {-2.2c)-} dominant :: [[Int]] -> [Int] -> Bool dominant tournament xs | null xs = False | otherwise = all (\x -> all (\other -> other `elem` dominion tournament x) (filter (`notElem` xs) (players tournament))) xs copelandSafe :: [[Int]] -> [Int] copelandSafe tournament = map succ (elemIndices (maximum (map length tournament)) (map length tournament)) -- [player | player<-players tournament,length (dominion tournament player)== maximum [length (dominion tournament player)|player <- players tournament]] {-H2.2e)-} uncoveredSetSafe :: [[Int]] -> [Int] uncoveredSetSafe tournament = [i | i <- players tournament, all (\x -> not (covers tournament x i)) [j | j <- players tournament, j /= i]] --uncoveredSet tournament = filter (\i -> all (\x -> x==i || not (covers tournament x i)) $ players tournament) $ players tournament {-H2.2f)-} topCycleSafe :: [[Int]] -> [Int] topCycleSafe tournament = head (filter (dominant tournament) (subsequences (players tournament))) {-WETT-} {-H2.2d)-} copeland :: [[Int]] -> [Int] copeland tournament = succ <$> maximum ns `elemIndices` ns where ns = map length tournament {-H2.2e)-} uncoveredSet :: [[Int]] -> [Int] uncoveredSet tournament = players tournament \\ [y | y<-players tournament,x <- y `delete` players tournament,covers tournament x y] {-H2.2f)-} topCycle :: [[Int]] -> [Int] topCycle tournament = addPlayers tournament [] $ 1 `take` copeland tournament addPlayers :: [[Int]] -> [Int] -> [Int] -> [Int] addPlayers tournament done (first : todo) | first `elem` done = addPlayers tournament done todo | otherwise = first : addPlayers tournament (first : done) (todo ++ dominators tournament first) addPlayers tournament done x = x --x = [] {-TTEW-} prop_copeland :: [[Int]] -> Bool prop_copeland t = copelandSafe t == copeland t prop_uncoveredSet :: [[Int]] -> Bool prop_uncoveredSet t = uncoveredSetSafe t == uncoveredSet t prop_topCycle :: [[Int]] -> Bool prop_topCycle t = topCycleSafe t == topCycle t prop_all :: [[Int]] -> Bool prop_all [] = True prop_all t = prop_copeland t && prop_topCycle t && prop_uncoveredSet t game :: Int -> [[Int]] game 0 = [[1, 3, 4, 5, 6, 7, 8, 11, 13, 14, 15, 16, 17], [1, 2, 3, 7, 9, 12, 14, 15, 17, 20], [3, 4, 6, 7, 8, 9, 10, 12, 15, 16, 17, 18], [2, 4, 7, 8, 10, 11, 12, 14, 18], [2, 3, 4, 5, 7, 8, 11, 12, 14, 15, 16, 17], [2, 4, 5, 6, 7, 10, 11, 12, 14, 15, 17], [7, 8, 10, 12, 13, 17, 19, 20], [2, 6, 8, 10, 11, 12, 14, 15, 17], [1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 15, 16, 20], [1, 2, 5, 10, 12, 14, 15, 16, 17, 19], [2, 3, 7, 10, 11, 16, 17, 20], [1, 11, 12, 16, 17, 18, 19, 20], [2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 16, 19], [3, 7, 11, 12, 13, 14, 17, 18], [4, 7, 11, 12, 13, 14, 15, 16, 20], [2, 4, 6, 7, 8, 14, 16, 17, 18], [4, 9, 13, 15, 17, 20], [1, 2, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 18, 20], [1, 2, 3, 4, 5, 6, 8, 9, 11, 14, 15, 16, 17, 18, 19], [1, 3, 4, 5, 6, 8, 10, 13, 14, 16, 19, 20]] game 1 = [[4], [1], [1, 2, 4, 5], [2], [1, 2, 4, 6], [1, 2, 3, 4]] game 2 = [[1, 2, 3, 4], [2, 4], [2, 3, 4], [4]] game 3 = [[1, 3, 5, 8, 10], [1, 2, 4, 5, 8, 10], [2, 3, 5, 6, 7, 8, 9], [1, 3, 4, 6, 7, 8], [4, 5, 6, 7, 8, 10], [1, 2, 6, 7, 8], [1, 2, 10, 7], [8, 10, 7], [1, 2, 4, 5, 6, 7, 8, 9], [3, 4, 6, 9, 10]] game 4 = [[1, 2, 7, 8, 11, 13, 15, 19], [2, 4, 5, 6, 7, 8, 9, 11, 12, 14, 15, 18, 20], [1, 2, 3, 5, 6, 9, 11, 12, 14, 16, 17, 20], [1, 3, 4, 5, 6, 7, 9, 10, 13, 14, 16, 19, 20], [1, 5, 6, 7, 9, 10, 12, 13, 15, 18, 19, 20], [1, 6, 9, 10, 11, 12, 13, 19], [3, 6, 7, 10, 13, 14, 16, 19], [3, 4, 5, 6, 7, 8, 9, 10, 13, 16, 17, 19, 20], [1, 7, 9, 12, 13, 18, 20], [1, 2, 3, 9, 10, 11, 14, 16, 17], [4, 5, 7, 8, 9, 11, 12, 13, 15, 16, 17], [1, 4, 7, 8, 10, 12, 15, 18, 19], [2, 3, 10, 12, 13, 14, 16, 18, 19], [1, 5, 6, 8, 9, 11, 12, 14, 18, 19, 20], [3, 4, 6, 7, 8, 9, 10, 13, 14, 15, 17, 18, 19, 20], [1, 2, 5, 6, 9, 12, 14, 15, 16, 18], [1, 2, 4, 5, 6, 7, 9, 12, 13, 14, 16, 17, 19, 20], [1, 3, 4, 6, 7, 8, 10, 11, 17, 18], [2, 3, 9, 10, 11, 16, 18, 19], [1, 6, 7, 10, 11, 12, 13, 16, 18, 19, 20]] game 5 = [[1, 3, 5, 6, 8, 10, 12, 14, 15], [1, 2, 4, 7, 8, 11, 14], [2, 3, 4, 7, 8, 9, 12, 15], [1, 4, 6, 9, 11, 15], [2, 3, 4, 5, 6, 9, 12, 13, 14], [2, 3, 6, 9, 11, 12, 13], [1, 4, 5, 6, 7, 8, 10, 11, 12, 14], [4, 5, 6, 8, 10, 11, 14], [1, 2, 7, 8, 9, 12, 15], [2, 3, 4, 5, 6, 9, 10, 11, 12, 13, 14], [1, 3, 5, 9, 11, 12, 13, 15], [2, 4, 8, 12, 13, 14, 15], [1, 2, 3, 4, 7, 8, 9, 13], [3, 4, 6, 9, 11, 13, 14], [2, 5, 6, 7, 8, 10, 13, 14, 15]] game 6 = [[1, 2, 5, 8, 9, 11], [2, 3, 5, 8, 9, 11, 12], [1, 3, 5, 9], [1, 2, 3, 4, 5, 7, 9], [5, 7, 8, 10, 12], [1, 2, 3, 4, 5, 6, 8, 9, 12], [1, 2, 3, 6, 7, 9, 10], [8, 3, 4, 7], [5, 8, 9, 10, 12], [1, 2, 3, 4, 6, 8, 10, 11, 12], [3, 4, 5, 6, 7, 8, 9, 11], [1, 3, 4, 7, 8, 11, 12]] game 7 = [[1, 2, 3, 4, 5, 8, 10], [9, 2, 4, 7], [8, 2, 3, 7], [8, 3, 4, 7], [2, 3, 4, 5, 6, 7, 9, 10], [1, 2, 3, 4, 6, 7, 8], [8, 1, 9, 7], [8, 2, 5], [1, 3, 4, 6, 8, 9, 10], [2, 3, 4, 6, 7, 8, 10]] game 8 = [[1, 3, 4, 5], [1, 2, 4, 6], [2, 3, 4, 5, 7], [4, 6, 7], [2, 4, 5, 7], [1, 3, 5, 6, 8], [1, 2, 6, 7], [1, 2, 3, 4, 5, 7, 8]] game 9 = [[1, 4, 6], [1, 2, 4, 5], [1, 2, 3], [3, 4, 6], [1, 3, 4, 5], [2, 3, 5, 6]] testTop :: Int -> Bool testTop i = t1 == t2 && dominant (game i) t1 && dominant (game i) t2 where t1 = sort (topCycle (game i)) t2 = topCycleSafe (game i)