module Problems ( myLast, lastTwo, kth, myLength, rev, isPalindrome, flatten, NestedList(..), compress, pack, encode ) where -- H99: Ninety-Nine Haskell Problems -- https://wiki.haskell.org/H-99:_Ninety-Nine_Haskell_Problems -- Find the last element of a list. myLast :: [t] -> Maybe t myLast [] = Nothing myLast [x] = Just x myLast (x:xs) = myLast xs -- Find the last but one element of a list. lastTwo :: [t] -> Maybe (t, t) lastTwo [] = Nothing lastTwo [x] = Nothing lastTwo [x, y] = Just(x, y) lastTwo (x:y:xs) = lastTwo xs -- Find the K'th element of a list. The first element in the list is number 1. kth :: [t] -> Int -> Maybe t kth [] _ = Nothing kth (x:xs) n = if n == 0 then Just x else kth xs (n - 1) -- Find the number of elements of a list. myLength :: [t] -> Int myLength [] = 0 --myLength (_:xs) = 1 + myLength xs myLength (_:xs) = subMyLength xs 0 + 1 where subMyLength :: [t] -> Int -> Int subMyLength [] n = n subMyLength (_:ys) n = subMyLength ys (n + 1) -- Reverse a list rev :: [t] -> [t] rev [] = [] rev (x:xs) = rev xs ++ [x] -- Palindrome isPalindrome :: (Eq t) => [t] -> Bool isPalindrome [] = True --isPalindrome (x:xs) = (x == y) && equal_list xs ys -- where -- equal_list :: [t] -> [t] -> Bool -- equal_list [] [] = True -- equal_list (x1:x1s) (y1:y1s) = (x1 == y1) && equal_list x1s y1s -- (y:ys) = rev (x:xs) isPalindrome (x:xs) = (x == y) && (xs == ys) where (y:ys) = rev (x:xs) -- Flatten a list data NestedList a = Elem a | List [NestedList a] flatten :: NestedList a -> [a] flatten (List []) = [] flatten (Elem a) = [a] flatten (List (x:xs)) = flatten x ++ flatten (List xs) -- Eliminate consecutive duplicates of list elements. -- compress :: (Eq t) => [t] -> [t] -- compress [] = [] -- compress [x] = [x] -- compress (x:xs) = x : unique x xs -- where -- unique :: (Eq t) => t -> [t] -> [t] -- unique _ [] = [] -- unique x (y:ys) = if x == y then unique y ys else y : unique y ys compress :: (Eq t) => [t] -> [t] compress (x:ys@(y:_)) = if x == y then compress ys else x : compress ys compress x = x -- Pack consecutive duplicates of list elements into sublists. -- If a list contains repeated elements they should be placed in separate sublists. --pack :: (Eq t) => [t] -> [[t]] --pack [] = [[]] --pack [x] = [[x]] --pack (x:y:xs) -- | x == y = [x,y] : pack xs -- | otherwise = [x] : [y] : pack xs pack :: (Eq t) => [t] -> [[t]] pack [] = [] pack (x:xs) = (x:first) : pack rest where getReps [] = ([], []) getReps (y:ys) | y == x = let (f, r) = getReps ys in (y:f, r) | otherwise = ([], y:ys) (first, rest) = getReps xs -- Run-length encoding of a list. -- Use the result of problem P09 to implement the so-called run-length encoding data compression method. -- Consecutive duplicates of elements are encoded as lists (N E) where N is the number of duplicates of the element E. encode :: (Eq t) => [t] -> [(Int, t)] encode [] = [] -- encode (x:xs) = [(n,e) | ] -- where -- y:ys = pack (x:xs)