From d4b5cde4dad18d61979fcff886b2caf23d3ff9af Mon Sep 17 00:00:00 2001 From: Syndamia Date: Sun, 25 Oct 2020 14:10:19 +0200 Subject: Did set 2b and part of set 3a from the mooc haskell exercises --- Haskell/mooc-exercises.hs | 136 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 135 insertions(+), 1 deletion(-) (limited to 'Haskell') diff --git a/Haskell/mooc-exercises.hs b/Haskell/mooc-exercises.hs index 879ec8f..77e49d9 100644 --- a/Haskell/mooc-exercises.hs +++ b/Haskell/mooc-exercises.hs @@ -1,6 +1,8 @@ -- This are my solutions to the exercises from https://github.com/moocfi/haskell-mooc import Data.List +import Data.Char +import Data.Either --------- -- Set.01 @@ -80,6 +82,7 @@ ilog3 n = 1 + ilog3 (div n 3) -- https://github.com/moocfi/haskell-mooc/blob/master/exercises/Set2a.hs -- Functions you'll need: head, tail, take, drop, length, null +-- Can only use Data.List -- Ex. 1 @@ -135,7 +138,7 @@ safeIndex xs i = if 0 > i || i >= length xs then Nothing -- Ex. 10 -eitherDiv :: Int -> Int -> Either String Int -- a value can be the left one or the right one (specified when given) +eitherDiv :: Int -> Int -> Either String Int -- a value type can be the left one or the right one (specified when given) eitherDiv x 0 = Left (show x ++ "/0") eitherDiv x y = Right (div x y) @@ -145,3 +148,134 @@ addEithers :: Either String Int -> Either String Int -> Either String Int addEithers (Right x) (Right y) = Right (x + y) addEithers (Right x) (Left y) = Left y addEithers (Left x) (Right y) = Left x + +---------- +-- Set.02b +-- https://github.com/moocfi/haskell-mooc/blob/master/exercises/Set2b.hs + +-- Ex. 1 + +binomial :: Int -> Int -> Int +binomial n 0 = 1 +binomial 0 k + | k > 0 = 0 + | otherwise = (-1) +binomial n k = binomial (n - 1) k + binomial (n - 1) (k - 1) + +-- Ex. 2 + +oddFactorial :: Int -> Int +oddFactorial 1 = 1 -- technically having a pattern match for 3 is more efficient +oddFactorial n + |even n = oddFactorial (n - 1) + |otherwise = n * oddFactorial (n - 2) + +-- Ex. 3 + +myGcd :: Int -> Int -> Int +myGcd 0 b = b +myGcd a 0 = a +myGcd a b + | a > b = myGcd (a - b) b + | otherwise = myGcd a (b - a) + +-- Ex. 4 + +leftpad :: String -> Int -> String +leftpad s a = if length s >= a then s + else leftpad (" " ++ s) a + +-- Ex. 5 + +countdown :: Int -> String +countdown n = "Ready! " ++ count n ++ "Liftoff!" + +count :: Int -> String -- recursive helper function +count 0 = "" +count n = show n ++ "... " ++ count (n - 1) + +-- Ex. 6 + +smallestDivisor :: Int -> Int +smallestDivisor n = smallest n 2 + +smallest :: Int -> Int -> Int +smallest n k = if mod n k == 0 then k + else smallest n (k + 1) + +-- Ex. 7 + +isPrime :: Int -> Bool +isPrime 1 = False +isPrime n = smallestDivisor n == n + +-- Ex. 8 + +biggestPrimeAtMost :: Int -> Int +biggestPrimeAtMost n = if isPrime n then n + else biggestPrimeAtMost (n - 1) + +---------- +-- Set.03a +-- https://github.com/moocfi/haskell-mooc/blob/master/exercises/Set3a.hs + +-- Can only use Data.List, Data.Either, Data.Char + +-- Ex. 1 + +maxBy :: (a -> Int) -> a -> a -> a +maxBy measure a b = if (measure a) > (measure b) then a else b + +-- Ex. 2 + +mapMaybe :: (a -> b) -> Maybe a -> Maybe b +mapMaybe f Nothing = Nothing +mapMaybe f (Just a) = Just (f a) + +-- Ex. 3 + +mapMaybe2 :: (a -> b -> c) -> Maybe a -> Maybe b -> Maybe c +mapMaybe2 f (Just a) Nothing = Nothing +mapMaybe2 f Nothing (Just b) = Nothing +mapMaybe2 f (Just a) (Just b) = Just (f a b) + +-- Ex. 4 + +palindromeHalfs :: [String] -> [String] +palindromeHalfs xs = map firstHalf (filter palindrome xs) + +firstHalf :: String -> String +-- div rounds down to negative infinity, meaning 2.5 will be rounded down to 2 and -2.5 to -3 +-- using this feature, we can round up a division of integers by one of them being negative and taking the absolute result +firstHalf s = take (abs (div (length s) (-2))) s + +palindrome :: String -> Bool +palindrome s = s == reverse s + +-- Ex. 5 + +capitalize :: String -> String +capitalize s = unwords (map capitlizeFirst (words s)) + where capitlizeFirst s = [toUpper (head s)] ++ tail s -- helper function, only available in capitalize + +-- Ex. 6 + +powers :: Int -> Int -> [Int] +powers k max = filter (<=max) (map (\x -> k ^ x) [0..max]) + +-- Ex. 7 + +while :: (a -> Bool) -> (a -> a) -> a -> a +while check update value = if check value then while check update (update value) + else value + +-- Ex. 8 + +whileRight :: (a -> Either b a) -> a -> b +whileRight f x = either (\y -> y) (\y -> whileRight f y) (f x) + +step :: Int -> Int -> Either Int Int -- function for testing +step k x = if x < k then Right (2*x) else Left x + +-- Ex. 9 + -- cgit v1.2.3