sicp-3-3-3
Posted on 2015-02-27 19:57:55 +0900 in SICP
3.24
(define (make-table same-key?)
(let ((local-table (list '*table*)))
(define (assoc key records)
(cond ((null? records) #f)
((same-key? key (caar records)) (car records))
(else (assoc key (cdr records)))))
(define (lookup key-1 key-2)
(let ((subtable (assoc key-1 (cdr local-table))))
(if subtable
(let ((record (assoc key-2 (cdr subtable))))
(if record
(cdr record)
#f
))
#f)))
(define (insert! key-1 key-2 value)
(let ((subtable (assoc key-1 (cdr local-table))))
(if subtable
(let ((record (assoc key-2 (cdr subtable))))
(if record
(set-cdr! record value)
(set-cdr! subtable (cons
(cons key-2 value)
(cdr subtable)))))
(set-cdr! local-table (cons
(list key-1
(cons key-2 value))
(cdr local-table))))))
(define (dispatch m)
(cond ((eq? m 'lookup-proc) lookup)
((eq? m 'insert-proc!) insert!)
(else (error "Unkown operation -- TABLE" m))))
dispatch))
3.25
(define (fold-left op init seq)
(define (iter ans res)
(if (null? res)
ans
(iter (op ans (car res)) (cdr res))))
(iter init seq))
(define (make-table same-key?)
(define (associate key records)
(cond ((null? records) #f)
((same-key? key (caar records))
(car records))
(else
(associate key (cdr records)))))
(let ((the-table (list '*table*)))
(define (lookup keys)
(define (lookup-record record-list key)
(if record-list
(let ((record (associate key record-list)))
(if record
(cdr record)
#f))
#f))
(fold-left lookup-record (cdr the-table) keys))
(define (insert! keys value)
(define (descend table key)
(let ((record (associate key (cdr table))))
(if record
record
(let ((new (cons (list key)
(cdr table))))
(set-cdr! table new)
(car new)))))
(set-cdr! (fold-left descend the-table keys)
value))
(define (dispatch m)
(cond ((eq? m 'lookup) lookup)
((eq? m 'insert!) insert!)
(else (error "Undefined method" m))))
dispatch))
(define op-table (make-table eq?))
(define put (op-table 'insert!))
(define get (op-table 'lookup))
(put '(letters a) 97) ; Two dimensions
(put '(letters b) 98)
(put '(math +) 43)
(put '(math -) 45)
(put '(math *) 42)
(put '(greek majiscule Λ) 923) ; Three dimensions
(put '(greek miniscule λ) 955)
(put '(min) 42) ; One dimension
(put '(max) 955)
(get '(min))
(get '(letters b))
(put '(min) 43) ; update
(get '(min))
This is a hard problem for me, as recursive problem is always hard for me to understand.
schemewiki provides a great base for this problem, especially the fold-left
is used,
which simplifies the logic a lot.
Recursive relies on split the problem into smaller consistently defined subproblems.
((k11
(k12
(k13 v1)))
(k21
(k22
(k23 v2)))
(k31
(k32 v3)))
Multi-dimention table looks like this.
3.26
(define (entry tree) (car tree))
(define (entry-key tree) (caar tree))
(define (entry-value tree) (cdar tree))
(define (left-branch tree) (cadr tree))
(define (right-branch tree) (caddr tree))
(define (make-tree entry left right)
(list entry left right))
(define (adjoin-set x set)
(cond ((null? set)
(make-tree x '() '()))
((= (car x) (entry-key set))
(set-cdr! (entry set) x))
((< (car x) (entry-key set))
(make-tree (entry set)
(adjoin-set x (left-branch set))
(right-branch set)))
(else
(make-tree (entry set)
(left-branch set)
(adjoin-set x (right-branch set))
))))
(define (make-table)
(let ((local-table '()))
(define (associate key)
(define (iter tree)
(cond ((null? tree) #f)
((= key (entry-key tree))
(entry tree))
((< key (entry-key tree))
(iter (left-branch tree)))
(else
(iter (right-branch tree)))))
(iter local-table))
(define (insert! key value)
(let ((record (associate key)))
(if record
(set-cdr! record value)
(set! local-table
(adjoin-set (cons key value) local-table)
))))
(define (dispatch m)
(cond ((eq? m 'get-proc) associate)
((eq? m 'insert-proc) insert!)))
dispatch))
(define table (make-table))
(define get (table 'get-proc))
(define put (table 'insert-proc))
(put 43 'a)
(put 42 'b)
(get 43)
(get 42)
(put 43 'e)
(get 43)
3.27
(define (memoize f)
(let ((table (make-table)))
(lambda (x)
(let ((previously-computed-result (lookup x table)))
(or previously-computed-result
(let ((result (f x)))
(insert! x result table)
result))))))
(define memo-fib
(memoize (lambda (n)
(cond ((= n 0) 0)
((= n 1) 1)
(else (+ (memo-fib (- n 1))
(memo-fib (- n 2))))))))
The key lies in the memo-fib
will share the table cache.
Hide Comments
comments powered by Disqus