{- Setup -} -- sequence is already defined in Prelude -- but does something different from what we want. import Prelude hiding (sequence) import Text.Read (readMaybe) import Data.List(sortBy, sort) {- Exercise 2 -} webData :: [String] webData = ["Youtube", "Google", "Facebook", "Youtube", "Facebook", "Youtube", "Facebook", "Google", "Youtube"] -- Task 1 uniqueWebsites = undefined -- Task 2 count = undefined -- Task 3 result = undefined {- Exercise 3 -} -- reference implementations collatzList :: Integer -> [Integer] collatzList 1 = [1] collatzList n = n : collatzList (if even n then n `div` 2 else 3 * n + 1) mercatorList :: Double -> [Double] mercatorList x | x <= -1 || x>1 = error "You must input a value x in -1 Integer -> [Double] mercatorListMain y n = let y' = y + ((-1)^(n + 1) * (x^n)) / fromInteger n in y : if y' == y then [] else mercatorListMain y' (n+1) -- Task 1 series :: (Integer -> Double) -> [Double] series = undefined -- Task 2 f :: Integer -> Double f i = 1 / 2^(i * i) mercator :: Double -> [Double] mercator = undefined -- Task 3 sequence :: (a -> a) -> (a -> Bool) -> a -> [a] sequence = undefined -- Task 4 collatz :: Integer -> [Integer] collatz = undefined {- Tests -} testFunEq :: (Show a,Show b,Eq c) => (b -> c) -> (a -> b) -> [(a,b)] -> Bool testFunEq eq f = all (\p -> eq (f (fst p)) == eq (snd p) || error ("on input "++(show (fst p))++" output is "++(show (f (fst p)))++" but should be "++(show (snd p)))) testFun :: (Show a,Show b,Eq b) => (a -> b) -> [(a,b)] -> Bool testFun = testFunEq id testFun2 testFun f l = testFun (\p -> f (fst p) (snd p)) (map (\(x,y,z) -> ((x,y),z)) l) splitter [] = [] splitter xs = case span (\ (a,_) -> a == fst (head xs)) xs of (as, rest) -> (fst $ head xs, sort (map snd as)) : splitter rest ioTestWebData = ["Facebook", "Google", "Google", "Facebook", "Youtube", "Twitter", "Twitter", "Facebook", "Google", "Google", "Facebook", "Twitter"] testUniqueWebsites = testFunEq sort uniqueWebsites [(webData, ["Google","Facebook","Youtube"]), (ioTestWebData, ["Facebook", "Google", "Youtube", "Twitter"])] testCount = testFun2 testFun count [("Google", webData, 2), ("Youtube", webData, 4), ("Facebook", webData, 3), ("Fake", webData, 0), ("Facebook", ioTestWebData, 4), ("Google", ioTestWebData, 4), ("Youtube", ioTestWebData, 1), ("Twitter", ioTestWebData, 3)] testResult = testFunEq splitter result [(webData, [(4,"Youtube"),(3,"Facebook"),(2,"Google")]), (ioTestWebData, [(4,"Google"),(4,"Facebook"),(3,"Twitter"),(1,"Youtube")])] tests = do check "series1" "[1.0,1.5,1.5625,1.564453125,1.5644683837890625,1.5644684135913849,1.5644684136059368,1.5644684136059386]" (series f) check "series2" "[0.0]" (series (const 0)) check "series3" "[0.0,1.0,3.0,6.0,10.0,15.0,21.0,28.0,36.0,45.0]" (series (\ x -> if x <= 9 then fromInteger x else 0)) check "mercator1" "[0.0]" (mercator 0) check "mercator2" "[0.0,1.0e-2,9.95e-3,9.950333333333334e-3,9.950330833333333e-3,9.950330853333333e-3,9.950330853166666e-3,9.950330853168095e-3,9.950330853168083e-3]" (mercator 0.01) check "mercator3" "[0.0,0.1,9.5e-2,9.533333333333334e-2,9.530833333333334e-2,9.531033333333334e-2,9.531016666666668e-2,9.531018095238097e-2,9.531017970238097e-2,9.531017981349207e-2,9.531017980349207e-2,9.531017980440117e-2,9.531017980431783e-2,9.531017980432552e-2,9.531017980432481e-2,9.531017980432488e-2]" (mercator 0.1) check "sequence1" "[0,1,2,3,4,5,6]" (sequence (+ 1) (> 5) 0) check "sequence2" "[3,4,5,6,7,8,9,10,11,12]" (take 10 (sequence (+ 1) (const False) 3)) check "sequence3" "[1,2,4,8,16,32,64,128,256,512,1024]" (sequence (* 2) (> 1000) 1) check "collatz1" "[1]" (collatz 1) check "collatz2" "[3,10,5,16,8,4,2,1]" (collatz 3) check "collatz3" "[255,766,383,1150,575,1726,863,2590,1295,3886,1943,5830,2915,8746,4373,13120,6560,3280,1640,820,410,205,616,308,154,77,232,116,58,29,88,44,22,11,34,17,52,26,13,40,20,10,5,16,8,4,2,1]" (collatz 255) check "webTest-uniqueWebsite" "True" testUniqueWebsites check "webTest-count" "True" testCount check "webTest-result" "True" testResult check name e c = do putStr ("*** " ++ name ++ ": ") if show c == e then putStrLn "OK" else putStrLn ("ERROR; expected '" ++ e ++ "', but found '" ++ show c ++ "'")