aboutsummaryrefslogtreecommitdiff
path: root/Haskell
diff options
context:
space:
mode:
authorSyndamia <kamen.d.mladenov@protonmail.com>2020-10-25 14:10:19 +0200
committerSyndamia <kamen.d.mladenov@protonmail.com>2020-10-25 14:10:19 +0200
commitd4b5cde4dad18d61979fcff886b2caf23d3ff9af (patch)
tree58b278125a854e4ff6d2727361bff1aba23d1965 /Haskell
parentcd18e9959869c17697168ed8cfd43b31a16cc913 (diff)
downloadSelf-learning-d4b5cde4dad18d61979fcff886b2caf23d3ff9af.tar
Self-learning-d4b5cde4dad18d61979fcff886b2caf23d3ff9af.tar.gz
Self-learning-d4b5cde4dad18d61979fcff886b2caf23d3ff9af.zip
Did set 2b and part of set 3a from the mooc haskell exercises
Diffstat (limited to 'Haskell')
-rw-r--r--Haskell/mooc-exercises.hs136
1 files changed, 135 insertions, 1 deletions
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
+