;; NSet = [Listof Number] ;; order does not matter; no repetitions allowed ;; contains? : NSet Number -> Boolean ;; Does set s contain the number n? (define (contains? s n) (ormap (lambda (x) (= x n)) s)) (check-expect (contains? '() 4) false) (check-expect (contains? '(2 4 1) 4) true) (check-expect (contains? '(2 4 1) 3) false) (check-expect (contains? '(1 2 4) 4) true) ;; subset? : NSet NSet -> Boolean ;; Is set xs a subset of set ys? (define (subset? xs ys) (andmap (lambda (x) (contains? ys x)) xs)) (check-expect (subset? '() '(3)) true) (check-expect (subset? '(3) '()) false) (check-expect (subset? '(1 2 3) '(4 3 2 1)) true) ;; set=? : NSet NSet -> Boolean ;; are the two sets equal? (define (set=? xs ys) (and (subset? xs ys) (subset? ys xs))) ;; intersect : NSet NSet -> NSet ;; intersect the two sets (define (intersect xs ys) (local ((define (in-xs? y) (contains? xs y))) (filter in-xs? ys))) (check-expect (set=? (intersect '(1 2 3 4 5) '(5 3 7 1)) '(1 3 5)) true) ;; union : NSet NSet -> NSet ;; union the two sets (define (union.v1 xs ys) (local ((define (not-in-xs? y) (not (contains? xs y)))) (append xs (filter not-in-xs? ys)))) ;; Now let's write union using foldr... ;; union : NSet NSet -> NSet ;; union the two sets (define (union xs ys) (local ((define (op? y ans) (cond [(contains? ans y) ans] [else (cons y ans)]))) (foldr op? xs ys))) ;; compare the output of the following: ;; (union.v1 '(1 2 3 4 5) '(5 3 7 1)) ;; vs. ;; (union '(1 2 3 4 5) '(5 3 7 1)) (check-expect (set=? (union '(1 2 3 4 5) '()) '(1 2 3 4 5)) true) (check-expect (set=? (union '(1 2 3 4 5) '(5 3 7 1)) '(1 2 3 4 5 7)) true)