11module W2 where
22
3+ import Data.Char
4+
35-- Week 2:
46--
57-- * lists
@@ -21,27 +23,29 @@ module W2 where
2123--
2224-- Prelude> :t length
2325-- length :: [a] -> Int
24-
25- import Data.List
26- import Data.Char
26+ import Data.List
2727
2828-- Ex 1: Define the constant years, that is a list of the values 1982,
2929-- 2004 and 2012 in this order.
30-
31- years = undefined
30+ years :: [ Int ]
31+ years = [ 1982 , 2004 , 2012 ]
3232
3333-- Ex 2: define the function measure that for an empty list returns -1
3434-- and for other lists returns the length of the list.
35-
3635measure :: [String ] -> Int
37- measure ss = undefined
36+ measure [] = - 1
37+ measure ss = length ss
3838
3939-- Ex 3: define the function takeFinal, which returns the n last
4040-- elements of the given list.
41-
4241takeFinal :: Int -> [Int ] -> [Int ]
43- takeFinal n xs = undefined
42+ -- takeFinal n xs = takeFinal' (length xs - n) xs
43+ -- better way:
44+ takeFinal n xs = drop (length xs - n) xs
4445
46+ -- takeFinal' _ [] = []
47+ -- takeFinal' 0 xs = xs
48+ -- takeFinal' n (_:xs) = takeFinal' (n - 1) xs
4549-- Ex 4: remove the nth element of the given list. More precisely,
4650-- return a list that is identical to the given list except the nth
4751-- element is missing.
@@ -53,17 +57,15 @@ takeFinal n xs = undefined
5357-- remove 2 [4,5,6,7] ==> [4,5,7]
5458--
5559-- The [a] in the type signature means "a list of any type"
56-
5760remove :: Int -> [a ] -> [a ]
58- remove i xs = undefined
61+ remove i xs = take i xs ++ drop (i + 1 ) xs
5962
6063-- Ex 5: substring i n s should return the length n substring of s
6164-- starting at index i.
6265--
6366-- Remember that strings are lists!
64-
6567substring :: Int -> Int -> String -> String
66- substring i n s = undefined
68+ substring i n s = take n ( drop i s)
6769
6870-- Ex 6: implement the function mymax that takes as argument a
6971-- measuring function (of type a -> Int) and two values (of type a).
@@ -77,18 +79,21 @@ substring i n s = undefined
7779-- mymax (*2) 3 5 ==> 5
7880-- mymax length [1,2,3] [4,5] ==> [1,2,3]
7981-- mymax head [1,2,3] [4,5] ==> [4,5]
80-
8182mymax :: (a -> Int ) -> a -> a -> a
82- mymax measure a b = undefined
83+ mymax measure a b =
84+ if measure a > measure b
85+ then a
86+ else b
8387
8488-- Ex 7: countSorted receives a list of strings and returns a count of
8589-- how many of the strings are in alphabetical order (i.e. how many of
8690-- the strings have their letters in alphabetical order)
8791--
8892-- Remember the functions length, filter and sort
89-
9093countSorted :: [String ] -> Int
91- countSorted ss = undefined
94+ countSorted ss = length $ filter sorted ss
95+ where
96+ sorted s = s == sort s
9297
9398-- Ex 8: Implement a function funny, that
9499-- - takes in a list of strings
@@ -101,9 +106,8 @@ countSorted ss = undefined
101106-- These functions will help:
102107-- - toUpper :: Char -> Char from the module Data.Char
103108-- - intercalate from the module Data.List
104-
105- funny :: [String ] -> String
106- funny strings = undefined
109+ -- funny :: [String] -> String
110+ funny = map toUpper . unwords . filter ((> 5 ) . length )
107111
108112-- Ex 9: implement quicksort. Quicksort is a recursive sorting
109113-- algorithm that works like this.
@@ -117,9 +121,11 @@ funny strings = undefined
117121-- are combined into one sorted list
118122--
119123-- PS. yes if you want to nit-pick this isn't really quicksort :)
120-
121124quicksort :: [Int ] -> [Int ]
122- quicksort xs = undefined
125+ quicksort [] = []
126+ quicksort (x: xs) = quicksort (fst parts) ++ [x] ++ quicksort (snd parts)
127+ where
128+ parts = partition (< x) xs
123129
124130-- Ex 10: powers k max should return all the powers of k that are less
125131-- than or equal to max. For example:
@@ -131,9 +137,8 @@ quicksort xs = undefined
131137-- Hints:
132138-- * n^max > max
133139-- * the function takeWhile
134-
135140powers :: Int -> Int -> [Int ]
136- powers n max = undefined
141+ powers n max = takeWhile ( <= max ) $ map ( \ i -> n ^ i) [ 0 .. ]
137142
138143-- Ex 11: implement a search function that takes an updating function,
139144-- a checking function and an initial value. Search should repeatedly
@@ -152,22 +157,29 @@ powers n max = undefined
152157-- check _ = False
153158-- in search tail check "xyzAvvt"
154159-- ==> Avvt
155-
156- search :: (a -> a ) -> (a -> Bool ) -> a -> a
157- search update check initial = undefined
160+ search :: (a -> a ) -> (a -> Bool ) -> a -> a
161+ search update check initial
162+ | check initial = initial
163+ | otherwise = search update check $ update initial
158164
159165-- Ex 12: given numbers n and k, build the list of numbers n,n+1..k.
160166-- Use recursion and the : operator to build the list.
161-
162167fromTo :: Int -> Int -> [Int ]
163- fromTo n k = undefined
168+ fromTo n k
169+ | n > k = []
170+ | otherwise = n : fromTo (n + 1 ) k
164171
165172-- Ex 13: given i, build the list of sums [1, 1+2, 1+2+3, .., 1+2+..+i]
166173--
167174-- Ps. you'll probably need a recursive helper function
168-
169175sums :: Int -> [Int ]
170- sums i = undefined
176+ sums i = sums' i 0 1
177+
178+ sums' n t i
179+ | i > n = []
180+ | otherwise = u : sums' n u (i + 1 )
181+ where
182+ u = t + i
171183
172184-- Ex 14: using list pattern matching and recursion, define a function
173185-- mylast that returns the last value of the given list. For an empty
@@ -176,25 +188,26 @@ sums i = undefined
176188-- Examples:
177189-- mylast 0 [] ==> 0
178190-- mylast 0 [1,2,3] ==> 3
179-
180191mylast :: a -> [a ] -> a
181- mylast def xs = undefined
192+ mylast def [] = def
193+ mylast _ [x] = x
194+ mylast def (_: xs) = mylast def xs
182195
183196-- Ex 15: define a function that checks if the given list is in
184197-- increasing order. Use recursion and pattern matching. Don't use any
185198-- library list functions.
186-
187199sorted :: [Int ] -> Bool
188- sorted xs = undefined
200+ sorted [] = True
201+ sorted [x] = True
202+ sorted (x: y: xs) = (x <= y) && sorted (y : xs)
189203
190204-- Ex 16: compute the partial sums of the given list like this:
191205--
192206-- sumsOf [a,b,c] ==> [a,a+b,a+b+c]
193207-- sumsOf [a,b] ==> [a,a+b]
194208-- sumsOf [] ==> []
195-
196209sumsOf :: [Int ] -> [Int ]
197- sumsOf xs = undefined
210+ sumsOf xs = map ( sum . ( `take` xs)) [ 1 .. ( length xs)]
198211
199212-- Ex 17: define the function mymaximum that takes a list and a
200213-- comparing function of type a -> a -> Ordering and returns the
@@ -211,9 +224,17 @@ sumsOf xs = undefined
211224-- comp x y = compare x y
212225-- in mymaximum comp 1 [1,4,6,100,0,3]
213226-- ==> 0
214-
215227mymaximum :: (a -> a -> Ordering ) -> a -> [a ] -> a
216- mymaximum cmp def xs = undefined
228+ mymaximum _ def [] = def
229+ mymaximum cmp def (x: xs) = mymaximum' cmp x xs
230+
231+ mymaximum' _ currMax [] = currMax
232+ mymaximum' cmp currMax (x: xs) = mymaximum' cmp newMax xs
233+ where
234+ newMax =
235+ if cmp currMax x == LT
236+ then x
237+ else currMax
217238
218239-- Ex 18: define a version of map that takes a two-argument function
219240-- and two lists. Example:
@@ -223,9 +244,10 @@ mymaximum cmp def xs = undefined
223244--
224245-- Ps. this function is in the Haskell Prelude but under a different
225246-- name.
226-
227247map2 :: (a -> b -> c ) -> [a ] -> [b ] -> [c ]
228- map2 f as bs = undefined
248+ map2 _ [] _ = []
249+ map2 _ _ [] = []
250+ map2 f (a: as) (b: bs) = f a b : map2 f as bs
229251
230252-- Ex 19: in this exercise you get to implement an interpreter for a
231253-- simple language. The language controls two counters, A and B, and
@@ -256,16 +278,39 @@ map2 f as bs = undefined
256278--
257279-- Unfortunately the surprise might not work if you've implemented
258280-- your interpreter correctly but weirdly :(
259-
260281interpreter :: [String ] -> [String ]
261- interpreter commands = undefined
262-
282+ interpreter = interpreter' 0 0
283+ where
284+ interpreter' _ _ [] = []
285+ interpreter' a b (command: commands) =
286+ case command of
287+ " incA" -> interpreter' (a + 1 ) b commands
288+ " incB" -> interpreter' a (b + 1 ) commands
289+ " decA" -> interpreter' (a - 1 ) b commands
290+ " decB" -> interpreter' a (b - 1 ) commands
291+ " printA" -> show a : interpreter' a b commands
292+ " printB" -> show b : interpreter' a b commands
293+ _ -> " BAD!" : interpreter' a b commands
294+
295+ -- interpreter = go 0 0
296+ -- where
297+ -- go a b ("incA":commands) = go (a + 1) b commands
298+ -- go a b ("decA":commands) = go (a - 1) b commands
299+ -- go a b ("incB":commands) = go a (b + 1) commands
300+ -- go a b ("decB":commands) = go a (b - 1) commands
301+ -- go a b ("printA":commands) = show a : go a b commands
302+ -- go a b ("printB":commands) = show b : go a b commands
303+ -- go a b [] = []
304+ -- go a b (_:commands) = "BAD" : go a b commands
305+ --
306+ --
263307-- Ex 20: write a function that finds the n first squares (numbers of
264308-- the form x*x) that start and end with the same digit.
265309--
266310-- Example: squares 9 ==> [1,4,9,121,484,676,1521,1681,4624]
267311--
268312-- Remember, the function show transforms a number to a string.
269-
270313squares :: Int -> [Integer ]
271- squares n = undefined
314+ squares n = (take n . filter sameFirstLastDigit . map (^ 2 )) [1 .. ]
315+ where
316+ sameFirstLastDigit x = head (show x) == last (show x)
0 commit comments