Skip to content

Instantly share code, notes, and snippets.

@rosechou
Forked from banacorn/Chapter-1-6.hs
Last active July 20, 2020 12:32
Show Gist options
  • Select an option

  • Save rosechou/fe2efd749d59086b624ac7d7e693fb65 to your computer and use it in GitHub Desktop.

Select an option

Save rosechou/fe2efd749d59086b624ac7d7e693fb65 to your computer and use it in GitHub Desktop.
-- This exercise covers the first 6 chapters of "Learn You a Haskell for Great Good!"
-- Chapter 1 - http://learnyouahaskell.com/introduction
-- Chapter 2 - http://learnyouahaskell.com/starting-out
-- Chapter 3 - http://learnyouahaskell.com/types-and-typeclasses
-- Chapter 4 - http://learnyouahaskell.com/syntax-in-functions
-- Chapter 5 - http://learnyouahaskell.com/recursion
-- Chapter 6 - http://learnyouahaskell.com/higher-order-functions
-- Download this file and then type ":l Chapter-1-6.hs" in GHCi to load this exercise
-- Some of the definitions are left "undefined", you should replace them with your answers.
import Data.List(sortOn)
-- Find the penultimate (second-to-last) element in list xs
penultimate xs = last (init xs)
-- Find the antepenultimate (third-to-last) element in list xs
-- to-do
antepenultimate xs = last (init (init xs))
-- Left shift list xs by 1
-- For example, "shiftLeft [1, 2, 3]" should return "[2, 3, 1]"
-- to-do
shiftLeft xs = (tail xs) ++ [head xs]
-- Left shift list xs by n
-- For example, "rotateLeft 2 [1, 2, 3]" should return "[3, 1, 2]"
-- to-do
rotateLeft 0 xs = xs
rotateLeft n (x:xs) = rotateLeft (n-1) xs ++ [x]
-- Insert element x in list xs at index k
-- For example, "insertElem 100 3 [0,0,0,0,0]" should return [0,0,0,100,0,0]
-- to-do
insertElem x 0 xs = x : xs
insertElem x k xs = [head xs] ++ insertElem x (k-1) (tail xs)
-- Here we have a type for the 7 days of the week
-- Try typeclass functions like "show" or "maxBound" on them
data Day = Mon | Tue | Wed | Thu | Fri | Sat | Sun
deriving (Eq, Ord, Show, Bounded, Enum)
-- Note that if you try "succ Sun", you should get an error, because "succ" is not defined on "Sun"
-- Define "next", which is like "succ", but returns "Mon" on "next Sun"
-- to-do
next :: Day -> Day
next Mon = Tue
next Tue = Wed
next Wed = Thu
next Thu = Fri
next Fri = Sat
next Sat = Sun
next Sun = Mon
-- Return "True" on weekend
-- to-do
isWeekend :: Day -> Bool
isWeekend Mon = False
isWeekend Tue = False
isWeekend Wed = False
isWeekend Thu = False
isWeekend Fri = False
isWeekend Sat = True
isWeekend Sun = True
data Task = Work | Shop | Play deriving (Eq, Show)
-- You are given a schedule, which is a list of pairs of Tasks and Days
schedule :: [(Task, Day)]
schedule = [(Shop, Fri), (Work, Tue), (Play, Mon), (Play, Fri)]
-- However, the schedule is a mess
-- Sort the schedule by Day, and return only a list of Tasks.
-- If there are many Tasks in a Day, you should keep its original ordering
-- For example, "sortTask schedule" should return "[(Play, Mon), (Work, Tue), (Shop, Fri), (Play, Fri)]"
sortTask :: [(Task, Day)] -> [Task]
sortTask = (map fst) . (sortOn snd)
-- sortTask :: [(Task, Day)] -> [Task]
-- -- to-do(return only a list of Tasks)
-- sortTask x = map (\(a,b)->a) (sortTask2 x)
-- sortTask2 :: [(Task, Day)] -> [(Task, Day)]
-- -- -- to-do
-- -- sortTask2 [] = []
-- sortTask2 [x] = [x]
-- sortTask2 (x:xs) = if (snd x) <= snd(head xs) then x:sortTask2 xs
-- else [head xs]++(sortTask2 ([x]++tail xs))
-- -- to-do(quicl sort verison)
-- -- sortTask2 :: [(Task, Day)] -> [(Task, Day)]
-- -- sortTask2 [] = []
-- -- sortTask2 [x] = [x]
-- -- sortTask2 (x:xs) =
-- -- let small = sortTask2 [z | z<-map (\(a,b)->(a,b))xs,y<-map (\(a,b)->b)xs, y<=(snd x)]
-- -- big = sortTask2 [z | z<-map (\(a,b)->(a,b))xs,y<-map (\(a,b)->b)xs, y>(snd x)]
-- -- in small++ [x] ++ big
-- This function converts days to names, like "show", but a bit fancier
-- For example, "nameOfDay Mon" should return "Monday"
-- to-do
nameOfDay :: Day -> String
nameOfDay Mon = "Monday"
nameOfDay Tue = "Tuesday"
nameOfDay Wed = "Wednesday"
nameOfDay Thu = "Thursday"
nameOfDay Fri = "Friday"
nameOfDay Sat = "Saturday"
nameOfDay Sun = "Sunday"
-- You shouldn't be working on the weekends
-- Return "False" if the Task is "Work" and the Day is "Sat" or "Sun"
-- to-do
labourCheck :: Task -> Day -> Bool
labourCheck task day = if (task==Work && (day==Sat || day ==Sun)) then False else True
-- Raise x to the power y using recursion
-- For example, "power 3 4" should return "81"
-- to-do
power :: Int -> Int -> Int
power x 0 = 1
power 0 y = 0
power x y = x*power x (y-1)
-- Convert a list of booleans (big-endian) to a interger using recursion
-- For example, "convertBinaryDigit [True, False, False]" should return 4
-- to-do
convertBinaryDigit :: [Bool] -> Int
convertBinaryDigit [] = 0
convertBinaryDigit x
|((last x) == True) = 1 + 2*convertBinaryDigit(init x)
|otherwise = 2*convertBinaryDigit(init x)
-- Create a fibbonaci sequence of length N in reverse order
-- For example, "fib 5" should return "[3, 2, 1, 1, 0]"
-- to-do
-- question: fib x = [(head fib(x-1))+(head fib(x-2))]++fib(x-1)
fib :: Int -> [Int]
fib 0 = []
fib 1 = [0]
fib 2 = [1,0]
fib x = [(fib(x-1)!!0)+(fib(x-2)!!0)]++fib(x-1)
-- Determine whether a given list is a palindrome
-- For example, "palindrome []" or "palindrome [1, 3, 1]" should return "True"
-- to-do
palindrome :: Eq a => [a] -> Bool
palindrome [] = True
palindrome [x] = True
palindrome xs = (head xs == last xs) && palindrome(init(tail xs))
-- Map the first component of a pair with the given function
-- For example, "mapFirst (+3) (4, True)" should return "(7, True)"
-- to-do
mapFirst :: (a -> b) -> (a, c) -> (b, c)
mapFirst f pair = (f(fst pair),snd pair)
-- Devise a function that has the following type
-- to-do
someFunction :: (a -> b -> c) -> (a -> b) -> a -> c
someFunction f g x = f x (g x)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment