Section 2.2.3

This commit is contained in:
Correl Roush 2014-06-29 21:33:26 -04:00
parent 4d0dec9ac2
commit 206628f165

307
2-2.org
View file

@ -684,3 +684,310 @@ layout: org
(let ((rest (subsets (cdr s)))) (let ((rest (subsets (cdr s))))
(append rest (map (lambda (x) (cons (car s) x)) rest))))) (append rest (map (lambda (x) (cons (car s) x)) rest)))))
#+end_src #+end_src
* Sequences as Conventional Interfaces
** Sequence Operations
#+begin_src scheme :tangle yes
;; ===================================================================
;; Section 2.2.3: Sequences as Conventional Interfaces
;; ===================================================================
(define (filter predicate sequence)
(cond ((null? sequence) nil)
((predicate (car sequence))
(cons (car sequence)
(filter predicate (cdr sequence))))
(else (filter predicate (cdr sequence)))))
(define (accumulate op initial sequence)
(if (null? sequence)
initial
(op (car sequence)
(accumulate op initial (cdr sequence)))))
#+end_src
*** Exercise 2.33
Fill in the missing expressions to complete the
following definitions of some basic list-manipulation operations
as accumulations:
#+begin_src scheme
(define (map p sequence)
(accumulate (lambda (x y) <??>) nil sequence))
(define (append seq1 seq2)
(accumulate cons <??> <??>))
(define (length sequence)
(accumulate <??> 0 sequence))
#+end_src
----------------------------------------------------------------------
#+begin_src scheme :tangle yes
;; -------------------------------------------------------------------
;; Exercise 2.33
;; -------------------------------------------------------------------
(define (map p sequence)
(accumulate (lambda (x y) (cons (p x) y)) '() sequence))
(define (append seq1 seq2)
(accumulate cons seq2 seq1))
(define (length sequence)
(accumulate (lambda (e acc) (+ 1 acc)) 0 sequence))
#+end_src
*** Exercise 2.34
Evaluating a polynomial in x at a given value of
x can be formulated as an accumulation. We evaluate the polynomial
#+begin_example
a_n r^n | a_(n-1) r^(n-1) + ... + a_1 r + a_0
#+end_example
using a well-known algorithm called "Horner's rule", which
structures the computation as
#+begin_example
(... (a_n r + a_(n-1)) r + ... + a_1) r + a_0
#+end_example
In other words, we start with a_n, multiply by x, add a_(n-1),
multiply by x, and so on, until we reach a_0.(3)
Fill in the following template to produce a procedure that
evaluates a polynomial using Horner's rule. Assume that the
coefficients of the polynomial are arranged in a sequence, from
a_0 through a_n.
#+begin_src scheme
(define (horner-eval x coefficient-sequence)
(accumulate (lambda (this-coeff higher-terms) <??>)
0
coefficient-sequence))
#+end_src
For example, to compute 1 + 3x + 5x^3 + x^(5) at x = 2 you would
evaluate
#+begin_src scheme
(horner-eval 2 (list 1 3 0 5 0 1))
#+end_src
----------------------------------------------------------------------
#+begin_src scheme :tangle yes
;; -------------------------------------------------------------------
;; Exercise 2.34
;; -------------------------------------------------------------------
(define (horner-eval x coefficient-sequence)
(accumulate (lambda (this-coeff higher-terms)
(+ this-coeff (* higher-terms x)))
0
coefficient-sequence))
#+end_src
*** Exercise 2.35
Redefine `count-leaves' from section *Note 2-2-2:: as an
accumulation:
#+begin_src scheme
(define (count-leaves t)
(accumulate <??> <??> (map <??> <??>)))
#+end_src
----------------------------------------------------------------------
#+begin_src scheme :tangle yes
;; -------------------------------------------------------------------
;; Exercise 2.35
;; -------------------------------------------------------------------
(define (count-leaves t)
(accumulate + 0 (map
(lambda (node)
(if (pair? node)
(count-leaves node)
1))
t)))
#+end_src
*** Exercise 2.36
The procedure `accumulate-n' is similar to `accumulate' except
that it takes as its third argument a sequence of sequences, which
are all assumed to have the same number of elements. It applies
the designated accumulation procedure to combine all the first
elements of the sequences, all the second elements of the
sequences, and so on, and returns a sequence of the results. For
instance, if `s' is a sequence containing four sequences, `((1
2 3) (4 5 6) (7 8 9) (10 11 12)),' then the value of
`(accumulate-n + 0 s)' should be the sequence `(22 26 30)'. Fill
in the missing expressions in the following definition of
`accumulate-n':
#+begin_src scheme
(define (accumulate-n op init seqs)
(if (null? (car seqs))
nil
(cons (accumulate op init <??>)
(accumulate-n op init <??>))))
#+end_src
----------------------------------------------------------------------
#+begin_src scheme :tangle yes
;; -------------------------------------------------------------------
;; Exercise 2.36
;; -------------------------------------------------------------------
(define (accumulate-n op init seqs)
(if (null? (car seqs))
'()
(cons (accumulate op init (map car seqs))
(accumulate-n op init (map cdr seqs)))))
#+end_src
** Exercise 2.37
Suppose we represent vectors v = (v_i) as sequences of numbers, and
matrices m = (m_(ij)) as sequences of vectors (the rows of the matrix).
For example, the matrix
#+begin_example
+- -+
| 1 2 3 4 |
| 4 5 6 6 |
| 6 7 8 9 |
+- -+
#+end_example
is represented as the sequence `((1 2 3 4) (4 5 6 6) (6 7 8 9))'. With
this representation, we can use sequence operations to concisely
express the basic matrix and vector operations. These operations
(which are described in any book on matrix algebra) are the following:
#+begin_example
__
(dot-product v w) returns the sum >_i v_i w_i
(matrix-*-vector m v) returns the vector t,
__
where t_i = >_j m_(ij) v_j
(matrix-*-matrix m n) returns the matrix p,
__
where p_(ij) = >_k m_(ik) n_(kj)
(transpose m) returns the matrix n,
where n_(ij) = m_(ji)
#+end_example
We can define the dot product as(4)
#+begin_src scheme
(define (dot-product v w)
(accumulate + 0 (map * v w)))
#+end_src
Fill in the missing expressions in the following procedures for
computing the other matrix operations. (The procedure `accumulate-n'
is defined in *Note Exercise 2-36::.)
#+begin_src scheme
(define (matrix-*-vector m v)
(map <??> m))
(define (transpose mat)
(accumulate-n <??> <??> mat))
(define (matrix-*-matrix m n)
(let ((cols (transpose n)))
(map <??> m)))
#+end_src
*** Exercise 2.38
The `accumulate' procedure is also known as `fold-right', because
it combines the first element of the sequence with the result of
combining all the elements to the right. There is also a
`fold-left', which is similar to `fold-right', except that it
combines elements working in the opposite direction:
#+begin_src scheme
(define (fold-left op initial sequence)
(define (iter result rest)
(if (null? rest)
result
(iter (op result (car rest))
(cdr rest))))
(iter initial sequence))
#+end_src
What are the values of
(fold-right / 1 (list 1 2 3))
(fold-left / 1 (list 1 2 3))
(fold-right list nil (list 1 2 3))
(fold-left list nil (list 1 2 3))
Give a property that `op' should satisfy to guarantee that
`fold-right' and `fold-left' will produce the same values for any
sequence.
----------------------------------------------------------------------
#+begin_src scheme
;; -------------------------------------------------------------------
;; Exercise 2.38
;; -------------------------------------------------------------------
(define fold-right accumulate)
(define (fold-left op initial sequence)
(define (iter result rest)
(if (null? rest)
result
(iter (op result (car rest))
(cdr rest))))
(iter initial sequence))
;; (fold-right / 1 (list 1 2 3))
;; 3/2
;; (fold-left / 1 (list 1 2 3))
;; 1/6
;; (fold-right list nil (list 1 2 3))
;; (((() 1) 2) 3)
;; (fold-left list nil (list 1 2 3))
;; (1 (2 (3 ())))
#+end_src
*** Exercise 2.39
Complete the following definitions of `reverse'
(*Note Exercise 2-18::) in terms of `fold-right' and `fold-left'
from *Note Exercise 2-38:::
#+begin_src scheme
(define (reverse sequence)
(fold-right (lambda (x y) <??>) nil sequence))
(define (reverse sequence)
(fold-left (lambda (x y) <??>) nil sequence))
#+end_src
----------------------------------------------------------------------
#+begin_src scheme :tangle yes
;; -------------------------------------------------------------------
;; Exercise 2.39
;; -------------------------------------------------------------------
(define (reverse sequence)
(fold-right (lambda (x y) (append y (list x))) '() sequence))
(define (reverse sequence)
(fold-left (lambda (x y) (cons y x)) '() sequence))
#+end_src