#lang racket (require htdp/testing) ; Set difference, where sets are represented ; by sorted lists without duplicates ;(define (difference A B) ; (cond ; ((null? A) '()) ; ((null? B) A) ; ((< (first A) (first B)) (cons (first A) (difference (rest A) B))) ; ((= (first A) (first B)) (difference (rest A) (rest B))) ; (else (difference A (rest B))))) ; Tail-recursive set difference using an accumulator (define (difference A B) (difference-helper A B '())) (define (difference-helper A B Acc) (cond ((null? A) (reverse Acc)) ((null? B) (append (reverse Acc) A)) ((< (first A) (first B)) (difference-helper (rest A) B (cons (first A) Acc))) ((= (first A) (first B)) (difference-helper (rest A) (rest B) Acc)) (else (difference-helper A (rest B) Acc)))) ; Traditional append definition ;(define (append A B) ; (if (null? A) ; B ; (cons (first A) (append (rest A) B)))) ; Tail-recursive append ; Note that these over-write built-in functions, ; so should be used very cautiously. (define (append A B) (append-tr A (reverse B))) (define (append-tr A Acc) (if (null? A) (reverse Acc) (append-tr (rest A) (cons (first A) Acc)))) ; Naive reverse ;(define (reverse A) ; (if (null? A) ; '() ; (append (reverse (rest A)) (list (first A))))) ; Tail-recursive reverse (define (reverse A) (reverse-helper A '())) (define (reverse-helper A Acc) (if (null? A) Acc (reverse-helper (rest A) (cons (first A) Acc)))) (check-expect (difference '(1 2 4 6) '(3 4 5 6 7)) '(1 2)) (check-expect (difference '(1 2 4 6) '(2 3 4 5 6 7)) '(1)) (check-expect (difference '(2 4 6) '(2 3 4 5 6 7)) '()) (generate-report)