-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlists.hs
247 lines (190 loc) · 5.81 KB
/
lists.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
-- Problem 1
-- Find the last element of a list
myLast :: [a] -> a
myLast (x:xs)
| length xs == 0 = x
| otherwise = myLast xs
-- Problem 2
-- Find the last but one element of a list.
myButLast :: [a] -> a
myButLast (x:xs)
| length xs == 1 = x
| otherwise = myButLast xs
-- Problem 3
-- Find the K'th element of a list. The first element in the list is number 1.
elementAt :: [a] -> Int -> a
elementAt (x:xs) n
| n > length (x:xs) = error "Number is bigger than list"
| n == 1 = x
| otherwise = elementAt xs (n-1)
-- Problem 4
-- Find the number of elements of a list
myLength :: [a] -> Int
myLength [] = 0
myLength (_:xs) = 1 + myLength xs
-- Problem 5
-- Reverse a list
myReverse :: [a] -> [a]
myReverse [] = []
myReverse (x:xs) = myReverse xs ++ [x]
-- Problem 6
-- Find out whether a list is a palindrome. A palindrome can be read forward or backward; e.g. (x a m a x).
isPalindrome :: Eq a => [a] -> Bool
isPalindrome [] = False
isPalindrome xs
| xs == reverse xs = True
| otherwise = False
-- Problem 7
{--
(**) Flatten a nested list structure.
Transform a list, possibly holding lists as elements into a `flat'
list by replacing each list with its elements (recursively).
--}
data NestedList a = Elem a | List [NestedList a]
flatten :: NestedList a -> [a]
flatten (Elem x) = [x]
flatten (List x) = concatMap flatten x
-- Problem 8
{--
(**) Eliminate consecutive duplicates of list elements.
If a list contains repeated elements they should be
replaced with a single copy of the element.
The order of the elements should not be changed.
--}
compress :: Eq a => [a] -> [a]
compress [] = []
compress (x:xs)
| x `elem` xs = compress xs
| otherwise = [x] ++ compress xs
-- Problem 9
{--
(**) Pack consecutive duplicates of list elements into
sublists. If a list contains repeated elements they should
be placed in separate sublists.
--}
pack :: (Eq a) => [a] -> [[a]]
pack [] = []
pack (x:xs) = (x : takeWhile (==x) xs) : pack (dropWhile (==x) xs)
-- Problem 10
{--
(*) 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 a => [a] -> [(Int, a)]
encode [] = []
encode xs = [(length x, head x) | x <- pack xs]
-- Problem 11
{--
(*) Modified run-length encoding.
Modify the result of problem 10 in such a way that if an
element has no duplicates it is simply copied into the
result list. Only elements with duplicates are transferred
as (N E) lists.
--}
data MultipleList a = Single a | Multiple Int a deriving (Show)
encodeModified :: Eq a => [a] -> [MultipleList a]
encodeModified = map transform . encode
where transform (1,a) = Single a
transform (n,a) = Multiple n a
-- Problem 12
{--
**) Decode a run-length encoded list.
Given a run-length code list generated as specified in problem 11.
Construct its uncompressed version.
--}
decodeModified :: Eq a => [MultipleList a] -> [a]
decodeModified [] = []
decodeModified (Multiple n c:xs) = replicate n c ++ decodeModified xs
decodeModified (Single a:xs) = a : decodeModified xs
-- Problem 13
{--
(**) Run-length encoding of a list (direct solution).
Implement the so-called run-length encoding data compression
method directly. I.e. don't explicitly create the sublists containing
the duplicates, as in problem 9, but only count them.
As in problem P11, simplify the result list by replacing the singleton lists (1 X) by X.
--}
-- not done yet
-- Problem 14
{--
(*) Duplicate the elements of a list
--}
dupli :: [a] -> [a]
dupli [] = []
dupli (x:xs) = replicate 2 x ++ dupli xs
-- Problem 15
{--
(**) Replicate the elements of a list a given number of times.
--}
repli :: [a] -> Int -> [a]
repli [] _ = []
repli (x:xs) n = replicate n x ++ repli xs n
-- Problem 16
{--
(**) Drop every N'th element from a list.
--}
dropEvery :: Eq a => [a] -> Int -> [a]
dropEvery [] _ = []
dropEvery (_:xs) 1 = xs
dropEvery (x:xs) n = [x] ++ dropEvery xs (n-1)
-- Problem 17
{--
(*) Split a list into two parts; the length of the first part is given.
--}
split :: [a] -> Int -> ([a],[a])
split xs n = (take n xs, drop n xs)
-- Problem 18
{--
(**) Extract a slice from a list.
Given two indices, i and k, the slice is the list containing the
elements between the i'th and k'th element of the original
list (both limits included). Start counting the elements with 1.
--}
slice :: [a] -> Int -> Int -> [a]
slice [] _ _ = []
slice xs l r = take (r-l+1) $ drop (l-1) xs
-- Problem 19
{--
(**) Rotate a list N places to the left.
Hint: Use the predefined functions length and (++).
--}
rotate :: Eq a => [a] -> Int -> [a]
rotate [] _ = []
rotate xs n
| n > 0 = drop n xs ++ take n xs
| otherwise = drop negative xs ++ take negative xs
where negative = ((length xs)-(-1*n))
-- Problem 20
{--
(*) Remove the K'th element from a list.
--}
removeAt :: Eq a => Int -> [a] -> (a,[a])
removeAt n xs = (choosen,filter (/=choosen) xs)
where choosen = xs !! (n-1)
-- Problem 21
{--
Insert an element at a given position into a list.
--}
insertAt :: Eq a => a -> [a] -> Int -> [a]
insertAt _ [] _ = []
insertAt value (x:xs) n
| n == 1 = [value] ++ [x] ++ xs
| otherwise = [x] ++ insertAt value xs (n-1)
-- Problem 22
{--
Create a list containing all integers within a given range.
--}
range :: Int -> Int -> [Int]
range x y = [x..y]
-- Problem 23
{--
Extract a given number of randomly selected elements from a list.
--}
-- Not implemented yet
-- Problem 24
{--
Lotto: Draw N different random numbers from the set 1..M.
--}
-- Not implemented yet