-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathchristia_hw1.hs
292 lines (242 loc) · 5.8 KB
/
christia_hw1.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
283
284
285
286
287
288
289
290
291
292
module HW1 where
--
-- * Name: Arpit Christi
-- * id: christia
-- * Completion: All problems completed.
-- * email: [email protected]
-- * collaboration: none
-- * online resources used: none
-- * Part 1: Binary trees
--
-- | Integer-labeled binary trees.
data Tree = Node Int Tree Tree -- ^ Internal nodes
| Leaf Int -- ^ Leaf nodes
deriving (Eq,Show)
-- | An example binary tree, which will be used in tests.
t1 :: Tree
t1 = Node 1 (Node 2 (Node 3 (Leaf 4) (Leaf 5))
(Leaf 6))
(Node 7 (Leaf 8) (Leaf 9))
-- | Another example binary tree, used in tests.
t2 :: Tree
t2 = Node 6 (Node 2 (Leaf 1) (Node 4 (Leaf 3) (Leaf 5)))
(Node 8 (Leaf 7) (Leaf 9))
-- | The integer at the left-most node of a binary tree.
--
-- >>> leftmost (Leaf 3)
-- 3
--
-- >>> leftmost (Node 5 (Leaf 6) (Leaf 7))
-- 6
--
-- >>> leftmost t1
-- 4
--
-- >>> leftmost t2
-- 1
--
leftmost :: Tree -> Int
leftmost (Leaf i) = i
leftmost (Node _ l _) = leftmost l
-- | The integer at the right-most node of a binary tree.
--
-- >>> rightmost (Leaf 3)
-- 3
--
-- >>> rightmost (Node 5 (Leaf 6) (Leaf 7))
-- 7
--
-- >>> rightmost t1
-- 9
--
-- >>> rightmost t2
-- 9
--
rightmost :: Tree -> Int
rightmost (Leaf i) = i
rightmost (Node _ _ r) = rightmost r
-- | Get the maximum integer from a binary tree.
--
-- >>> maxInt (Leaf 3)
-- 3
--
-- >>> maxInt (Node 5 (Leaf 4) (Leaf 2))
-- 5
--
-- >>> maxInt (Node 5 (Leaf 7) (Leaf 2))
-- 7
--
-- >>> maxInt t1
-- 9
--
-- >>> maxInt t2
-- 9
--
maxTwo :: Int -> Int -> Int
maxTwo a b | a >= b = a
| otherwise = b
maxThree :: Int -> Int -> Int -> Int
maxThree a b c | a >= maxTwo b c = a
| otherwise = maxTwo b c
maxInt :: Tree -> Int
maxInt (Leaf i) = i
maxInt ( Node i l r) = maxThree i (maxInt l) (maxInt r)
-- | Get the minimum integer from a binary tree.
--
-- >>> minInt (Leaf 3)
-- 3
--
-- >>> minInt (Node 2 (Leaf 5) (Leaf 4))
-- 2
--
-- >>> minInt (Node 5 (Leaf 4) (Leaf 7))
-- 4
--
-- >>> minInt t1
-- 1
--
-- >>> minInt t2
-- 1
--
minTwo :: Int -> Int -> Int
minTwo a b | a <= b = a
| otherwise = b
minThree :: Int -> Int -> Int -> Int
minThree a b c | a <= minTwo b c = a
| otherwise = minTwo b c
minInt :: Tree -> Int
minInt (Leaf i) = i
minInt (Node i l r) = minThree i (minInt l) (minInt r)
-- | Get the sum of the integers in a binary tree.
--
-- >>> sumInts (Leaf 3)
-- 3
--
-- >>> sumInts (Node 2 (Leaf 5) (Leaf 4))
-- 11
--
-- >>> sumInts t1
-- 45
--
-- >>> sumInts (Node 10 t1 t2)
-- 100
--
sumInts :: Tree -> Int
sumInts (Leaf i) = i
sumInts (Node i l r) = i + sumInts(l) + sumInts(r)
-- | The list of integers encountered by a pre-order traversal of the tree.
--
-- >>> preorder (Leaf 3)
-- [3]
--
-- >>> preorder (Node 5 (Leaf 6) (Leaf 7))
-- [5,6,7]
--
-- >>> preorder t1
-- [1,2,3,4,5,6,7,8,9]
--
-- >>> preorder t2
-- [6,2,1,4,3,5,8,7,9]
--
preorder :: Tree -> [Int]
preorder (Leaf i) = i : []
preorder (Node i l r) = (i : []) ++ preorder (l) ++ preorder(r)
-- | The list of integers encountered by an in-order traversal of the tree.
--
-- >>> inorder (Leaf 3)
-- [3]
--
-- >>> inorder (Node 5 (Leaf 6) (Leaf 7))
-- [6,5,7]
--
-- >>> inorder t1
-- [4,3,5,2,6,1,8,7,9]
--
-- >>> inorder t2
-- [1,2,3,4,5,6,7,8,9]
--
inorder :: Tree -> [Int]
inorder (Leaf i) = i : []
inorder (Node i l r) = inorder (l) ++ (i : []) ++ inorder(r)
-- | Check whether a binary tree is a binary search tree.
--
-- >>> isBST (Leaf 3)
-- True
--
-- >>> isBST (Node 5 (Leaf 6) (Leaf 7))
-- False
-- >>> isBST(Node 6 (Leaf 5) (Leaf 7))
-- True
--
-- >>> isBST t1
-- False
--
-- >>> isBST t2
-- True
--
isBST :: Tree -> Bool
isBST (Leaf i) = True
isBST (Node i l r) = (maxInt(l) <= i && minInt(r) >= i) && isBST(l) && isBST(r)
-- | Check whether a number is contained in a binary search tree.
-- (You may assume that the given tree is a binary search tree.)
--
-- >>> inBST 2 (Node 5 (Leaf 2) (Leaf 7))
-- True
--
-- >>> inBST 3 (Node 5 (Leaf 2) (Leaf 7))
-- False
--
-- >>> inBST 4 t2
-- True
--
-- >>> inBST 10 t2
-- False
--
inBST :: Int -> Tree -> Bool
inBST i (Leaf x) = i == x
inBST i (Node x l r) = (i == x) || (inBST i l) || (inBST i r)
--
-- * Part 2: Run-length lists
--
-- | Convert a regular list into a run-length list.
--
-- >>> appendBefore 1 [1,1,1,2,3,3,3,1,2,2,2,2]
-- [(4,1),(1,2),(3,3),(1,1),(4,2)]
--
-- >>> appendBefore 5 [1,1,1,2,3,3,3,1,2,2,2,2]
-- [(1,5),(3,1),(1,2),(3,3),(1,1),(4,2)]
appendBefore :: Eq a => a -> [(Int,a)] -> [(Int,a)]
appendBefore x list1
| x == element = [(num + 1,element)] ++ reminderlist
| otherwise = [(1,x)] ++ list1
where
(num,element) = head(list1)
reminderlist = tail(list1)
-- | Convert a regular list into a run-length list.
--
-- >>> compress [1,1,1,2,3,3,3,1,2,2,2,2]
-- [(3,1),(1,2),(3,3),(1,1),(4,2)]
--
-- >>> compress "Mississippi"
-- [(1,'M'),(1,'i'),(2,'s'),(1,'i'),(2,'s'),(1,'i'),(2,'p'),(1,'i')]
--
compress :: Eq a => [a] -> [(Int,a)]
compress [x] = [(1,x)]
compress (y : ys) = appendBefore y (compress ys)
--
-- >>> decompressIndividual 5 'a'
-- "aaaaa"
-- >>> decompressIndividual 1 'b'
-- "b"
--
decompressIndividual :: Eq a => Int -> a -> [a]
decompressIndividual 1 x = [x]
decompressIndividual num y = decompressIndividual (num - 1) y ++ [y]
-- | Convert a run-length list back into a regular list.
--
-- >>> decompress [(5,'a'),(3,'b'),(4,'c'),(1,'a'),(2,'b')]
-- "aaaaabbbccccabb"
--
decompress :: Eq a => [(Int,a)] -> [a]
decompress [(num,x)] = decompressIndividual num x
decompress ((num1,x1): ys) = (decompressIndividual num1 x1) ++ (decompress ys)