1 (define (test-case actual expected)
10 (define (make-leaf symbol weight)
11 (list 'leaf symbol weight))
12 (define (leaf? object)
13 (eq? (car object) 'leaf))
14 (define (symbol-leaf x) (cadr x))
15 (define (weight-leaf x) (caddr x))
17 (define (make-code-tree left right)
20 (append (symbols left) (symbols right))
21 (+ (weight left) (weight right))))
23 (define (left-branch tree) (car tree))
24 (define (right-branch tree) (cadr tree))
25 (define (symbols tree)
27 (list (symbol-leaf tree))
34 (define (decode bits tree)
35 (define (decode-1 bits current-branch)
39 (choose-branch (car bits) current-branch)))
40 (if (leaf? next-branch)
41 (cons (symbol-leaf next-branch)
42 (decode-1 (cdr bits) tree))
43 (decode-1 (cdr bits) next-branch)))))
45 (define (choose-branch bit branch)
46 (cond ((= bit 0) (left-branch branch))
47 ((= bit 1) (right-branch branch))
48 (else (error "bad bit -- CHOOSE-BRANCH" bit))))
50 (define (adjoin-set x set)
51 (cond ((null? set) (list x))
52 ((< (weight x) (weight (car set))) (cons x set))
54 (adjoin-set x (cdr set))))))
55 (define (make-leaf-set pairs)
58 (let ((pair (car pairs)))
59 (adjoin-set (make-leaf (car pair)
61 (make-leaf-set (cdr pairs))))))
63 (define (encode message tree)
66 (append (encode-symbol (car message) tree)
67 (encode (cdr message) tree))))
69 (define (element-of-set x set)
70 (and (not (null? set))
71 (or (equal? x (car set))
72 (element-of-set x (cdr set)))))
74 (define (encode-symbol sym tree)
75 (cond ((null? tree) (error "empty tree"))
76 ((not (element-of-set sym (symbols tree)))
77 (error "symbol not in tree"))
79 ((element-of-set sym (symbols (left-branch tree)))
80 (cons 0 (encode-symbol sym (left-branch tree))))
81 ((element-of-set sym (symbols (right-branch tree)))
82 (cons 1 (encode-symbol sym (right-branch tree))))))
84 (define (generate-huffman-tree pairs)
85 (successive-merge (make-leaf-set pairs)))
87 (define (successive-merge leaf-set)
88 (cond ((null? leaf-set) (error "no leaves in leaf-set"))
89 ((null? (cdr leaf-set)) (car leaf-set))
90 (else (successive-merge (adjoin-set (make-code-tree (cadr leaf-set)
94 ;; Exercise 2.70. The following eight-symbol alphabet with associated relative frequencies was designed to efficiently encode the lyrics of 1950s rock songs. (Note that the ``symbols'' of an ``alphabet'' need not be individual letters.)
100 ;; Use generate-huffman-tree (exercise 2.69) to generate a corresponding Huffman tree, and use encode (exercise 2.68) to encode the following message:
102 (test-case (generate-huffman-tree '((A 2) (BOOM 1) (GET 2) (JOB 2) (NA 16) (SHA 3) (YIP 9) (WAH 1)))
103 '((((((leaf get 2) (leaf job 2) (get job) 4)
107 (((leaf boom 1) (leaf wah 1) (boom wah) 2)
111 (get job sha boom wah a)
114 (get job sha boom wah a yip)
117 (get job sha boom wah a yip na)
119 (test-case (encode '(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)
120 (generate-huffman-tree '((A 2) (BOOM 1) (GET 2) (JOB 2) (NA 16) (SHA 3) (YIP 9) (WAH 1))))
121 '(0 0 0 0 0 0 0 1 1 0 0 0 0 1 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 1 1 0 0 0 0 1 0 0 0 1 1 1 1 1 1 1 1 1 0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 0 0 1 0 0 1 0 0))
134 ;; Sha na na na na na na na na
138 ;; Sha na na na na na na na na
140 ;; Wah yip yip yip yip yip yip yip yip yip
144 ;; How many bits are required for the encoding? What is the smallest number of bits that would be needed to encode this song if we used a fixed-length code for the eight-symbol alphabet?
146 ;; 5 bits are required at most for encoding a symbol, which is actually 2 bits more than fixed-length code
148 ;; Overall, though, only 84 bits are required using Huffman encoding vs. 108 bits for fixed-length code