-
Notifications
You must be signed in to change notification settings - Fork 1
/
Exercise 2.65 union-set and intersection-set.rkt
344 lines (314 loc) · 12.2 KB
/
Exercise 2.65 union-set and intersection-set.rkt
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
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
#lang racket
; Exercise 2.65. Use the results of exercises 2.63 and 2.64 to give Theta(n)
; implementations of union-set and intersection-set for sets implemented as (balanced)
; binary trees.
(define (tree-union-set set1 set2)
; The input sets are binary trees
; 1. Convert each tree into an ordered set implemented as a list
; 2. Construct the union set from the above ordered lists
; 3. Convert the union set (which will be an ordered list) to a balanced binary tree
(list->tree (union-set (tree->list-2 set1) (tree->list-2 set2)))
)
(define (tree-intersection-set set1 set2)
; The input sets are binary trees
; 1. Convert each tree into an ordered set implemented as a list
; 2. Construct the intersection set from the above ordered lists
; 3. Convert the intersection set (which will be an ordered list) to a balanced binary tree
(list->tree (intersection-set (tree->list-2 set1) (tree->list-2 set2)))
)
(define (list->tree elements)
(car (partial-tree elements (length elements)))
)
(define (union-set set1 set2)
(cond
; If either of the sets is null the other one is the union
((null? set1) set2)
((null? set2) set1)
; If the first element of set1 is lesser than the first element of set2 then
; the first element is added to the union and the remaining data is processed
; recursively
((< (car set1) (car set2))
(cons (car set1) (union-set (cdr set1) set2))
)
; If the first element of set1 is equal to the first element of set2 then
; this element is added to the union and the remaining data is processed
; recursively
((= (car set1) (car set2))
(cons (car set1) (union-set (cdr set1) (cdr set2)))
)
; If the first element of set1 is greater than the first element of set2 then
; the first element of set2 is added to the union and the remaining data is processed
; recursively
((> (car set1) (car set2))
(cons (car set2) (union-set set1 (cdr set2)))
)
)
)
(define (intersection-set set1 set2)
(cond
; If either of the sets is null the intersection is also null
((null? set1) (list))
((null? set2) (list))
; If the first element of set1 is lesser than the first element of set2 then
; the first element of set1 is not present in set2 and it will not belong to the
; intersection set
; So the first element of set1 is ignored and we continue looking recursively
((< (car set1) (car set2))
(intersection-set (cdr set1) set2)
)
; If the first element of set1 is equal to the first element of set2 then
; this element is added to the intersection and the remaining data is processed
; recursively
((= (car set1) (car set2))
(cons (car set1) (intersection-set (cdr set1) (cdr set2)))
)
; If the first element of set1 is greater than the first element of set2 then
; the first element if set2 is not present in set1 and it will not belong to the
; intersection set
; So the first element of set2 is ignored and we continue looking recursively
((> (car set1) (car set2))
(intersection-set set1 (cdr set2))
)
)
)
(define (partial-tree elts n)
(if (= n 0)
(cons '() elts)
(let ((left-size (quotient (- n 1) 2)))
(let ((left-result (partial-tree elts left-size)))
(let
(
(left-tree (car left-result))
(non-left-elts (cdr left-result))
(right-size (- n (+ left-size 1)))
)
(let
(
(this-entry (car non-left-elts))
(right-result (partial-tree (cdr non-left-elts) right-size))
)
(let
(
(right-tree (car right-result))
(remaining-elts (cdr right-result))
)
(cons (make-tree this-entry left-tree right-tree) remaining-elts)
)
)
)
)
)
)
)
(define (tree->list-1 tree)
(cond
((null? tree) tree)
((not (pair? tree)) (list tree))
(else
(append
(tree->list-1 (left-branch tree))
(cons (entry tree) (tree->list-1 (right-branch tree)))
)
)
)
)
(define (tree->list-2 tree)
(define (copy-to-list tree result-list)
(cond
((null? tree) result-list)
((not (pair? tree)) (cons tree result-list))
(else
(copy-to-list
(left-branch tree)
(cons
(entry tree)
(copy-to-list (right-branch tree) result-list)
)
)
)
)
)
(copy-to-list tree '())
)
(define (entry tree)
(if (not (pair? tree))
tree
(car tree)
)
)
(define (left-branch tree)
(if (not (pair? tree))
tree
(cadr tree)
)
)
(define (right-branch tree)
(if (not (pair? tree))
tree
(caddr tree)
)
)
(define (make-tree entry left right)
(list entry left right)
)
(define (make-list start end)
(cond
((> start end) (list))
(else
(cons start (make-list (+ start 1) end))
)
)
)
; Tests
(define (test-tree-union-set range1-start range1-end range2-start range2-end)
(define tree1 (list->tree (make-list range1-start range1-end)))
(define tree2 (list->tree (make-list range2-start range2-end)))
(tree-union-set tree1 tree2)
)
(define (test-tree-intersection-set range1-start range1-end range2-start range2-end)
(define tree1 (list->tree (make-list range1-start range1-end)))
(define tree2 (list->tree (make-list range2-start range2-end)))
(tree-intersection-set tree1 tree2)
)
(define (timed-test-tree-union-set range1-start range1-end range2-start range2-end)
(define start-time (current-milliseconds))
(define result (test-tree-union-set range1-start range1-end range2-start range2-end))
(define end-time (current-milliseconds))
(display "Elapsed Time: ")
(display (- end-time start-time))
(newline)
)
(define (timed-test-tree-intersection-set range1-start range1-end range2-start range2-end)
(define start-time (current-milliseconds))
(define result (test-tree-intersection-set range1-start range1-end range2-start range2-end))
(define end-time (current-milliseconds))
(display "Elapsed Time: ")
(display (- end-time start-time))
(newline)
)
; Union tests
Welcome to DrRacket, version 6.11 [3m].
Language: racket, with debugging; memory limit: 256 MB.
> (test-tree-union-set 0 5 6 10)
'(5 (2 (0 () (1 () ())) (3 () (4 () ()))) (8 (6 () (7 () ())) (9 () (10 () ()))))
> (tree->list-2 (test-tree-union-set 0 5 6 10))
'(0 1 2 3 4 5 6 7 8 9 10)
> (tree->list-2 (test-tree-union-set 0 5 5 10))
'(0 1 2 3 4 5 6 7 8 9 10)
> (test-tree-union-set 0 5 3 8)
'(4 (1 (0 () ()) (2 () (3 () ()))) (6 (5 () ()) (7 () (8 () ()))))
> (tree->list-2 (test-tree-union-set 0 5 3 8))
'(0 1 2 3 4 5 6 7 8)
> (test-tree-union-set 0 5 1 5)
'(2 (0 () (1 () ())) (4 (3 () ()) (5 () ())))
> (tree->list-2 (test-tree-union-set 0 5 1 5))
'(0 1 2 3 4 5)
> (test-tree-union-set 0 5 0 5)
'(2 (0 () (1 () ())) (4 (3 () ()) (5 () ())))
> (tree->list-2 (test-tree-union-set 0 5 0 5))
'(0 1 2 3 4 5)
> (test-tree-union-set 0 5 -3 5)
'(1 (-2 (-3 () ()) (-1 () (0 () ()))) (3 (2 () ()) (4 () (5 () ()))))
> (tree->list-2 (test-tree-union-set 0 5 -3 5))
'(-3 -2 -1 0 1 2 3 4 5)
> (test-tree-union-set 0 5 -3 1)
'(1 (-2 (-3 () ()) (-1 () (0 () ()))) (3 (2 () ()) (4 () (5 () ()))))
> (tree->list-2 (test-tree-union-set 0 5 -3 1))
'(-3 -2 -1 0 1 2 3 4 5)
> (test-tree-union-set 0 5 -3 0)
'(1 (-2 (-3 () ()) (-1 () (0 () ()))) (3 (2 () ()) (4 () (5 () ()))))
> (tree->list-2 (test-tree-union-set 0 5 -3 0))
'(-3 -2 -1 0 1 2 3 4 5)
> (test-tree-union-set 0 5 -17 -6)
'(-9
(-14 (-16 (-17 () ()) (-15 () ())) (-12 (-13 () ()) (-11 () (-10 () ()))))
(1 (-7 (-8 () ()) (-6 () (0 () ()))) (3 (2 () ()) (4 () (5 () ())))))
> (tree->list-2 (test-tree-union-set 0 5 -17 -6))
'(-17 -16 -15 -14 -13 -12 -11 -10 -9 -8 -7 -6 0 1 2 3 4 5)
>
; Intersection tests
> (test-tree-intersection-set 0 5 6 10) (tree->list-2 (test-tree-intersection-set 0 5 6 10))
'()
'()
> (test-tree-intersection-set 0 5 5 10) (tree->list-2 (test-tree-intersection-set 0 5 5 10))
'(5 () ())
'(5)
> (test-tree-intersection-set 0 5 3 8) (tree->list-2 (test-tree-intersection-set 0 5 3 8))
'(4 (3 () ()) (5 () ()))
'(3 4 5)
> (test-tree-intersection-set 0 5 1 5) (tree->list-2 (test-tree-intersection-set 0 5 1 5))
'(3 (1 () (2 () ())) (4 () (5 () ())))
'(1 2 3 4 5)
> (test-tree-intersection-set 0 5 0 5) (tree->list-2 (test-tree-intersection-set 0 5 0 5))
'(2 (0 () (1 () ())) (4 (3 () ()) (5 () ())))
'(0 1 2 3 4 5)
> (test-tree-intersection-set 0 5 -3 5) (tree->list-2 (test-tree-intersection-set 0 5 -3 5))
'(2 (0 () (1 () ())) (4 (3 () ()) (5 () ())))
'(0 1 2 3 4 5)
> (test-tree-intersection-set 0 5 -3 1) (tree->list-2 (test-tree-intersection-set 0 5 -3 1))
'(0 () (1 () ()))
'(0 1)
> (test-tree-intersection-set 0 5 -3 0) (tree->list-2 (test-tree-intersection-set 0 5 -3 0))
'(0 () ())
'(0)
> (test-tree-intersection-set 0 5 -17 -6) (tree->list-2 (test-tree-intersection-set 0 5 -17 -6))
'()
'()
>
; Performance Tests
(time (timed-test-tree-union-set -10000 -10 10 10000))
(time (timed-test-tree-union-set -20000 -10 10 20000))
(time (timed-test-tree-union-set -30000 -10 10 30000))
(time (timed-test-tree-union-set -40000 -10 10 40000))
(time (timed-test-tree-union-set -50000 -10 10 50000))
(time (timed-test-tree-union-set -60000 -10 10 60000))
(time (timed-test-tree-union-set -70000 -10 10 70000))
(time (timed-test-tree-union-set -80000 -10 10 80000))
(time (timed-test-tree-union-set -90000 -10 10 90000))
(time (timed-test-tree-union-set -100000 -10 10 100000))
(time (timed-test-tree-union-set -200000 -10 10 200000))
(time (timed-test-tree-union-set -300000 -10 10 300000))
(time (timed-test-tree-union-set -400000 -10 10 400000))
(time (timed-test-tree-union-set -500000 -10 10 500000))
(time (timed-test-tree-union-set -600000 -10 10 600000))
(time (timed-test-tree-union-set -700000 -10 10 700000))
(time (timed-test-tree-union-set -800000 -10 10 800000))
(time (timed-test-tree-union-set -900000 -10 10 900000))
(time (timed-test-tree-union-set -1000000 -10 10 1000000))
(time (timed-test-tree-union-set -2000000 -10 10 2000000))
(time (timed-test-tree-union-set -3000000 -10 10 3000000))
(time (timed-test-tree-union-set -4000000 -10 10 4000000))
(time (timed-test-tree-union-set -5000000 -10 10 5000000))
(time (timed-test-tree-union-set -6000000 -10 10 6000000))
(time (timed-test-tree-union-set -7000000 -10 10 7000000))
(time (timed-test-tree-union-set -8000000 -10 10 8000000))
(time (timed-test-tree-union-set -9000000 -10 10 9000000))
(time (timed-test-tree-union-set -10000000 -10 10 10000000))
(time (timed-test-tree-intersection-set -10000 -10 -100 10000))
(time (timed-test-tree-intersection-set -20000 -10 -100 20000))
(time (timed-test-tree-intersection-set -30000 -10 -100 30000))
(time (timed-test-tree-intersection-set -40000 -10 -100 40000))
(time (timed-test-tree-intersection-set -50000 -10 -100 50000))
(time (timed-test-tree-intersection-set -60000 -10 -100 60000))
(time (timed-test-tree-intersection-set -70000 -10 -100 70000))
(time (timed-test-tree-intersection-set -80000 -10 -100 80000))
(time (timed-test-tree-intersection-set -90000 -10 -100 90000))
(time (timed-test-tree-intersection-set -100000 -10 -100 100000))
(time (timed-test-tree-intersection-set -200000 -10 -100 200000))
(time (timed-test-tree-intersection-set -300000 -10 -100 300000))
(time (timed-test-tree-intersection-set -400000 -10 -100 400000))
(time (timed-test-tree-intersection-set -500000 -10 -100 500000))
(time (timed-test-tree-intersection-set -600000 -10 -100 600000))
(time (timed-test-tree-intersection-set -700000 -10 -100 700000))
(time (timed-test-tree-intersection-set -800000 -10 -100 800000))
(time (timed-test-tree-intersection-set -900000 -10 -100 900000))
(time (timed-test-tree-intersection-set -1000000 -10 -1000 1000000))
(time (timed-test-tree-intersection-set -2000000 -10 -1000 2000000))
(time (timed-test-tree-intersection-set -3000000 -10 -1000 3000000))
(time (timed-test-tree-intersection-set -4000000 -10 -1000 4000000))
(time (timed-test-tree-intersection-set -5000000 -10 -1000 5000000))
(time (timed-test-tree-intersection-set -6000000 -10 -1000 6000000))
(time (timed-test-tree-intersection-set -7000000 -10 -1000 7000000))
(time (timed-test-tree-intersection-set -8000000 -10 -1000 8000000))
(time (timed-test-tree-intersection-set -9000000 -10 -1000 9000000))
(time (timed-test-tree-intersection-set -10000000 -10 -1000 10000000))