forked from opqdonut/ifp2018-exercises
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathW2.hs
282 lines (240 loc) · 7.75 KB
/
W2.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
module W2 where
-- Week 2:
--
-- * lists
-- * strings
-- * library functions for them
-- * higher order functions
-- * polymorphism
--
-- Functions you will need:
-- * head, tail
-- * take, drop
-- * length
-- * null
-- * map
-- * filter
--
-- You can ask ghci for the types of these functions with the :t
-- command:
--
-- Prelude> :t head
-- head :: [a] -> a
-- Some imports you'll need.
-- Do not add any other imports! :)
import Data.List
import Data.Char
-- Ex 1: Define the constant years, that is a list of the values 1982,
-- 2004 and 2012 in this order.
years = undefined
-- Ex 2: define the function measure that for an empty list returns -1
-- and for other lists returns the length of the list.
measure :: [String] -> Int
measure ss = undefined
-- Ex 3: define the function takeFinal, which returns the n last
-- elements of the given list.
--
-- If the list is shorter than n, return all elements.
takeFinal :: Int -> [Int] -> [Int]
takeFinal n xs = undefined
-- Ex 4: remove the nth element of the given list. More precisely,
-- return a list that is identical to the given list except the nth
-- element is missing.
--
-- Note! indexing starts from 0
--
-- Examples:
-- remove 0 [1,2,3] ==> [2,3]
-- remove 2 [4,5,6,7] ==> [4,5,7]
--
-- The [a] in the type signature means "a list of any type"
remove :: Int -> [a] -> [a]
remove i xs = undefined
-- Ex 5: substring i n s should return the length n substring of s
-- starting at index i.
--
-- Remember that strings are lists!
substring :: Int -> Int -> String -> String
substring i n s = undefined
-- Ex 6: implement the function mymax that takes as argument a
-- measuring function (of type a -> Int) and two values (of type a).
--
-- mymax should apply the measuring function to both arguments and
-- return the argument for which the measuring function returns a
-- higher value.
--
-- Examples:
--
-- mymax (*2) 3 5 ==> 5
-- mymax length [1,2,3] [4,5] ==> [1,2,3]
-- mymax head [1,2,3] [4,5] ==> [4,5]
mymax :: (a -> Int) -> a -> a -> a
mymax measure a b = undefined
-- Ex 7: countPalindromes receives a list of strings and returns a
-- count of how many of the strings are palindromes (i.e. how many
-- strings are the same when reversed)
--
-- Remember the functions length, filter and reverse
countPalindromes :: [String] -> Int
countPalindromes ss = undefined
-- Ex 8: Implement a function funny, that
-- - takes in a list of strings
-- - returns a string
-- - that contains all input words of length over 5
-- - ... combined into one string
-- - ... separated with spaces
-- - ... and converted to upper case!
--
-- These functions will help:
-- - toUpper :: Char -> Char from the module Data.Char
-- - intercalate from the module Data.List
--
-- Example:
-- funny ["boing","functional","foo","haskell"] ==> "FUNCTIONAL HASKELL"
funny :: [String] -> String
funny strings = undefined
-- Ex 9: powers k max should return all the powers of k that are less
-- than or equal to max. For example:
--
-- powers 2 5 ==> [1,2,4]
-- powers 3 30 ==> [1,3,9,27]
-- powers 2 2 ==> [1,2]
--
-- Hints:
-- * n^max > max
-- * the function takeWhile
powers :: Int -> Int -> [Int]
powers n max = undefined
-- Ex 10: implement a search function that takes an updating function,
-- a checking function and an initial value. Search should repeatedly
-- apply the updating function to the initial value until a value is
-- produced that passes the checking function. This value is then
-- returned.
--
-- Examples:
--
-- search (+1) even 0 ==> 0
--
-- search (+1) (>4) 0 ==> 5
--
-- let check [] = True
-- check ('A':xs) = True
-- check _ = False
-- in search tail check "xyzAvvt"
-- ==> Avvt
search :: (a->a) -> (a->Bool) -> a -> a
search update check initial = undefined
-- Ex 11: given numbers n and k, build the list of numbers n,n+1..k.
-- Use recursion and the : operator to build the list.
fromTo :: Int -> Int -> [Int]
fromTo n k = undefined
-- Ex 12: given i, build the list of sums [1, 1+2, 1+2+3, .., 1+2+..+i]
--
-- Ps. you'll probably need a recursive helper function
sums :: Int -> [Int]
sums i = undefined
-- Ex 13: using list pattern matching and recursion, define a function
-- mylast that returns the last value of the given list. For an empty
-- list, a provided default value is returned.
--
-- Examples:
-- mylast 0 [] ==> 0
-- mylast 0 [1,2,3] ==> 3
mylast :: a -> [a] -> a
mylast def xs = undefined
-- Ex 14: define a function that checks if the given list is in
-- increasing order. Use recursion and pattern matching. Don't use any
-- library list functions.
sorted :: [Int] -> Bool
sorted xs = undefined
-- Ex 15: compute the partial sums of the given list like this:
--
-- sumsOf [a,b,c] ==> [a,a+b,a+b+c]
-- sumsOf [a,b] ==> [a,a+b]
-- sumsOf [] ==> []
sumsOf :: [Int] -> [Int]
sumsOf xs = undefined
-- Ex 16: implement the function merge that merges two sorted lists of
-- Ints into a sorted list
--
-- Use only recursion, pattern matching and the list constructors
-- (: and []). Do not use any other list functions.
--
-- Examples:
-- merge [1,3,5] [2,4,6] ==> [1,2,3,4,5,6]
-- merge [1,1,6] [1,2] ==> [1,1,1,2,6]
merge :: [Int] -> [Int] -> [Int]
merge xs ys = undefined
-- Ex 17: using the merge function you just defined, implement mergesort
--
-- Mergesort is a sorting algorithm that splits the input list in
-- half, sorts the halves recursively using mergesort, and then merges
-- the halves back together.
--
-- You will probably need two base cases for the recursion. I've
-- filled them in for you already.
--
-- Example:
-- mergesort [4,1,3,2] ==> [1,2,3,4]
mergesort :: [Int] -> [Int]
mergesort [] = []
mergesort [x] = [x]
mergesort xs = undefined
-- Ex 18: define the function mymaximum that takes a list and a
-- comparing function of type a -> a -> Ordering and returns the
-- maximum value of the list, according to the comparing function.
--
-- For an empty list the given default value is returned.
--
-- Examples:
-- mymaximum compare (-1) [] ==> -1
-- mymaximum compare (-1) [1,3,2] ==> 3
-- let comp 0 0 = EQ
-- comp _ 0 = LT
-- comp 0 _ = GT
-- comp x y = compare x y
-- in mymaximum comp 1 [1,4,6,100,0,3]
-- ==> 0
mymaximum :: (a -> a -> Ordering) -> a -> [a] -> a
mymaximum cmp def xs = undefined
-- Ex 19: define a version of map that takes a two-argument function
-- and two lists. Example:
-- map2 f [x,y,z,w] [a,b,c] ==> [f x a, f y b, f z c]
--
-- Use recursion and pattern matching. Do not use any library functions.
--
-- Ps. this function is in the Haskell Prelude but under a different
-- name.
map2 :: (a -> b -> c) -> [a] -> [b] -> [c]
map2 f as bs = undefined
-- Ex 20: in this exercise you get to implement an interpreter for a
-- simple language. You should keep track of the x and y coordinates,
-- and interpret the following commands:
--
-- up -- increment y by one
-- down -- decrement y by one
-- left -- decrement x by one
-- right -- increment x by one
-- printX -- print value of x
-- printY -- print value of y
--
-- The interpreter will be a function of type [String] -> [String].
-- Its input is a list of commands, and its output is a list of the
-- results of the print commands in the input.
--
-- Both coordinates start at 0.
--
-- Examples:
--
-- interpreter ["up","up","up","printY","down","printY"] ==> ["3","2"]
-- interpreter ["up","right","right","printY","printX"] ==> ["1","2"]
--
-- Surprise! after you've implemented the function, try running this in GHCi:
-- interact (unlines . interpreter . lines)
-- after this you can enter commands on separate lines and see the
-- responses to them
--
-- Unfortunately the surprise might not work if you've implemented
-- your interpreter correctly but weirdly :(
interpreter :: [String] -> [String]
interpreter commands = undefined