Permalink
Browse files

sets

  • Loading branch information...
1 parent 6320983 commit 5ba87047756cdd7a4c739e00c70330781f8a8c50 @sarabander committed Sep 20, 2011
Showing with 128 additions and 0 deletions.
  1. +42 −0 2.3/2.59.scm
  2. +31 −0 2.3/2.60.scm
  3. +24 −0 2.3/2.61.scm
  4. +31 −0 2.3/2.62.scm
View
@@ -0,0 +1,42 @@
+
+;; From the book
+(define (element-of-set? x set)
+ (cond ((null? set) false)
+ ((equal? x (car set)) true)
+ (else (element-of-set? x (cdr set)))))
+
+(define (adjoin-set x set)
+ (if (element-of-set? x set)
+ set
+ (cons x set)))
+
+(define (intersection-set set1 set2)
+ (cond ((or (null? set1) (null? set2)) '())
+ ((element-of-set? (car set1) set2)
+ (cons (car set1)
+ (intersection-set (cdr set1) set2)))
+ (else (intersection-set (cdr set1) set2))))
+
+;; Added definitions:
+
+;; Why don't we just filter one set through another?
+(define (intersection-set set1 set2)
+ (filter (λ (e) (element-of-set? e set2))
+ set1))
+
+(define (union-set set1 set2)
+ (cond ((empty? set1) set2)
+ ((empty? set2) set1)
+ (else
+ (let ((subset (union-set (cdr set1) set2)))
+ (cond ((element-of-set? (car set1) subset) subset)
+ (else (cons (car set1) subset)))))))
+
+;; Better version
+(define (union-set set1 set2)
+ (append (filter (λ (e) (not (element-of-set? e set2)))
+ set1)
+ set2))
+
+(union-set '(1 4) '(1 2)) ; '(4 1 2)
+(intersection-set '(1 3 4) '(1 2 3)) ; '(1 3)
View
@@ -0,0 +1,31 @@
+
+;; Same as in book.
+;; Grows as before: O(n)
+(define (element-of-set? x set)
+ (cond ((null? set) false)
+ ((equal? x (car set)) true)
+ (else (element-of-set? x (cdr set)))))
+
+;; No reason to check membership.
+;; This now grows as O(1) instead of O(n).
+(define (adjoin-set x set)
+ (cons x set))
+
+;; Unchanged from book.
+;; Grows as before: O(n²).
+(define (intersection-set set1 set2)
+ (cond ((or (null? set1) (null? set2)) '())
+ ((element-of-set? (car set1) set2)
+ (cons (car set1)
+ (intersection-set (cdr set1) set2)))
+ (else (intersection-set (cdr set1) set2))))
+
+;; No need to check membership.
+;; Grows as O(1) instead of O(n²).
+(define (union-set set1 set2)
+ (append set1 set2))
+
+(union-set '(1 5) '(1 2 4)) ; '(1 5 1 2 4)
+
+;; Sure, I would use this for example to find unions of book collections.
+;; I don't mind having duplicate books in the library.
View
@@ -0,0 +1,24 @@
+
+;; We split the set so that set = subset1 + subset2. At first, subset1
+;, is empty. Then we move elements from the start of subset2 to the
+;; end of subset1 as if moving beads on the abacus. Every step we compare x
+;; to the first element of subset2. If it's less, we sandwich x between
+;; subset1 and subset2. If it's equal, we throw it away and reunite subset1
+;; with subset2. Average number of steps is n/2, where n is the number of
+;; elements in the set. Order of growth is still O(n).
+
+(define (adjoin-set x set)
+ (define (iter subset1 subset2)
+ (cond ((or (empty? subset2) (< x (car subset2)))
+ (append subset1 (list x) subset2))
+ ((= x (car subset2))
+ (append subset1 subset2))
+ (else (iter (append subset1
+ (list (car subset2)))
+ (cdr subset2)))))
+ (iter empty set))
+
+(adjoin-set 4 '(1 3 5 8)) ; '(1 3 4 5 8)
+(adjoin-set 14 '(1 3 5 8)) ; '(1 3 5 8 14)
+(adjoin-set 2 '(5 8)) ; '(2 5 8)
+(adjoin-set 12 '()) ; '(12)
View
@@ -0,0 +1,31 @@
+
+;; We take away car of first set, compare it to car of second set.
+;; If it's less, we append it to third set. If it's equal,
+;; we ignore it and append car of second set to third set. And so on.
+;; Number of steps grows as O(n), where n is cardinality of the bigger set.
+
+(define (union-set set1 set2)
+ (define (iter s1 s2 s3)
+ (cond ((empty? s1) (append s3 s2))
+ ((empty? s2) (append s3 s1))
+ ((< (car s1) (car s2))
+ (iter (cdr s1)
+ s2
+ (append s3 (list (car s1)))))
+ ((= (car s1) (car s2))
+ (iter (cdr s1)
+ (cdr s2)
+ (append s3 (list (car s2)))))
+ ((> (car s1) (car s2))
+ (iter s1
+ (cdr s2)
+ (append s3 (list (car s2)))))
+ (else (error "How did you get here?" s1 s2 s3))))
+ (iter set1 set2 empty))
+
+;; Tests
+(union-set '() '()) ; '()
+(union-set '(1 5) '(-3 8)) ; '(-3 1 5 8)
+(union-set '() '(4 7 12)) ; '(4 7 12)
+(union-set '(-9 2) '(2)) ; '(-9 2)
+(union-set '(6 8) '(5 7)) ; '(5 6 7 8)

0 comments on commit 5ba8704

Please sign in to comment.