Skip to content

Commit b5ba767

Browse files
committed
haskell-exercises W2
1 parent 36eeea5 commit b5ba767

1 file changed

Lines changed: 91 additions & 46 deletions

File tree

  • haskell/haskell-exercises

haskell/haskell-exercises/W2.hs

Lines changed: 91 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
module 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-
3635
measure :: [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-
4241
takeFinal :: 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-
5760
remove :: 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-
6567
substring :: 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-
8182
mymax :: (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-
9093
countSorted :: [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-
121124
quicksort :: [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-
135140
powers :: 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-
162167
fromTo :: 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-
169175
sums :: 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-
180191
mylast :: 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-
187199
sorted :: [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-
196209
sumsOf :: [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-
215227
mymaximum :: (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-
227247
map2 :: (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-
260281
interpreter :: [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-
270313
squares :: 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

Comments
 (0)