aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacques Comeaux <jacquesrcomeaux@protonmail.com>2023-07-09 11:53:34 -0500
committerJacques Comeaux <jacquesrcomeaux@protonmail.com>2023-07-09 11:53:34 -0500
commit1f7aa972194ca35ed12bf41fc7d59576f3796ad0 (patch)
tree381cacea0e119168b509eda29ed3d62548ec08dc
parentf24f3c4259140d0ff6a6aae21ad6e80aaafce87c (diff)
Add chapter 2 part 3
-rw-r--r--chap2/part1.rkt3
-rw-r--r--chap2/part2.rkt4
-rw-r--r--chap2/part3.rkt654
3 files changed, 661 insertions, 0 deletions
diff --git a/chap2/part1.rkt b/chap2/part1.rkt
index 766bbca..e7233f2 100644
--- a/chap2/part1.rkt
+++ b/chap2/part1.rkt
@@ -1,4 +1,6 @@
#lang sicp
+(#%require (only racket/base print-as-expression))
+(print-as-expression #f)
;; Chapter 2
;; Building Abstractions with Data
@@ -77,6 +79,7 @@
(print-rat one-half)
(print-rat (add-rat one-half one-third))
(print-rat (add-rat one-third one-third))
+(newline)
#| 2.2 |#
diff --git a/chap2/part2.rkt b/chap2/part2.rkt
index 1da2e67..461374e 100644
--- a/chap2/part2.rkt
+++ b/chap2/part2.rkt
@@ -1,4 +1,8 @@
#lang sicp
+(#%require (only racket/base print-as-expression print-mpair-curly-braces))
+(print-as-expression #f)
+(print-mpair-curly-braces #f)
+
(#%require graphics/graphics)
(open-graphics)
(define vp (open-viewport "Picture Language" 500 500))
diff --git a/chap2/part3.rkt b/chap2/part3.rkt
new file mode 100644
index 0000000..3777f79
--- /dev/null
+++ b/chap2/part3.rkt
@@ -0,0 +1,654 @@
+#lang sicp
+(#%require (only racket/base print-as-expression print-mpair-curly-braces))
+(print-as-expression #f)
+(print-mpair-curly-braces #f)
+
+;; Chapter 2
+;; Building Abstractions with Data
+
+;; 2.3
+;; Symbolic Data
+
+(#%provide memq)
+(define (memq item x)
+ (cond
+ ((null? x) false)
+ ((eq? item (car x)) x)
+ (else (memq item (cdr x)))))
+
+#| 2.53 |#
+
+;; (list 'a 'b 'c)
+;; (a b c)
+
+;; (list (list 'george))
+;; ((george))
+
+;; (cdr '((x1 x2) (y1 y2)))
+;; ((y1 y2))
+
+;; (cadr '((x1 x2) (y1 y2)))
+;; (y1 y2)
+
+;; (pair? (car '(a short list)))
+;; #f
+
+;; (memq 'red '((red shoes) (blue socks)))
+;; #f
+
+;; (memq 'red '(red shoes blue socks))
+;; (red shoes blue socks)
+
+#| 2.54 |#
+
+(#%provide equal?)
+(define (equal? a b)
+ (cond
+ ((and (not (pair? a)) (not (pair? b)))
+ (eq? a b))
+ ((and (pair? a) (pair? b))
+ (and
+ (equal? (car a) (car b))
+ (equal? (cdr a) (cdr b))))
+ (else false)))
+
+#| 2.55 |#
+
+;; (car ''abracadabra)
+;; (car '(quote abracadabra))
+;; quote
+
+(#%provide deriv)
+(define (deriv exp var)
+ (cond
+ ((number? exp) 0)
+ ((variable? exp)
+ (if (same-variable? exp var) 1 0))
+ ((sum? exp)
+ (make-sum
+ (deriv (addend exp) var)
+ (deriv (augend exp) var)))
+ ((product? exp)
+ (make-sum
+ (make-product
+ (multiplier exp)
+ (deriv (multiplicand exp) var))
+ (make-product
+ (deriv (multiplier exp) var)
+ (multiplicand exp))))
+ ((exponentiation? exp)
+ (make-product
+ (make-product
+ (exponent exp)
+ (make-exponentiation
+ (base exp)
+ (- (exponent exp) 1)))
+ (deriv (base exp) var)))
+ (else (error "bro what"))))
+
+(define (variable? x) (symbol? x))
+
+(define (same-variable? v1 v2)
+ (and (variable? v1) (variable? v2) (eq? v1 v2)))
+
+(define (make-sum- a1 a2)
+ (cond
+ ((=number? a1 0) a2)
+ ((=number? a2 0) a1)
+ ((and (number? a1) (number? a2))
+ (+ a1 a2))
+ (else (list '+ a1 a2))))
+
+(define (make-product- m1 m2)
+ (cond
+ ((or (=number? m1 0) (=number? m2 0))
+ 0)
+ ((=number? m1 1) m2)
+ ((=number? m2 1) m1)
+ ((and (number? m1) (number? m2))
+ (* m1 m2))
+ (else (list '* m1 m2))))
+
+(define (sum?- x)
+ (and (pair? x) (eq? (car x) '+)))
+
+(define (addend- s) (cadr s))
+
+(define (augend- s) (caddr s))
+
+(define (product?- x)
+ (and (pair? x) (eq? (car x) '*)))
+
+(define (multiplier- p)
+ (cadr p))
+
+(define (multiplicand- p) (caddr p))
+
+(define (=number? exp num)
+ (and (number? exp) (= exp num)))
+
+#| 2.56 |#
+
+(define (exponentiation? x)
+ (and (pair? x) (eq? (car x) '**)))
+
+(define (base s) (cadr s))
+
+(define (exponent s) (caddr s))
+
+(define (make-exponentiation u n)
+ (cond
+ ((not (number? n)) (error "exponent must be a number"))
+ ((=number? n 0) 1)
+ ((=number? n 1) u)
+ (else (list '** u n))))
+
+#| 2.57 |#
+
+(define (augend-- s)
+ (cond
+ ((null? (cdddr s)) (caddr s))
+ (else (cons '+ (cddr s)))))
+
+(define (multiplicand-- p)
+ (cond
+ ((null? (cdddr p)) (caddr p))
+ (else (cons '* (cddr p)))))
+
+#| 2.58 |#
+
+(define (make-sum a1 a2)
+ (cond
+ ((=number? a1 0) a2)
+ ((=number? a2 0) a1)
+ ((and (number? a1) (number? a2))
+ (+ a1 a2))
+ (else
+ (let
+ ((a1- (if (pair? a1) a1 (list a1)))
+ (a2- (if (pair? a2) a2 (list a2))))
+ (append a1- (cons '+ a2-))))))
+
+(define (make-product m1 m2)
+ (cond
+ ((or (=number? m1 0) (=number? m2 0))
+ 0)
+ ((=number? m1 1) m2)
+ ((=number? m2 1) m1)
+ ((and (number? m1) (number? m2))
+ (* m1 m2))
+ (else (list m1 '* m2))))
+
+(define (sum? x)
+ (and (pair? x) (memq '+ x)))
+
+(define (addend s)
+ (let ((front (take-until '+ s)))
+ (if (product? front) front (car front))))
+
+(define (augend s)
+ (let ((end (take-after '+ s)))
+ (if
+ (or (sum? end) (product? end))
+ end
+ (car end))))
+
+(define (product? x)
+ (and
+ (pair? x)
+ (not (memq '+ x))
+ (memq '* x)))
+
+(define (multiplier p)
+ (car (take-until '* p)))
+
+(define (multiplicand p)
+ (let ((end (take-after '* p)))
+ (if (product? end) end (car end))))
+
+(define (take-after item x)
+ (cond
+ ((null? x) x)
+ ((eq? item (car x)) (cdr x))
+ (else (take-after item (cdr x)))))
+
+(define (take-until item x)
+ (define (iter seen rest)
+ (cond
+ ((null? rest) rest)
+ ((eq? item (car rest)) (reverse seen))
+ (else (iter (cons (car rest) seen) (cdr rest)))))
+ (iter '() x))
+
+(#%provide element-of-set?-1)
+(define (element-of-set?-1 x set)
+ (cond
+ ((null? set) false)
+ ((equal? x (car set)) true)
+ (else (element-of-set?-1 x (cdr set)))))
+
+(#%provide adjoin-set-1)
+(define (adjoin-set-1 x set)
+ (if (element-of-set?-1 x set)
+ set
+ (cons x set)))
+
+(#%provide intersection-set-1)
+(define (intersection-set-1 set1 set2)
+ (cond
+ ((or (null? set1) (null? set2)) '())
+ ((element-of-set?-1 (car set1) set2)
+ (cons
+ (car set1)
+ (intersection-set-1 (cdr set1) set2)))
+ (else (intersection-set-1 (cdr set1) set2))))
+
+#| 2.59 |#
+
+(#%provide union-set-1)
+(define (union-set-1 set1 set2)
+ (cond
+ ((null? set1) set2)
+ ((element-of-set?-1 (car set1) set2)
+ (union-set-1 (cdr set1) set2))
+ (else (cons (car set1) (union-set-1 (cdr set1) set2)))))
+
+#| 2.60 |#
+
+(#%provide element-of-set?-2)
+(define (element-of-set?-2 x set)
+ (cond
+ ((null? set) false)
+ ((equal? x (car set)) true)
+ (else (element-of-set?-2 x (cdr set)))))
+
+(#%provide adjoin-set-2)
+(define (adjoin-set-2 x set)=
+ (cons x set))
+
+(#%provide intersection-set-2)
+(define (intersection-set-2 set1 set2)
+ (cond
+ ((or (null? set1) (null? set2)) '())
+ ((element-of-set?-2 (car set1) set2)
+ (cons
+ (car set1)
+ (intersection-set-2 (cdr set1) set2)))
+ (else (intersection-set-2 (cdr set1) set2))))
+
+(#%provide union-set-2)
+(define (union-set-2 set1 set2)
+ (cond
+ ((null? set1) set2)
+ (else (append set1 set2))))
+
+(#%provide element-of-set?-3)
+(define (element-of-set?-3 x set)
+ (cond
+ ((null? set) false)
+ ((= x (car set)) true)
+ ((< x (car set)) false)
+ (else (element-of-set?-3 x (cdr set)))))
+
+(#%provide intersection-set-3)
+(define (intersection-set-3 set1 set2)
+ (if (or (null? set1) (null? set2))
+ '()
+ (let ((x1 (car set1)) (x2 (car set2)))
+ (cond
+ ((= x1 x2) (cons x1 (intersection-set-3 (cdr set1) (cdr set2))))
+ ((< x1 x2) (intersection-set-3 (cdr set1) set2))
+ (else (intersection-set-3 set1 (cdr set2)))))))
+
+#| 2.61 |#
+
+(#%provide adjoin-set-3)
+(define (adjoin-set-3 x set)
+ (cond
+ ((null? set) (list x))
+ ((= x (car set)) set)
+ ((< x (car set)) (cons x set))
+ (else (cons (car set) (adjoin-set-3 x (cdr set))))))
+
+#| 2.62 |#
+
+(#%provide union-set-3)
+(define (union-set-3 set1 set2)
+ (cond
+ ((null? set1) set2)
+ ((null? set2) set1)
+ (else
+ (let ((x1 (car set1)) (x2 (car set2)))
+ (cond
+ ((= x1 x2) (cons x1 (union-set-3 (cdr set1) (cdr set2))))
+ ((< x1 x2) (cons x1 (union-set-3 (cdr set1) set2)))
+ (else (cons x2 (union-set-3 set1 (cdr set2)))))))))
+
+(define (entry tree) (car tree))
+
+(define (left-branch tree) (cadr tree))
+
+(define (right-branch tree) (caddr tree))
+
+(define (make-tree entry left right)
+ (list entry left right))
+
+(#%provide element-of-set?-4)
+(define (element-of-set?-4 x set)
+ (cond
+ ((null? set) false)
+ ((= x (entry set)) true)
+ ((< x (entry set)) (element-of-set?-4 x (left-branch set)))
+ (else (element-of-set?-4 x (right-branch set)))))
+
+(#%provide adjoin-set-4)
+(define (adjoin-set-4 x set)
+ (cond
+ ((null? set) (make-tree x '() '()))
+ ((= x (entry set)) set)
+ ((< x (entry set))
+ (make-tree (entry set) (adjoin-set-4 x (left-branch set)) (right-branch set)))
+ (else
+ (make-tree (entry set) (left-branch set) (adjoin-set-4 x (right-branch set))))))
+
+#| 2.63 |#
+
+(#%provide tree->list-1)
+(define (tree->list-1 tree)
+ (if (null? tree)
+ '()
+ (append
+ (tree->list-1 (left-branch tree))
+ (cons
+ (entry tree)
+ (tree->list-1 (right-branch tree))))))
+
+(#%provide tree->list-2)
+(define (tree->list-2 tree)
+ (define (copy-to-list tree result-list)
+ (if (null? tree)
+ result-list
+ (copy-to-list
+ (left-branch tree)
+ (cons
+ (entry tree)
+ (copy-to-list
+ (right-branch tree)
+ result-list)))))
+ (copy-to-list tree '()))
+
+;; tree->list-1 and tree-list-2 produce the same result
+;; tree->list-1 has order of growth n^2
+;; tree->list-2 has order of growth n
+
+#| 2.64 |#
+
+(#%provide list->tree)
+(define (list->tree elements)
+ (car (partial-tree elements (length elements))))
+
+(define (partial-tree elts n)
+ (if (= n 0)
+ (cons '() elts)
+ (let ((left-size (quotient (- n 1) 2)))
+ (let
+ ((left-result
+ (partial-tree elts left-size))
+ (right-size (- n (+ left-size 1))))
+ (let
+ ((left-tree (car left-result))
+ (non-left-elts (cdr left-result)))
+ (let
+ ((this-entry (car non-left-elts))
+ (right-result
+ (partial-tree (cdr non-left-elts) right-size)))
+ (let
+ ((right-tree (car right-result))
+ (remaining-elts (cdr right-result)))
+ (cons
+ (make-tree this-entry left-tree right-tree)
+ remaining-elts))))))))
+
+;; partial-tree calls itself recursively with size n/2 twice: first to make the
+;; left subtree, and then again to make the right subtree. The list of elements
+;; for the second call are those that remain after the first call and taking out
+;; one for the current entry
+
+;; partial-tree has linear order of growth
+
+#| 2.65 |#
+
+(#%provide intersection-set-4)
+(define (intersection-set-4 set1 set2)
+ (list->tree
+ (intersection-set-3
+ (tree->list-2 set1)
+ (tree->list-2 set2))))
+
+(#%provide union-set-4)
+(define (union-set-4 set1 set2)
+ (list->tree
+ (union-set-3
+ (tree->list-2 set1)
+ (tree->list-2 set2))))
+
+(define (lookup-1 given-key set-of-records)
+ (cond
+ ((null? set-of-records) false)
+ ((equal? given-key (key (car set-of-records)))
+ (car set-of-records))
+ (else (lookup-1 given-key (cdr set-of-records)))))
+
+#| 2.66 |#
+
+(define (make-rec k v) (cons k v))
+
+(define (key rec) (car rec))
+
+(define (value rec) (cdr rec))
+
+(define (lookup-2 k records)
+ (cond
+ ((null? records) false)
+ ((= k (key (entry records))) (entry records))
+ ((< k (key (entry records))) (lookup-2 k (left-branch records)))
+ (else (lookup-2 k (right-branch records)))))
+
+(define (make-leaf symbol weight)
+ (list 'leaf symbol weight))
+
+(define (leaf? object)
+ (eq? (car object) 'leaf))
+
+(define (symbol-leaf x) (cadr x))
+
+(define (weight-leaf x) (caddr x))
+
+(define (make-code-tree left right)
+ (list
+ left
+ right
+ (append (symbols left) (symbols right))
+ (+ (weight left) (weight right))))
+
+(define (left-branch- tree) (car tree))
+
+(define (right-branch- tree) (cadr tree))
+
+(define (symbols tree)
+ (if (leaf? tree)
+ (list (symbol-leaf tree))
+ (caddr tree)))
+
+(define (weight tree)
+ (if (leaf? tree)
+ (weight-leaf tree)
+ (cadddr tree)))
+
+(#%provide decode)
+(define (decode bits tree)
+ (define (decode-1 bits current-branch)
+ (if (null? bits)
+ '()
+ (let
+ ((next-branch
+ (choose-branch (car bits) current-branch)))
+ (if (leaf? next-branch)
+ (cons
+ (symbol-leaf next-branch)
+ (decode-1 (cdr bits) tree))
+ (decode-1 (cdr bits) next-branch)))))
+ (decode-1 bits tree))
+
+(define (choose-branch bit branch)
+ (cond
+ ((= bit 0) (left-branch- branch))
+ ((= bit 1) (right-branch- branch))
+ (else (error "bad bit -- CHOOSE-BRANCH" bit))))
+
+(define (adjoin-set- x set)
+ (cond
+ ((null? set) (list x))
+ ((< (weight x) (weight (car set))) (cons x set))
+ (else
+ (cons
+ (car set)
+ (adjoin-set- x (cdr set))))))
+
+(define (make-leaf-set pairs)
+ (if (null? pairs)
+ '()
+ (let ((pair (car pairs)))
+ (adjoin-set-
+ (make-leaf
+ (car pair)
+ (cadr pair))
+ (make-leaf-set (cdr pairs))))))
+
+#| 2.67 |#
+
+(#%provide sample-tree)
+(define sample-tree
+ (make-code-tree
+ (make-leaf 'A 4)
+ (make-code-tree
+ (make-leaf 'B 2)
+ (make-code-tree
+ (make-leaf 'D 1)
+ (make-leaf 'C 1)))))
+
+(#%provide sample-message)
+(define sample-message '(0 1 1 0 0 1 0 1 0 1 1 1 0))
+
+#| A 0 |#
+#| D 1 1 0 |#
+#| A 0 |#
+#| B 1 0 |#
+#| B 1 0 |#
+#| C 1 1 1 |#
+#| A 0 |#
+
+#| 2.68 |#
+
+(define (element-of-set?- x set)
+ (cond
+ ((null? set) false)
+ ((eq? x (car set)) true)
+ (else (element-of-set?- x (cdr set)))))
+
+(#%provide encode)
+(define (encode message tree)
+ (if (null? message)
+ '()
+ (append
+ (encode-symbol (car message) tree)
+ (encode (cdr message) tree))))
+
+(define (encode-symbol sym tree)
+ (define (search node path)
+ (cond
+ ((leaf? node) (reverse path))
+ ((element-of-set?- sym (symbols (left-branch- node)))
+ (search (left-branch- node) (cons 0 path)))
+ (else (search (right-branch- node) (cons 1 path)))))
+ (if (element-of-set?- sym (symbols tree))
+ (search tree '())
+ (error "symbol not in tree")))
+
+#| 2.69 |#
+
+(#%provide generate-huffman-tree)
+(define (generate-huffman-tree pairs)
+ (successive-merge (make-leaf-set pairs)))
+
+(define (successive-merge leaves)
+ (cond
+ ((null? leaves) (error "empty leaf set"))
+ ((null? (cdr leaves)) (car leaves))
+ (else
+ (successive-merge
+ (adjoin-set-
+ (make-code-tree (car leaves) (cadr leaves))
+ (cddr leaves))))))
+
+#| 2.70 |#
+
+(#%provide rock-tree)
+(define rock-tree
+ (generate-huffman-tree
+ '((A 2)
+ (BOOM 1)
+ (GET 2)
+ (JOB 2)
+ (NA 16)
+ (SHA 3)
+ (YIP 9)
+ (WAH 1))))
+
+(#%provide lyrics)
+(define lyrics
+ '(GET A JOB
+ SHA NA NA NA NA NA NA NA NA
+ GET A JOB
+ SHA NA NA NA NA NA NA NA NA
+ WAH YIP YIP YIP YIP YIP YIP YIP YIP YIP
+ SHA BOOM))
+
+;; (equal? lyrics (decode (encode lyrics rock-tree) rock-tree))
+;; #t
+
+;; (length lyrics)
+;; 36
+
+;; (length (encode lyrics rock-tree))
+;; 84
+
+;; for an eight-symbol fixed-length code, each symbol would require
+;; 3 bits, for a total of 3 * 36 = 108 bits
+
+#| 2.71 |#
+
+;; An alphabet of n symbols with relative frequencies
+;; 1, 2, 4, ..., 2^n-1
+
+;; With n = 5:
+;; o
+;; / \
+;; A o
+;; / \
+;; B o
+;; / \
+;; C o
+;; / \
+;; D E
+
+;; In such a tree, the most frequent symbol requires 1 bit
+;; and the least frequent symbol requires n-1 bits
+
+#| 2.72 |#
+
+;; Order of growth in number of steps to encode a symbol
+;; using a tree like the one above:
+
+;; Most frequent symbol: Theta(n)
+;; Least frequent symbol: Theta(n^2)