; Exercise 3.12 ; append! is a destructive version of append ; note x must not be null! (define (append! x y) (set-cdr! (last-pair x) y) x) ; takes a non-null list and returns its last pair (define (last-pair x) (if (null? (cdr x)) x (last-pair (cdr x)))) (define x (list 'a 'b)) (define y (list 'c 'd)) (define z (append x y)) ; note that x changes as a result of the next statement ;(define w (append! x y)) ; Exercise M3.9 ; takes a list and creates a copy -- sort-of (define (copy-list x) (if (null? x) () (cons (car x) (copy-list (cdr x))))) (define x9 '((a b) c)) (define y9 (copy-list x9)) ;> x9 ;((a b) c) ;> y9 ;((a b) c) ;> (set-car! (car x9) 'wow) ;> x9 ;((wow b) c) ;> y9 ;((wow b) c) ; does a deep-copy instead of just top-level (define (deep-copy-list x) (cond ((null? x) ()) ((pair? (car x)) (cons (deep-copy-list (car x)) (deep-copy-list (cdr x)))) (else (cons (car x) (copy-list (cdr x)))))) (define x9-2 '((a b) c)) (define y9-2 (deep-copy-list x9-2)) ;> x9-2 ;((a b) c) ;> y9-2 ;((a b) c) ;> (set-car! (car x9-2) 'wow) ;> x9-2 ;((wow b) c) ;> y9-2 ;((a b) c) ;;;;;;;; QUEUE IMPLEMENTATION ;;;;; ; makes an empty queue. A queue is a pair with a front ; pointer and a rear pointer (define (make-queue) (cons () ())) ; takes a queue and is #t if the queue is empty (define (empty-queue? q) (null? (car q))) ; takes a queue and returns the front element ; or error if the queue is empty (define (front-queue q) (if (empty-queue? q) (error "FRONT on empty queue" q) (caar q))) ; takes a queue and an item and changes the queue so ; as to add the new item (to the end) (define (insert-queue! q item) (let ((new-pair (cons item ()))) (cond ((empty-queue? q) (set-car! q new-pair) (set-cdr! q new-pair) q) (else (set-cdr! (cdr q) new-pair) (set-cdr! q new-pair) q)))) ; takes a queue and changes it so as to delete the ; front element or creates an error if the queue ; is empty (define (delete-queue! q) (cond ((empty-queue? q) (error "DELETE! on empty queue" q)) (else (set-car! q (cdar q))))) ;;; ASSOCIATION LISTS AND TABLES ;;; ; takes a key and an association list and returns ; the pair including the key in the list (define (assoc key assoc-list) (cond ((null? assoc-list) #f) ((equal? key (caar assoc-list)) (car assoc-list)) (else (assoc key (cdr assoc-list))))) (define abcs '((a . apple) (b . boy) (c . cat) (d. dog))) ; makes an empty table (define (make-table) (list '*table*)) ; finds an entry in the table and returns the value (define (lookup key table) (let ((record (assoc key (cdr table)))) (if record (cdr record) #f))) ; takes a key with a value and inserts ; it into the table table, value returned is ; the symbol done (define (insert! key value table) (let ((record (assoc key (cdr table)))) (if record (set-cdr! record value) (set-cdr! table (cons (cons key value) (cdr table))))) 'done) ;> (define t1 (make-table)) ;> (insert! 'a 'apple t1) ;done ;> (insert! 'b 'boy t1) ;done ;> t1 ;(*table* (b . boy) (a . apple)) ;> (lookup 'a t1) ;apple ;> (lookup 'c t1) ;#f ;> (lookup 'b t1) ;boy ;> (insert! 'b 'baby t1) ;done ;> (lookup 'b t1) ;baby (define (make-table2) (list '*table*)) ; takes two keys and a two dimensional table ; looks up the value associated with those ; two keys in the table (define (lookup2 key1 key2 table) (let ((subtable (assoc key1 (cdr table)))) (if subtable (let ((record (assoc key2 (cdr subtable)))) (if record (cdr record) #f)) #f))) ; insert a new value into a table with two keys ; first check keys already exist (define (insert2! key1 key2 val table) (let ((subtbl (assoc key1 (cdr table)))) (if subtbl (let ((record (assoc key2 (cdr subtbl)))) (if record (set-cdr! record val) (set-cdr! subtbl (cons (cons key2 val) (cdr subtbl))))) (set-cdr! table (cons (list key1 (cons key2 val)) (cdr table))))) 'done) ;> (define t2 (make-table2)) ;> t2 ;(*table*) ;> (insert2! 'a 'fruit 'apple t2) ;done ;> t2 ;(*table* (a (fruit . apple))) ;> (insert2! 'b 'fruit 'banana t2) ;done ;> t2 ;(*table* (b (fruit . banana)) (a (fruit . apple))) ;> (insert2! 'a 'part-of-speech 'adjective t2) ;done ;> t2 ;(*table* (b (fruit . banana)) (a (part-of-speech . adjective) (fruit . apple))) ;> (lookup2 'a 'part-of-speech t2) ;adjective ;> (insert2! 'a 'part-of-speech 'adverb t2) ;done ;> (lookup2 'a 'part-of-speech t2) ;adverb