Skip to content

Instantly share code, notes, and snippets.

@raymonstah
Created September 17, 2015 22:58
Show Gist options
  • Save raymonstah/5dad886e5e348a1fc507 to your computer and use it in GitHub Desktop.
Save raymonstah/5dad886e5e348a1fc507 to your computer and use it in GitHub Desktop.
-- Raymond Ho
-- 99 Haskell problems from: https://wiki.haskell.org/99_questions/1_to_10
-- 9/17/2015
module NinetyNineProblems where
--1
myLast :: [a] -> a
myLast [] = error "No end for empty lists"
myLast [x] = x
myLast (_:xs) = myLast xs
--2
secondToLast :: [a] -> a
secondToLast [] = error "Empty list"
secondToLast [x] = error "Not enough elements"
secondToLast (x:xs) | length xs == 1 = x
| length xs > 1 = secondToLast xs
--3
elementAt' :: [a] -> Int -> a
elementAt' [] _ = error "Empty list or index out of bounds"
elementAt' (x:_) 1 = x
elementAt' (_:xs) a = elementAt' xs (a-1)
--4
myLength :: [a] -> Int
myLength [] = 0
myLength (x:xs) = 1 + myLength xs
--5
myReverse :: [a] -> [a]
myReverse [] = []
myReverse [x] = [x]
myReverse (x:xs) = [last xs] ++ myReverse ([x] ++ init xs)
--6
isPalindrome :: (Eq a) => [a] -> Bool
isPalindrome x = x == (reverse x)
--7
data NestedList a = Elem a | List [NestedList a]
myFlatten :: NestedList a -> [a]
myFlatten (Elem x) = [x]
myFlatten (List (x:xs)) = myFlatten x ++ myFlatten (List xs)
myFlatten (List []) = []
--8 (remove consecutive dupes)
compress :: (Eq a) => [a] -> [a]
compress [] = []
compress (x:xs) = x : (compress $ dropWhile (== x) xs)
--9
pack :: (Eq a) => [a] -> [[a]]
pack [] = []
pack (x:xs) = (x : takeWhile (== x) xs) : pack (dropWhile (== x) xs)
--10
encode :: (Eq a) => [a] -> [(Int, a)]
encode xs = [(length x, head x) | x <- pack xs]
--Raymond Ho 9/17/15
--Playing around with Hspec, Haskell, and testing..
module TestProblems where
import Test.Hspec
import Control.Exception (evaluate)
import NinetyNineProblems
main :: IO ()
main = hspec $ do
describe "myLast" $ do
it "returns the last element of the list" $ myLast [1,2,3,4] `shouldBe` 4
it "throws an error given an empty list" $ myLast [] `shouldThrow` anyException
describe "secondToLast" $ do
it "return the 2nd to last element of a list" $ secondToLast [1,2,3,4] `shouldBe` 3
it "throws specific error given a list with one element"
$ evaluate (secondToLast [1]) `shouldThrow` errorCall "Not enough elements"
it "throws an error given an empty list" $ secondToLast [] `shouldThrow` anyException
describe "elementAt'" $ do
it "given 1, it returns the first element of a list"
$ elementAt' [1,2,3,4,5] 1 `shouldBe` 1
it "given an empty list, throw error"
$ evaluate (elementAt' [] 1) `shouldThrow` errorCall "Empty list or index out of bounds"
it "given an index out of bounds, throw error"
$ evaluate (elementAt' [1,2,3] 10) `shouldThrow` errorCall "Empty list or index out of bounds"
describe "myLength" $ do
it "returns 10 given a list of 10 items" $ myLength [1..10] `shouldBe` 10
it "returns 0 given an empty list" $ myLength [] `shouldBe` 0
describe "myReverse" $ do
it "reverses a list" $ myReverse [100,99..0] `shouldBe` [0..100]
describe "isPalindrome" $ do
it "racecar should return true" $ isPalindrome "racecar" `shouldBe` True
describe "myFlatten" $ do
it "flattens a nested list: [1] => [1]" $ myFlatten (Elem 1) `shouldBe` [1]
it "flattens a nested list: [1, [2, [3,4], 5]]" $ do
myFlatten (List [Elem 1, List [Elem 2, List [Elem 3, Elem 4], Elem 5]]) == [1..5]
describe "compress" $ do
it "removes consecutive duplicates from a list" $ compress "hhhhheeeelllooo" `shouldBe` "helo"
describe "pack" $ do
it "puts repeated elements into their own sublists" $ pack [1,1,1,2,4,4] `shouldBe` [[1,1,1], [2], [4,4]]
describe "encode" $ do
it "run length encodes a list: [1,1,1] => [(3, 1)]" $ encode [1,1,1] `shouldBe` [(3,1)]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment