(sicp22)m2.59~m2.60

(use pre-sicp)

(define (element-of-set? x set)
  (cond ((null? set) #f)
        ((equal? x (car set)) #t)
        (else (element-of-set? x (cdr set)))))

(define (adjoin-set x set)
  (if (element-of-set? x set)
      set
      (cons x set)))

(let ((set '(1 2 3 4 5)))
  (print (adjoin-set 2 set))
  (print (adjoin-set 6 set))
  (print (adjoin-set '(1 6) set)))

;; gosh> (1 2 3 4 5)
;; (6 1 2 3 4 5)
;; ((1 6) 1 2 3 4 5)


(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))))

;;m2.59
(define (union-set set1 set2)
  (cond ((null? set1) set2)
        ((null? set2) set1)
        ((not (element-of-set? (car set1) set2))
         (cons (car set1)
               (union-set (cdr set1) set2)))
        (else (union-set (cdr set1) set2))))

(let ((set1 '(1 3 5 7))
      (set2 '(1 2 3 4 5)))
  (print "set1= " set1 " set2=" set2)
  (print "intersection: " (intersection-set set1 set2))
  (print "union: " (union-set set1 set2)))

;; gosh> set1= (1 3 5 7) set2=(1 2 3 4 5)
;; intersection: (1 3 5)
;; union: (7 1 2 3 4 5)


;;m2.60
;;accumulate = fold
(let ((set1 (append '(1 3 5)(enumerate-interval 1 10)))
      (set2 '(2 4 2 4 2 6 10)))
  (define (element-of-set? x set)
    (not (null? (filter (lambda (y) (equal? x y)) set))))

  (define (adjoin-set x set2)
    (cons x set2))

  (define (union-set set1 set2)
    (append set1 set2))

  (define (intersection-set set1 set2)
    (fold (lambda (x rest)
            (append (filter (lambda (y) (equal? x y)) set2) rest))
          '()
          set1))
  (print "set1= " set1 " set2=" set2)
  (print "(element-of-set? 1 set1)" " result: " (element-of-set? 1 set1))
  (print "intersection: " (intersection-set set1 set2))
  (print "union: " (union-set set1 set2)))

;; gosh> set1= (1 3 5 1 2 3 4 5 6 7 8 9 10) set2=(2 4 2 4 2 6 10)
;; (element-of-set? 1 set1) result: #t
;; intersection: (10 6 4 4 2 2 2)
;; union: (1 3 5 1 2 3 4 5 6 7 8 9 10 2 4 2 4 2 6 10)