parent
3ea2479745
commit
5cc1e56aa0
@ -0,0 +1,27 @@ |
|||||||
|
|
||||||
|
Exercise 1.1: Below is a sequence of expressions. |
||||||
|
What is the result printed by the interpreter in response to each expression? |
||||||
|
Assume that the sequence is to be evaluated in the order in which it is |
||||||
|
presented. |
||||||
|
|
||||||
|
|
||||||
|
10 |
||||||
|
(+ 5 3 4) |
||||||
|
(- 9 1) |
||||||
|
(/ 6 2) |
||||||
|
(+ (* 2 4) (- 4 6)) |
||||||
|
(define a 3) |
||||||
|
(define b (+ a 1)) |
||||||
|
(+ a b (* a b)) |
||||||
|
(= a b) |
||||||
|
(if (and (> b a) (< b (* a b))) |
||||||
|
b |
||||||
|
a) |
||||||
|
(cond ((= a 4) 6) |
||||||
|
((= b 4) (+ 6 7 a)) |
||||||
|
(else 25)) |
||||||
|
(+ 2 (if (> b a) b a)) |
||||||
|
(* (cond ((> a b) a) |
||||||
|
((< a b) b) |
||||||
|
(else -1)) |
||||||
|
(+ a 1)) |
@ -0,0 +1,41 @@ |
|||||||
|
|
||||||
|
Exercise 1.10: The following procedure computes |
||||||
|
a mathematical function called Ackermann’s function. |
||||||
|
|
||||||
|
|
||||||
|
(define (A x y) |
||||||
|
(cond ((= y 0) 0) |
||||||
|
((= x 0) (* 2 y)) |
||||||
|
((= y 1) 2) |
||||||
|
(else (A (- x 1) |
||||||
|
(A x (- y 1)))))) |
||||||
|
|
||||||
|
What are the values of the following expressions? |
||||||
|
|
||||||
|
|
||||||
|
(A 1 10) |
||||||
|
(A 2 4) |
||||||
|
(A 3 3) |
||||||
|
|
||||||
|
Consider the following procedures, where A is the procedure |
||||||
|
defined above: |
||||||
|
|
||||||
|
|
||||||
|
(define (f n) (A 0 n)) |
||||||
|
(define (g n) (A 1 n)) |
||||||
|
(define (h n) (A 2 n)) |
||||||
|
(define (k n) (* 5 n n)) |
||||||
|
|
||||||
|
Give concise mathematical definitions for the functions computed by the |
||||||
|
procedures f, g, and h for positive integer values of |
||||||
|
|
||||||
|
n |
||||||
|
. For example, (k n) computes |
||||||
|
|
||||||
|
5 |
||||||
|
|
||||||
|
n |
||||||
|
2 |
||||||
|
|
||||||
|
|
||||||
|
. |
@ -0,0 +1,68 @@ |
|||||||
|
|
||||||
|
Exercise 1.11: A function |
||||||
|
f |
||||||
|
is defined by |
||||||
|
the rule that |
||||||
|
|
||||||
|
f |
||||||
|
( |
||||||
|
n |
||||||
|
) |
||||||
|
= |
||||||
|
n |
||||||
|
|
||||||
|
if |
||||||
|
|
||||||
|
n |
||||||
|
< |
||||||
|
3 |
||||||
|
|
||||||
|
and |
||||||
|
|
||||||
|
f |
||||||
|
( |
||||||
|
n |
||||||
|
) |
||||||
|
|
||||||
|
= |
||||||
|
|
||||||
|
f |
||||||
|
( |
||||||
|
n |
||||||
|
− |
||||||
|
1 |
||||||
|
) |
||||||
|
|
||||||
|
+ |
||||||
|
|
||||||
|
2 |
||||||
|
f |
||||||
|
( |
||||||
|
n |
||||||
|
− |
||||||
|
2 |
||||||
|
) |
||||||
|
|
||||||
|
+ |
||||||
|
|
||||||
|
3 |
||||||
|
f |
||||||
|
( |
||||||
|
n |
||||||
|
− |
||||||
|
3 |
||||||
|
) |
||||||
|
|
||||||
|
if |
||||||
|
|
||||||
|
n |
||||||
|
≥ |
||||||
|
3 |
||||||
|
|
||||||
|
. |
||||||
|
Write a procedure that computes |
||||||
|
f |
||||||
|
by means of a recursive process. Write a procedure that |
||||||
|
computes |
||||||
|
f |
||||||
|
by means of an iterative process. |
@ -0,0 +1,17 @@ |
|||||||
|
|
||||||
|
Exercise 1.12: The following pattern of numbers |
||||||
|
is called |
||||||
|
Pascal’s triangle. |
||||||
|
|
||||||
|
|
||||||
|
1 |
||||||
|
1 1 |
||||||
|
1 2 1 |
||||||
|
1 3 3 1 |
||||||
|
1 4 6 4 1 |
||||||
|
. . . |
||||||
|
|
||||||
|
|
||||||
|
The numbers at the edge of the triangle are all 1, and each number inside the |
||||||
|
triangle is the sum of the two numbers above it.35 Write a procedure that computes elements of Pascal’s triangle by |
||||||
|
means of a recursive process. |
@ -0,0 +1,85 @@ |
|||||||
|
|
||||||
|
Exercise 1.13: Prove that |
||||||
|
|
||||||
|
Fib |
||||||
|
( |
||||||
|
n |
||||||
|
) |
||||||
|
|
||||||
|
is |
||||||
|
the closest integer to |
||||||
|
|
||||||
|
|
||||||
|
φ |
||||||
|
n |
||||||
|
|
||||||
|
|
||||||
|
/ |
||||||
|
|
||||||
|
|
||||||
|
5 |
||||||
|
|
||||||
|
|
||||||
|
, where |
||||||
|
φ |
||||||
|
= |
||||||
|
|
||||||
|
( |
||||||
|
1 |
||||||
|
+ |
||||||
|
|
||||||
|
5 |
||||||
|
|
||||||
|
) |
||||||
|
|
||||||
|
/ |
||||||
|
|
||||||
|
2 |
||||||
|
|
||||||
|
. |
||||||
|
Hint: Let |
||||||
|
ψ |
||||||
|
= |
||||||
|
|
||||||
|
( |
||||||
|
1 |
||||||
|
− |
||||||
|
|
||||||
|
5 |
||||||
|
|
||||||
|
) |
||||||
|
|
||||||
|
/ |
||||||
|
|
||||||
|
2 |
||||||
|
|
||||||
|
. |
||||||
|
Use induction and the definition of the Fibonacci numbers (see 1.2.2) |
||||||
|
to prove that |
||||||
|
|
||||||
|
Fib |
||||||
|
( |
||||||
|
n |
||||||
|
) |
||||||
|
|
||||||
|
= |
||||||
|
|
||||||
|
( |
||||||
|
|
||||||
|
φ |
||||||
|
n |
||||||
|
|
||||||
|
− |
||||||
|
|
||||||
|
ψ |
||||||
|
n |
||||||
|
|
||||||
|
) |
||||||
|
|
||||||
|
/ |
||||||
|
|
||||||
|
|
||||||
|
5 |
||||||
|
|
||||||
|
|
||||||
|
. |
@ -0,0 +1,5 @@ |
|||||||
|
|
||||||
|
Exercise 1.14: Draw the tree illustrating the |
||||||
|
process generated by the count-change procedure of 1.2.2 |
||||||
|
in making change for 11 cents. What are the orders of growth of the space and |
||||||
|
number of steps used by this process as the amount to be changed increases? |
@ -0,0 +1,67 @@ |
|||||||
|
|
||||||
|
Exercise 1.16: Design a procedure that evolves |
||||||
|
an iterative exponentiation process that uses successive squaring and uses a |
||||||
|
logarithmic number of steps, as does fast-expt. (Hint: Using the |
||||||
|
observation that |
||||||
|
|
||||||
|
( |
||||||
|
|
||||||
|
b |
||||||
|
|
||||||
|
n |
||||||
|
|
||||||
|
/ |
||||||
|
|
||||||
|
2 |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
) |
||||||
|
2 |
||||||
|
|
||||||
|
|
||||||
|
= |
||||||
|
|
||||||
|
( |
||||||
|
|
||||||
|
b |
||||||
|
2 |
||||||
|
|
||||||
|
|
||||||
|
) |
||||||
|
|
||||||
|
n |
||||||
|
|
||||||
|
/ |
||||||
|
|
||||||
|
2 |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
, keep, along with |
||||||
|
the exponent |
||||||
|
n |
||||||
|
and the base |
||||||
|
b |
||||||
|
, an additional state variable |
||||||
|
a |
||||||
|
, and |
||||||
|
define the state transformation in such a way that the product |
||||||
|
|
||||||
|
a |
||||||
|
|
||||||
|
b |
||||||
|
n |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
is unchanged from state to state. At the beginning of the process |
||||||
|
|
||||||
|
a |
||||||
|
is taken to be 1, and the answer is given by the value of |
||||||
|
a |
||||||
|
at the |
||||||
|
end of the process. In general, the technique of defining an |
||||||
|
|
||||||
|
invariant quantity that remains unchanged from state to state is a |
||||||
|
powerful way to think about the design of iterative algorithms.) |
@ -0,0 +1,19 @@ |
|||||||
|
|
||||||
|
Exercise 1.17: The exponentiation algorithms in |
||||||
|
this section are based on performing exponentiation by means of repeated |
||||||
|
multiplication. In a similar way, one can perform integer multiplication by |
||||||
|
means of repeated addition. The following multiplication procedure (in which |
||||||
|
it is assumed that our language can only add, not multiply) is analogous to the |
||||||
|
expt procedure: |
||||||
|
|
||||||
|
|
||||||
|
(define (* a b) |
||||||
|
(if (= b 0) |
||||||
|
0 |
||||||
|
(+ a (* a (- b 1))))) |
||||||
|
|
||||||
|
This algorithm takes a number of steps that is linear in b. Now suppose |
||||||
|
we include, together with addition, operations double, which doubles an |
||||||
|
integer, and halve, which divides an (even) integer by 2. Using these, |
||||||
|
design a multiplication procedure analogous to fast-expt that uses a |
||||||
|
logarithmic number of steps. |
@ -0,0 +1,5 @@ |
|||||||
|
|
||||||
|
Exercise 1.18: Using the results of |
||||||
|
Exercise 1.16 and Exercise 1.17, devise a procedure that generates |
||||||
|
an iterative process for multiplying two integers in terms of adding, doubling, |
||||||
|
and halving and uses a logarithmic number of steps.40 |
@ -0,0 +1,203 @@ |
|||||||
|
|
||||||
|
Exercise 1.19: There is a clever algorithm for |
||||||
|
computing the Fibonacci numbers in a logarithmic number of steps. Recall the |
||||||
|
transformation of the state variables |
||||||
|
a |
||||||
|
and |
||||||
|
b |
||||||
|
in the fib-iter |
||||||
|
process of 1.2.2: |
||||||
|
a |
||||||
|
← |
||||||
|
a |
||||||
|
+ |
||||||
|
b |
||||||
|
and |
||||||
|
b |
||||||
|
← |
||||||
|
a |
||||||
|
. |
||||||
|
Call this transformation |
||||||
|
T |
||||||
|
, and observe that applying |
||||||
|
T |
||||||
|
over and over |
||||||
|
again |
||||||
|
n |
||||||
|
times, starting with 1 and 0, produces the pair |
||||||
|
|
||||||
|
Fib |
||||||
|
( |
||||||
|
n |
||||||
|
+ |
||||||
|
1 |
||||||
|
) |
||||||
|
|
||||||
|
and |
||||||
|
|
||||||
|
|
||||||
|
Fib |
||||||
|
( |
||||||
|
n |
||||||
|
) |
||||||
|
|
||||||
|
. In other words, the Fibonacci numbers are produced |
||||||
|
by applying |
||||||
|
|
||||||
|
T |
||||||
|
n |
||||||
|
|
||||||
|
, the |
||||||
|
|
||||||
|
n |
||||||
|
|
||||||
|
th |
||||||
|
|
||||||
|
|
||||||
|
power of the transformation |
||||||
|
T |
||||||
|
, |
||||||
|
starting with the pair (1, 0). Now consider |
||||||
|
T |
||||||
|
to be the special case of |
||||||
|
|
||||||
|
|
||||||
|
p |
||||||
|
= |
||||||
|
0 |
||||||
|
|
||||||
|
and |
||||||
|
|
||||||
|
q |
||||||
|
= |
||||||
|
1 |
||||||
|
|
||||||
|
in a family of transformations |
||||||
|
|
||||||
|
T |
||||||
|
|
||||||
|
p |
||||||
|
q |
||||||
|
|
||||||
|
|
||||||
|
, |
||||||
|
where |
||||||
|
|
||||||
|
T |
||||||
|
|
||||||
|
p |
||||||
|
q |
||||||
|
|
||||||
|
|
||||||
|
transforms the pair |
||||||
|
|
||||||
|
( |
||||||
|
a |
||||||
|
, |
||||||
|
b |
||||||
|
) |
||||||
|
|
||||||
|
according to |
||||||
|
|
||||||
|
a |
||||||
|
← |
||||||
|
|
||||||
|
b |
||||||
|
q |
||||||
|
|
||||||
|
+ |
||||||
|
|
||||||
|
a |
||||||
|
q |
||||||
|
|
||||||
|
+ |
||||||
|
|
||||||
|
a |
||||||
|
p |
||||||
|
|
||||||
|
and |
||||||
|
b |
||||||
|
← |
||||||
|
|
||||||
|
b |
||||||
|
p |
||||||
|
|
||||||
|
+ |
||||||
|
|
||||||
|
a |
||||||
|
q |
||||||
|
|
||||||
|
. |
||||||
|
Show that if we apply such a transformation |
||||||
|
|
||||||
|
T |
||||||
|
|
||||||
|
p |
||||||
|
q |
||||||
|
|
||||||
|
|
||||||
|
twice, the |
||||||
|
effect is the same as using a single transformation |
||||||
|
|
||||||
|
T |
||||||
|
|
||||||
|
|
||||||
|
p |
||||||
|
′ |
||||||
|
|
||||||
|
|
||||||
|
q |
||||||
|
′ |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
of the |
||||||
|
same form, and compute |
||||||
|
|
||||||
|
p |
||||||
|
′ |
||||||
|
|
||||||
|
|
||||||
|
and |
||||||
|
|
||||||
|
q |
||||||
|
′ |
||||||
|
|
||||||
|
|
||||||
|
in terms of |
||||||
|
p |
||||||
|
and |
||||||
|
q |
||||||
|
. This |
||||||
|
gives us an explicit way to square these transformations, and thus we can |
||||||
|
compute |
||||||
|
|
||||||
|
T |
||||||
|
n |
||||||
|
|
||||||
|
using successive squaring, as in the fast-expt |
||||||
|
procedure. Put this all together to complete the following procedure, which |
||||||
|
runs in a logarithmic number of steps:41 |
||||||
|
|
||||||
|
|
||||||
|
(define (fib n) |
||||||
|
(fib-iter 1 0 0 1 n)) |
||||||
|
|
||||||
|
(define (fib-iter a b p q count) |
||||||
|
(cond ((= count 0) |
||||||
|
b) |
||||||
|
((even? count) |
||||||
|
(fib-iter a |
||||||
|
b |
||||||
|
⟨??⟩ ;compute p' |
||||||
|
⟨??⟩ ;compute q' |
||||||
|
(/ count 2))) |
||||||
|
(else |
||||||
|
(fib-iter (+ (* b q) |
||||||
|
(* a q) |
||||||
|
(* a p)) |
||||||
|
(+ (* b p) |
||||||
|
(* a q)) |
||||||
|
p |
||||||
|
q |
||||||
|
(- count 1))))) |
@ -0,0 +1,47 @@ |
|||||||
|
|
||||||
|
Exercise 1.2: Translate the following expression |
||||||
|
into prefix form: |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
5 |
||||||
|
+ |
||||||
|
4 |
||||||
|
+ |
||||||
|
( |
||||||
|
2 |
||||||
|
− |
||||||
|
( |
||||||
|
3 |
||||||
|
− |
||||||
|
( |
||||||
|
6 |
||||||
|
+ |
||||||
|
|
||||||
|
4 |
||||||
|
5 |
||||||
|
|
||||||
|
) |
||||||
|
) |
||||||
|
) |
||||||
|
|
||||||
|
|
||||||
|
3 |
||||||
|
( |
||||||
|
6 |
||||||
|
− |
||||||
|
2 |
||||||
|
) |
||||||
|
( |
||||||
|
2 |
||||||
|
− |
||||||
|
7 |
||||||
|
) |
||||||
|
|
||||||
|
|
||||||
|
. |
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,11 @@ |
|||||||
|
|
||||||
|
Exercise 1.20: The process that a procedure |
||||||
|
generates is of course dependent on the rules used by the interpreter. As an |
||||||
|
example, consider the iterative gcd procedure given above. Suppose we |
||||||
|
were to interpret this procedure using normal-order evaluation, as discussed in |
||||||
|
1.1.5. (The normal-order-evaluation rule for if is |
||||||
|
described in Exercise 1.5.) Using the substitution method (for normal |
||||||
|
order), illustrate the process generated in evaluating (gcd 206 40) and |
||||||
|
indicate the remainder operations that are actually performed. How many |
||||||
|
remainder operations are actually performed in the normal-order |
||||||
|
evaluation of (gcd 206 40)? In the applicative-order evaluation? |
@ -0,0 +1,4 @@ |
|||||||
|
|
||||||
|
Exercise 1.21: Use the smallest-divisor |
||||||
|
procedure to find the smallest divisor of each of the following numbers: 199, |
||||||
|
1999, 19999. |
@ -0,0 +1,67 @@ |
|||||||
|
|
||||||
|
Exercise 1.22: Most Lisp implementations include |
||||||
|
a primitive called runtime that returns an integer that specifies the |
||||||
|
amount of time the system has been running (measured, for example, in |
||||||
|
microseconds). The following timed-prime-test procedure, when called |
||||||
|
with an integer |
||||||
|
n |
||||||
|
, prints |
||||||
|
n |
||||||
|
and checks to see if |
||||||
|
n |
||||||
|
is prime. If |
||||||
|
|
||||||
|
n |
||||||
|
is prime, the procedure prints three asterisks followed by the amount of |
||||||
|
time used in performing the test. |
||||||
|
|
||||||
|
|
||||||
|
(define (timed-prime-test n) |
||||||
|
(newline) |
||||||
|
(display n) |
||||||
|
(start-prime-test n (runtime))) |
||||||
|
|
||||||
|
|
||||||
|
(define (start-prime-test n start-time) |
||||||
|
(if (prime? n) |
||||||
|
(report-prime (- (runtime) |
||||||
|
start-time)))) |
||||||
|
|
||||||
|
|
||||||
|
(define (report-prime elapsed-time) |
||||||
|
(display " *** ") |
||||||
|
(display elapsed-time)) |
||||||
|
|
||||||
|
Using this procedure, write a procedure search-for-primes that checks |
||||||
|
the primality of consecutive odd integers in a specified range. Use your |
||||||
|
procedure to find the three smallest primes larger than 1000; larger than |
||||||
|
10,000; larger than 100,000; larger than 1,000,000. Note the time needed to |
||||||
|
test each prime. Since the testing algorithm has order of growth of |
||||||
|
|
||||||
|
|
||||||
|
Θ |
||||||
|
( |
||||||
|
|
||||||
|
n |
||||||
|
|
||||||
|
) |
||||||
|
|
||||||
|
, you should expect that testing for primes |
||||||
|
around 10,000 should take about |
||||||
|
|
||||||
|
10 |
||||||
|
|
||||||
|
times as long as testing for |
||||||
|
primes around 1000. Do your timing data bear this out? How well do the data |
||||||
|
for 100,000 and 1,000,000 support the |
||||||
|
|
||||||
|
Θ |
||||||
|
( |
||||||
|
|
||||||
|
n |
||||||
|
|
||||||
|
) |
||||||
|
|
||||||
|
prediction? Is your |
||||||
|
result compatible with the notion that programs on your machine run in time |
||||||
|
proportional to the number of steps required for the computation? |
@ -0,0 +1,16 @@ |
|||||||
|
|
||||||
|
Exercise 1.23: The smallest-divisor |
||||||
|
procedure shown at the start of this section does lots of needless testing: |
||||||
|
After it checks to see if the number is divisible by 2 there is no point in |
||||||
|
checking to see if it is divisible by any larger even numbers. This suggests |
||||||
|
that the values used for test-divisor should not be 2, 3, 4, 5, 6, |
||||||
|
…, but rather 2, 3, 5, 7, 9, …. To implement this change, define a |
||||||
|
procedure next that returns 3 if its input is equal to 2 and otherwise |
||||||
|
returns its input plus 2. Modify the smallest-divisor procedure to use |
||||||
|
(next test-divisor) instead of (+ test-divisor 1). With |
||||||
|
timed-prime-test incorporating this modified version of |
||||||
|
smallest-divisor, run the test for each of the 12 primes found in |
||||||
|
Exercise 1.22. Since this modification halves the number of test steps, |
||||||
|
you should expect it to run about twice as fast. Is this expectation |
||||||
|
confirmed? If not, what is the observed ratio of the speeds of the two |
||||||
|
algorithms, and how do you explain the fact that it is different from 2? |
@ -0,0 +1,11 @@ |
|||||||
|
|
||||||
|
Exercise 1.25: Alyssa P. Hacker complains that |
||||||
|
we went to a lot of extra work in writing expmod. After all, she says, |
||||||
|
since we already know how to compute exponentials, we could have simply written |
||||||
|
|
||||||
|
|
||||||
|
(define (expmod base exp m) |
||||||
|
(remainder (fast-expt base exp) m)) |
||||||
|
|
||||||
|
Is she correct? Would this procedure serve as well for our fast prime tester? |
||||||
|
Explain. |
@ -0,0 +1,23 @@ |
|||||||
|
|
||||||
|
Exercise 1.27: Demonstrate that the Carmichael |
||||||
|
numbers listed in Footnote 47 really do fool the Fermat test. That is, |
||||||
|
write a procedure that takes an integer |
||||||
|
n |
||||||
|
and tests whether |
||||||
|
|
||||||
|
a |
||||||
|
n |
||||||
|
|
||||||
|
is |
||||||
|
congruent to |
||||||
|
a |
||||||
|
modulo |
||||||
|
n |
||||||
|
for every |
||||||
|
|
||||||
|
a |
||||||
|
< |
||||||
|
n |
||||||
|
|
||||||
|
, and try your procedure |
||||||
|
on the given Carmichael numbers. |
@ -0,0 +1,92 @@ |
|||||||
|
|
||||||
|
Exercise 1.28: One variant of the Fermat test |
||||||
|
that cannot be fooled is called the |
||||||
|
Miller-Rabin test (Miller 1976; |
||||||
|
Rabin 1980). This starts from an alternate form of Fermat’s Little Theorem, |
||||||
|
which states that if |
||||||
|
n |
||||||
|
is a prime number and |
||||||
|
a |
||||||
|
is any positive integer |
||||||
|
less than |
||||||
|
n |
||||||
|
, then |
||||||
|
a |
||||||
|
raised to the |
||||||
|
|
||||||
|
( |
||||||
|
n |
||||||
|
− |
||||||
|
1 |
||||||
|
) |
||||||
|
|
||||||
|
-st power is congruent to 1 |
||||||
|
modulo |
||||||
|
n |
||||||
|
. To test the primality of a number |
||||||
|
n |
||||||
|
by the Miller-Rabin |
||||||
|
test, we pick a random number |
||||||
|
|
||||||
|
a |
||||||
|
< |
||||||
|
n |
||||||
|
|
||||||
|
and raise |
||||||
|
a |
||||||
|
to the |
||||||
|
|
||||||
|
( |
||||||
|
n |
||||||
|
− |
||||||
|
1 |
||||||
|
) |
||||||
|
|
||||||
|
-st |
||||||
|
power modulo |
||||||
|
n |
||||||
|
using the expmod procedure. However, whenever we |
||||||
|
perform the squaring step in expmod, we check to see if we have |
||||||
|
discovered a “nontrivial square root of 1 modulo |
||||||
|
n |
||||||
|
,” that is, a number |
||||||
|
not equal to 1 or |
||||||
|
|
||||||
|
n |
||||||
|
− |
||||||
|
1 |
||||||
|
|
||||||
|
whose square is equal to 1 modulo |
||||||
|
n |
||||||
|
. It is |
||||||
|
possible to prove that if such a nontrivial square root of 1 exists, then |
||||||
|
n |
||||||
|
|
||||||
|
is not prime. It is also possible to prove that if |
||||||
|
n |
||||||
|
is an odd number that |
||||||
|
is not prime, then, for at least half the numbers |
||||||
|
|
||||||
|
a |
||||||
|
< |
||||||
|
n |
||||||
|
|
||||||
|
, computing |
||||||
|
|
||||||
|
|
||||||
|
a |
||||||
|
|
||||||
|
n |
||||||
|
− |
||||||
|
1 |
||||||
|
|
||||||
|
|
||||||
|
in this way will reveal a nontrivial square root of 1 modulo |
||||||
|
|
||||||
|
n |
||||||
|
. (This is why the Miller-Rabin test cannot be fooled.) Modify the |
||||||
|
expmod procedure to signal if it discovers a nontrivial square root of |
||||||
|
1, and use this to implement the Miller-Rabin test with a procedure analogous |
||||||
|
to fermat-test. Check your procedure by testing various known primes |
||||||
|
and non-primes. Hint: One convenient way to make expmod signal is to |
||||||
|
have it return 0. |
@ -0,0 +1,149 @@ |
|||||||
|
|
||||||
|
Exercise 1.29: Simpson’s Rule is a more accurate |
||||||
|
method of numerical integration than the method illustrated above. Using |
||||||
|
Simpson’s Rule, the integral of a function |
||||||
|
f |
||||||
|
between |
||||||
|
a |
||||||
|
and |
||||||
|
b |
||||||
|
is |
||||||
|
approximated as |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
h |
||||||
|
3 |
||||||
|
|
||||||
|
( |
||||||
|
|
||||||
|
y |
||||||
|
0 |
||||||
|
|
||||||
|
+ |
||||||
|
|
||||||
|
4 |
||||||
|
|
||||||
|
y |
||||||
|
1 |
||||||
|
|
||||||
|
|
||||||
|
+ |
||||||
|
|
||||||
|
2 |
||||||
|
|
||||||
|
y |
||||||
|
2 |
||||||
|
|
||||||
|
|
||||||
|
+ |
||||||
|
|
||||||
|
4 |
||||||
|
|
||||||
|
y |
||||||
|
3 |
||||||
|
|
||||||
|
|
||||||
|
+ |
||||||
|
|
||||||
|
2 |
||||||
|
|
||||||
|
y |
||||||
|
4 |
||||||
|
|
||||||
|
|
||||||
|
+ |
||||||
|
⋯ |
||||||
|
+ |
||||||
|
|
||||||
|
2 |
||||||
|
|
||||||
|
y |
||||||
|
|
||||||
|
n |
||||||
|
− |
||||||
|
2 |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
+ |
||||||
|
|
||||||
|
4 |
||||||
|
|
||||||
|
y |
||||||
|
|
||||||
|
n |
||||||
|
− |
||||||
|
1 |
||||||
|
|
||||||
|
|
||||||
|
+ |
||||||
|
|
||||||
|
y |
||||||
|
n |
||||||
|
|
||||||
|
) |
||||||
|
, |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
where |
||||||
|
|
||||||
|
h |
||||||
|
= |
||||||
|
( |
||||||
|
b |
||||||
|
− |
||||||
|
a |
||||||
|
) |
||||||
|
|
||||||
|
/ |
||||||
|
|
||||||
|
n |
||||||
|
|
||||||
|
, for some even integer |
||||||
|
n |
||||||
|
, and |
||||||
|
|
||||||
|
|
||||||
|
y |
||||||
|
k |
||||||
|
|
||||||
|
= |
||||||
|
|
||||||
|
f |
||||||
|
( |
||||||
|
a |
||||||
|
+ |
||||||
|
k |
||||||
|
h |
||||||
|
) |
||||||
|
|
||||||
|
. (Increasing |
||||||
|
n |
||||||
|
increases the |
||||||
|
accuracy of the approximation.) Define a procedure that takes as arguments |
||||||
|
|
||||||
|
f |
||||||
|
, |
||||||
|
a |
||||||
|
, |
||||||
|
b |
||||||
|
, and |
||||||
|
n |
||||||
|
and returns the value of the integral, computed |
||||||
|
using Simpson’s Rule. Use your procedure to integrate cube between 0 |
||||||
|
and 1 (with |
||||||
|
|
||||||
|
n |
||||||
|
= |
||||||
|
100 |
||||||
|
|
||||||
|
and |
||||||
|
|
||||||
|
n |
||||||
|
= |
||||||
|
1000 |
||||||
|
|
||||||
|
), and compare the results to those of |
||||||
|
the integral procedure shown above. |
@ -0,0 +1,4 @@ |
|||||||
|
|
||||||
|
Exercise 1.3: Define a procedure that takes three |
||||||
|
numbers as arguments and returns the sum of the squares of the two larger |
||||||
|
numbers. |
@ -0,0 +1,13 @@ |
|||||||
|
|
||||||
|
Exercise 1.30: The sum procedure above |
||||||
|
generates a linear recursion. The procedure can be rewritten so that the sum |
||||||
|
is performed iteratively. Show how to do this by filling in the missing |
||||||
|
expressions in the following definition: |
||||||
|
|
||||||
|
|
||||||
|
(define (sum term a next b) |
||||||
|
(define (iter a result) |
||||||
|
(if ⟨??⟩ |
||||||
|
⟨??⟩ |
||||||
|
(iter ⟨??⟩ ⟨??⟩))) |
||||||
|
(iter ⟨??⟩ ⟨??⟩)) |
@ -0,0 +1,63 @@ |
|||||||
|
|
||||||
|
Exercise 1.31: |
||||||
|
|
||||||
|
|
||||||
|
The sum procedure is only the simplest of a vast number of similar |
||||||
|
abstractions that can be captured as higher-order procedures.51 Write an analogous |
||||||
|
procedure called product that returns the product of the values of a |
||||||
|
function at points over a given range. Show how to define factorial in |
||||||
|
terms of product. Also use product to compute approximations to |
||||||
|
|
||||||
|
π |
||||||
|
using the formula52 |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
π |
||||||
|
4 |
||||||
|
|
||||||
|
|
||||||
|
= |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2 |
||||||
|
⋅ |
||||||
|
4 |
||||||
|
⋅ |
||||||
|
4 |
||||||
|
⋅ |
||||||
|
6 |
||||||
|
⋅ |
||||||
|
6 |
||||||
|
⋅ |
||||||
|
8 |
||||||
|
⋅ |
||||||
|
⋯ |
||||||
|
|
||||||
|
|
||||||
|
3 |
||||||
|
⋅ |
||||||
|
3 |
||||||
|
⋅ |
||||||
|
5 |
||||||
|
⋅ |
||||||
|
5 |
||||||
|
⋅ |
||||||
|
7 |
||||||
|
⋅ |
||||||
|
7 |
||||||
|
⋅ |
||||||
|
⋯ |
||||||
|
|
||||||
|
|
||||||
|
. |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
If your product procedure generates a recursive process, write one that |
||||||
|
generates an iterative process. If it generates an iterative process, write |
||||||
|
one that generates a recursive process. |
||||||
|
|
||||||
|
|
@ -0,0 +1,25 @@ |
|||||||
|
|
||||||
|
Exercise 1.32: |
||||||
|
|
||||||
|
|
||||||
|
Show that sum and product (Exercise 1.31) are both special |
||||||
|
cases of a still more general notion called accumulate that combines a |
||||||
|
collection of terms, using some general accumulation function: |
||||||
|
|
||||||
|
|
||||||
|
(accumulate |
||||||
|
combiner null-value term a next b) |
||||||
|
|
||||||
|
Accumulate takes as arguments the same term and range specifications as |
||||||
|
sum and product, together with a combiner procedure (of |
||||||
|
two arguments) that specifies how the current term is to be combined with the |
||||||
|
accumulation of the preceding terms and a null-value that specifies what |
||||||
|
base value to use when the terms run out. Write accumulate and show how |
||||||
|
sum and product can both be defined as simple calls to |
||||||
|
accumulate. |
||||||
|
|
||||||
|
If your accumulate procedure generates a recursive process, write one |
||||||
|
that generates an iterative process. If it generates an iterative process, |
||||||
|
write one that generates a recursive process. |
||||||
|
|
||||||
|
|
@ -0,0 +1,45 @@ |
|||||||
|
|
||||||
|
Exercise 1.33: You can obtain an even more |
||||||
|
general version of accumulate (Exercise 1.32) by introducing the |
||||||
|
notion of a |
||||||
|
filter on the terms to be combined. That is, combine |
||||||
|
only those terms derived from values in the range that satisfy a specified |
||||||
|
condition. The resulting filtered-accumulate abstraction takes the same |
||||||
|
arguments as accumulate, together with an additional predicate of one argument |
||||||
|
that specifies the filter. Write filtered-accumulate as a procedure. |
||||||
|
Show how to express the following using filtered-accumulate: |
||||||
|
|
||||||
|
|
||||||
|
the sum of the squares of the prime numbers in the interval |
||||||
|
a |
||||||
|
to |
||||||
|
b |
||||||
|
|
||||||
|
(assuming that you have a prime? predicate already written) |
||||||
|
|
||||||
|
the product of all the positive integers less than |
||||||
|
n |
||||||
|
that are relatively |
||||||
|
prime to |
||||||
|
n |
||||||
|
(i.e., all positive integers |
||||||
|
|
||||||
|
i |
||||||
|
< |
||||||
|
n |
||||||
|
|
||||||
|
such that |
||||||
|
|
||||||
|
|
||||||
|
GCD |
||||||
|
( |
||||||
|
i |
||||||
|
, |
||||||
|
n |
||||||
|
) |
||||||
|
= |
||||||
|
1 |
||||||
|
|
||||||
|
). |
||||||
|
|
||||||
|
|
@ -0,0 +1,18 @@ |
|||||||
|
|
||||||
|
Exercise 1.34: Suppose we define the procedure |
||||||
|
|
||||||
|
|
||||||
|
(define (f g) (g 2)) |
||||||
|
|
||||||
|
Then we have |
||||||
|
|
||||||
|
|
||||||
|
(f square) |
||||||
|
4 |
||||||
|
|
||||||
|
(f (lambda (z) (* z (+ z 1)))) |
||||||
|
6 |
||||||
|
|
||||||
|
|
||||||
|
What happens if we (perversely) ask the interpreter to evaluate the combination |
||||||
|
(f f)? Explain. |
@ -0,0 +1,21 @@ |
|||||||
|
|
||||||
|
Exercise 1.35: Show that the golden ratio |
||||||
|
|
||||||
|
φ |
||||||
|
(1.2.2) is a fixed point of the transformation |
||||||
|
|
||||||
|
|
||||||
|
x |
||||||
|
↦ |
||||||
|
1 |
||||||
|
+ |
||||||
|
1 |
||||||
|
|
||||||
|
/ |
||||||
|
|
||||||
|
x |
||||||
|
|
||||||
|
, and use this fact to compute |
||||||
|
φ |
||||||
|
by means |
||||||
|
of the fixed-point procedure. |
@ -0,0 +1,166 @@ |
|||||||
|
|
||||||
|
Exercise 1.37: |
||||||
|
|
||||||
|
|
||||||
|
An infinite |
||||||
|
continued fraction is an expression of the form |
||||||
|
|
||||||
|
|
||||||
|
f |
||||||
|
|
||||||
|
= |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
N |
||||||
|
1 |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
D |
||||||
|
1 |
||||||
|
|
||||||
|
+ |
||||||
|
|
||||||
|
|
||||||
|
N |
||||||
|
2 |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
D |
||||||
|
2 |
||||||
|
|
||||||
|
+ |
||||||
|
|
||||||
|
|
||||||
|
N |
||||||
|
3 |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
D |
||||||
|
3 |
||||||
|
|
||||||
|
+ |
||||||
|
… |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
. |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
As an example, one can show that the infinite continued fraction expansion with |
||||||
|
the |
||||||
|
|
||||||
|
N |
||||||
|
i |
||||||
|
|
||||||
|
and the |
||||||
|
|
||||||
|
D |
||||||
|
i |
||||||
|
|
||||||
|
all equal to 1 produces |
||||||
|
|
||||||
|
1 |
||||||
|
|
||||||
|
/ |
||||||
|
|
||||||
|
φ |
||||||
|
|
||||||
|
, where |
||||||
|
|
||||||
|
φ |
||||||
|
is the golden ratio (described in 1.2.2). One way to |
||||||
|
approximate an infinite continued fraction is to truncate the expansion after a |
||||||
|
given number of terms. Such a truncation—a so-called |
||||||
|
finite continued fraction |
||||||
|
k-term |
||||||
|
finite continued fraction—has the form |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
N |
||||||
|
1 |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
D |
||||||
|
1 |
||||||
|
|
||||||
|
+ |
||||||
|
|
||||||
|
|
||||||
|
N |
||||||
|
2 |
||||||
|
|
||||||
|
|
||||||
|
⋱ |
||||||
|
+ |
||||||
|
|
||||||
|
|
||||||
|
N |
||||||
|
k |
||||||
|
|
||||||
|
|
||||||
|
D |
||||||
|
k |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
. |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Suppose that n and d are procedures of one argument (the term |
||||||
|
index |
||||||
|
i |
||||||
|
) that return the |
||||||
|
|
||||||
|
N |
||||||
|
i |
||||||
|
|
||||||
|
and |
||||||
|
|
||||||
|
D |
||||||
|
i |
||||||
|
|
||||||
|
of the terms of the |
||||||
|
continued fraction. Define a procedure cont-frac such that evaluating |
||||||
|
(cont-frac n d k) computes the value of the |
||||||
|
k |
||||||
|
-term finite continued |
||||||
|
fraction. Check your procedure by approximating |
||||||
|
|
||||||
|
1 |
||||||
|
|
||||||
|
/ |
||||||
|
|
||||||
|
φ |
||||||
|
|
||||||
|
using |
||||||
|
|
||||||
|
|
||||||
|
(cont-frac (lambda (i) 1.0) |
||||||
|
(lambda (i) 1.0) |
||||||
|
k) |
||||||
|
|
||||||
|
for successive values of k. How large must you make k in order |
||||||
|
to get an approximation that is accurate to 4 decimal places? |
||||||
|
|
||||||
|
If your cont-frac procedure generates a recursive process, write one |
||||||
|
that generates an iterative process. If it generates an iterative process, |
||||||
|
write one that generates a recursive process. |
||||||
|
|
||||||
|
|
@ -0,0 +1,28 @@ |
|||||||
|
|
||||||
|
Exercise 1.38: In 1737, the Swiss mathematician |
||||||
|
Leonhard Euler published a memoir De Fractionibus Continuis, which |
||||||
|
included a continued fraction expansion for |
||||||
|
|
||||||
|
e |
||||||
|
− |
||||||
|
2 |
||||||
|
|
||||||
|
, where |
||||||
|
e |
||||||
|
is the base |
||||||
|
of the natural logarithms. In this fraction, the |
||||||
|
|
||||||
|
N |
||||||
|
i |
||||||
|
|
||||||
|
are all 1, and |
||||||
|
the |
||||||
|
|
||||||
|
D |
||||||
|
i |
||||||
|
|
||||||
|
are successively 1, 2, 1, 1, 4, 1, 1, 6, 1, 1, 8, …. |
||||||
|
Write a program that uses your cont-frac procedure from Exercise 1.37 |
||||||
|
to approximate |
||||||
|
e |
||||||
|
, based on Euler’s expansion. |
@ -0,0 +1,8 @@ |
|||||||
|
|
||||||
|
Exercise 1.4: Observe that our model of |
||||||
|
evaluation allows for combinations whose operators are compound expressions. |
||||||
|
Use this observation to describe the behavior of the following procedure: |
||||||
|
|
||||||
|
|
||||||
|
(define (a-plus-abs-b a b) |
||||||
|
((if (> b 0) + -) a b)) |
@ -0,0 +1,27 @@ |
|||||||
|
|
||||||
|
Exercise 1.40: Define a procedure cubic |
||||||
|
that can be used together with the newtons-method procedure in |
||||||
|
expressions of the form |
||||||
|
|
||||||
|
|
||||||
|
(newtons-method (cubic a b c) 1) |
||||||
|
|
||||||
|
to approximate zeros of the cubic |
||||||
|
|
||||||
|
|
||||||
|
x |
||||||
|
3 |
||||||
|
|
||||||
|
+ |
||||||
|
a |
||||||
|
|
||||||
|
x |
||||||
|
2 |
||||||
|
|
||||||
|
+ |
||||||
|
b |
||||||
|
x |
||||||
|
+ |
||||||
|
c |
||||||
|
|
||||||
|
. |
@ -0,0 +1,9 @@ |
|||||||
|
|
||||||
|
Exercise 1.41: Define a procedure double |
||||||
|
that takes a procedure of one argument as argument and returns a procedure that |
||||||
|
applies the original procedure twice. For example, if inc is a |
||||||
|
procedure that adds 1 to its argument, then (double inc) should be a |
||||||
|
procedure that adds 2. What value is returned by |
||||||
|
|
||||||
|
|
||||||
|
(((double (double double)) inc) 5) |
@ -0,0 +1,32 @@ |
|||||||
|
|
||||||
|
Exercise 1.42: Let |
||||||
|
f |
||||||
|
and |
||||||
|
g |
||||||
|
be two |
||||||
|
one-argument functions. The |
||||||
|
composition |
||||||
|
f |
||||||
|
after |
||||||
|
g |
||||||
|
is defined |
||||||
|
to be the function |
||||||
|
|
||||||
|
x |
||||||
|
↦ |
||||||
|
f |
||||||
|
( |
||||||
|
g |
||||||
|
( |
||||||
|
x |
||||||
|
) |
||||||
|
) |
||||||
|
|
||||||
|
. Define a procedure |
||||||
|
compose that implements composition. For example, if inc is a |
||||||
|
procedure that adds 1 to its argument, |
||||||
|
|
||||||
|
|
||||||
|
((compose square inc) 6) |
||||||
|
49 |
||||||
|
|
@ -0,0 +1,110 @@ |
|||||||
|
|
||||||
|
Exercise 1.43: If |
||||||
|
f |
||||||
|
is a numerical function |
||||||
|
and |
||||||
|
n |
||||||
|
is a positive integer, then we can form the |
||||||
|
|
||||||
|
n |
||||||
|
|
||||||
|
th |
||||||
|
|
||||||
|
|
||||||
|
repeated |
||||||
|
application of |
||||||
|
f |
||||||
|
, which is defined to be the function whose value at |
||||||
|
x |
||||||
|
|
||||||
|
is |
||||||
|
|
||||||
|
f |
||||||
|
( |
||||||
|
f |
||||||
|
( |
||||||
|
… |
||||||
|
( |
||||||
|
f |
||||||
|
( |
||||||
|
x |
||||||
|
) |
||||||
|
) |
||||||
|
… |
||||||
|
) |
||||||
|
) |
||||||
|
|
||||||
|
. For example, if |
||||||
|
f |
||||||
|
is the |
||||||
|
function |
||||||
|
|
||||||
|
x |
||||||
|
↦ |
||||||
|
x |
||||||
|
+ |
||||||
|
1 |
||||||
|
|
||||||
|
, then the |
||||||
|
|
||||||
|
n |
||||||
|
|
||||||
|
th |
||||||
|
|
||||||
|
|
||||||
|
repeated application of |
||||||
|
f |
||||||
|
is |
||||||
|
the function |
||||||
|
|
||||||
|
x |
||||||
|
↦ |
||||||
|
x |
||||||
|
+ |
||||||
|
n |
||||||
|
|
||||||
|
. If |
||||||
|
f |
||||||
|
is the operation of squaring a |
||||||
|
number, then the |
||||||
|
|
||||||
|
n |
||||||
|
|
||||||
|
th |
||||||
|
|
||||||
|
|
||||||
|
repeated application of |
||||||
|
f |
||||||
|
is the function that |
||||||
|
raises its argument to the |
||||||
|
|
||||||
|
|
||||||
|
2 |
||||||
|
n |
||||||
|
|
||||||
|
-th |
||||||
|
|
||||||
|
power. Write a procedure that takes as |
||||||
|
inputs a procedure that computes |
||||||
|
f |
||||||
|
and a positive integer |
||||||
|
n |
||||||
|
and returns |
||||||
|
the procedure that computes the |
||||||
|
|
||||||
|
n |
||||||
|
|
||||||
|
th |
||||||
|
|
||||||
|
|
||||||
|
repeated application of |
||||||
|
f |
||||||
|
. Your |
||||||
|
procedure should be able to be used as follows: |
||||||
|
|
||||||
|
|
||||||
|
((repeated square 2) 5) |
||||||
|
625 |
||||||
|
|
||||||
|
|
||||||
|
Hint: You may find it convenient to use compose from Exercise 1.42. |
@ -0,0 +1,56 @@ |
|||||||
|
|
||||||
|
Exercise 1.44: The idea of |
||||||
|
smoothing a |
||||||
|
function is an important concept in signal processing. If |
||||||
|
f |
||||||
|
is a function |
||||||
|
and |
||||||
|
|
||||||
|
d |
||||||
|
x |
||||||
|
|
||||||
|
is some small number, then the smoothed version of |
||||||
|
f |
||||||
|
is the |
||||||
|
function whose value at a point |
||||||
|
x |
||||||
|
is the average of |
||||||
|
|
||||||
|
f |
||||||
|
( |
||||||
|
x |
||||||
|
− |
||||||
|
d |
||||||
|
x |
||||||
|
) |
||||||
|
|
||||||
|
, |
||||||
|
|
||||||
|
|
||||||
|
f |
||||||
|
( |
||||||
|
x |
||||||
|
) |
||||||
|
|
||||||
|
, and |
||||||
|
|
||||||
|
f |
||||||
|
( |
||||||
|
x |
||||||
|
+ |
||||||
|
d |
||||||
|
x |
||||||
|
) |
||||||
|
|
||||||
|
. Write a procedure |
||||||
|
smooth that takes as input a procedure that computes |
||||||
|
f |
||||||
|
and returns a |
||||||
|
procedure that computes the smoothed |
||||||
|
f |
||||||
|
. It is sometimes valuable to |
||||||
|
repeatedly smooth a function (that is, smooth the smoothed function, and so on) |
||||||
|
to obtain the |
||||||
|
n-fold smoothed function. Show how to generate |
||||||
|
the n-fold smoothed function of any given function using smooth and |
||||||
|
repeated from Exercise 1.43. |
@ -0,0 +1,97 @@ |
|||||||
|
|
||||||
|
Exercise 1.45: We saw in 1.3.3 |
||||||
|
that attempting to compute square roots by naively finding a fixed point of |
||||||
|
|
||||||
|
|
||||||
|
y |
||||||
|
↦ |
||||||
|
x |
||||||
|
|
||||||
|
/ |
||||||
|
|
||||||
|
y |
||||||
|
|
||||||
|
does not converge, and that this can be fixed by average |
||||||
|
damping. The same method works for finding cube roots as fixed points of the |
||||||
|
average-damped |
||||||
|
|
||||||
|
y |
||||||
|
↦ |
||||||
|
x |
||||||
|
|
||||||
|
/ |
||||||
|
|
||||||
|
|
||||||
|
y |
||||||
|
2 |
||||||
|
|
||||||
|
|
||||||
|
. Unfortunately, the process does not |
||||||
|
work for fourth roots—a single average damp is not enough to make a |
||||||
|
fixed-point search for |
||||||
|
|
||||||
|
y |
||||||
|
↦ |
||||||
|
x |
||||||
|
|
||||||
|
/ |
||||||
|
|
||||||
|
|
||||||
|
y |
||||||
|
3 |
||||||
|
|
||||||
|
|
||||||
|
converge. On the other hand, if |
||||||
|
we average damp twice (i.e., use the average damp of the average damp of |
||||||
|
|
||||||
|
|
||||||
|
y |
||||||
|
↦ |
||||||
|
x |
||||||
|
|
||||||
|
/ |
||||||
|
|
||||||
|
|
||||||
|
y |
||||||
|
3 |
||||||
|
|
||||||
|
|
||||||
|
) the fixed-point search does converge. Do some experiments |
||||||
|
to determine how many average damps are required to compute |
||||||
|
|
||||||
|
n |
||||||
|
|
||||||
|
th |
||||||
|
|
||||||
|
|
||||||
|
roots as a |
||||||
|
fixed-point search based upon repeated average damping of |
||||||
|
|
||||||
|
y |
||||||
|
↦ |
||||||
|
x |
||||||
|
|
||||||
|
/ |
||||||
|
|
||||||
|
|
||||||
|
y |
||||||
|
|
||||||
|
|
||||||
|
n |
||||||
|
− |
||||||
|
1 |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
. |
||||||
|
Use this to implement a simple procedure for computing |
||||||
|
|
||||||
|
|
||||||
|
n |
||||||
|
|
||||||
|
th |
||||||
|
|
||||||
|
|
||||||
|
roots using fixed-point, average-damp, and the |
||||||
|
repeated procedure of Exercise 1.43. Assume that any arithmetic |
||||||
|
operations you need are available as primitives. |
@ -0,0 +1,15 @@ |
|||||||
|
|
||||||
|
Exercise 1.46: Several of the numerical methods |
||||||
|
described in this chapter are instances of an extremely general computational |
||||||
|
strategy known as |
||||||
|
iterative improvement. Iterative improvement says |
||||||
|
that, to compute something, we start with an initial guess for the answer, test |
||||||
|
if the guess is good enough, and otherwise improve the guess and continue the |
||||||
|
process using the improved guess as the new guess. Write a procedure |
||||||
|
iterative-improve that takes two procedures as arguments: a method for |
||||||
|
telling whether a guess is good enough and a method for improving a guess. |
||||||
|
Iterative-improve should return as its value a procedure that takes a |
||||||
|
guess as argument and keeps improving the guess until it is good enough. |
||||||
|
Rewrite the sqrt procedure of 1.1.7 and the |
||||||
|
fixed-point procedure of 1.3.3 in terms of |
||||||
|
iterative-improve. |
@ -0,0 +1,26 @@ |
|||||||
|
|
||||||
|
Exercise 1.5: Ben Bitdiddle has invented a test |
||||||
|
to determine whether the interpreter he is faced with is using |
||||||
|
applicative-order evaluation or normal-order evaluation. He defines the |
||||||
|
following two procedures: |
||||||
|
|
||||||
|
|
||||||
|
(define (p) (p)) |
||||||
|
|
||||||
|
(define (test x y) |
||||||
|
(if (= x 0) |
||||||
|
0 |
||||||
|
y)) |
||||||
|
|
||||||
|
Then he evaluates the expression |
||||||
|
|
||||||
|
|
||||||
|
(test 0 (p)) |
||||||
|
|
||||||
|
What behavior will Ben observe with an interpreter that uses applicative-order |
||||||
|
evaluation? What behavior will he observe with an interpreter that uses |
||||||
|
normal-order evaluation? Explain your answer. (Assume that the evaluation |
||||||
|
rule for the special form if is the same whether the interpreter is |
||||||
|
using normal or applicative order: The predicate expression is evaluated first, |
||||||
|
and the result determines whether to evaluate the consequent or the alternative |
||||||
|
expression.) |
@ -0,0 +1,34 @@ |
|||||||
|
|
||||||
|
Exercise 1.6: Alyssa P. Hacker doesn’t see why |
||||||
|
if needs to be provided as a special form. “Why can’t I just define it |
||||||
|
as an ordinary procedure in terms of cond?” she asks. Alyssa’s friend |
||||||
|
Eva Lu Ator claims this can indeed be done, and she defines a new version of |
||||||
|
if: |
||||||
|
|
||||||
|
|
||||||
|
(define (new-if predicate |
||||||
|
then-clause |
||||||
|
else-clause) |
||||||
|
(cond (predicate then-clause) |
||||||
|
(else else-clause))) |
||||||
|
|
||||||
|
Eva demonstrates the program for Alyssa: |
||||||
|
|
||||||
|
|
||||||
|
(new-if (= 2 3) 0 5) |
||||||
|
5 |
||||||
|
|
||||||
|
(new-if (= 1 1) 0 5) |
||||||
|
0 |
||||||
|
|
||||||
|
|
||||||
|
Delighted, Alyssa uses new-if to rewrite the square-root program: |
||||||
|
|
||||||
|
|
||||||
|
(define (sqrt-iter guess x) |
||||||
|
(new-if (good-enough? guess x) |
||||||
|
guess |
||||||
|
(sqrt-iter (improve guess x) x))) |
||||||
|
|
||||||
|
What happens when Alyssa attempts to use this to compute square roots? |
||||||
|
Explain. |
@ -0,0 +1,11 @@ |
|||||||
|
|
||||||
|
Exercise 1.7: The good-enough? test used |
||||||
|
in computing square roots will not be very effective for finding the square |
||||||
|
roots of very small numbers. Also, in real computers, arithmetic operations |
||||||
|
are almost always performed with limited precision. This makes our test |
||||||
|
inadequate for very large numbers. Explain these statements, with examples |
||||||
|
showing how the test fails for small and large numbers. An alternative |
||||||
|
strategy for implementing good-enough? is to watch how guess |
||||||
|
changes from one iteration to the next and to stop when the change is a very |
||||||
|
small fraction of the guess. Design a square-root procedure that uses this |
||||||
|
kind of end test. Does this work better for small and large numbers? |
@ -0,0 +1,37 @@ |
|||||||
|
|
||||||
|
Exercise 1.8: Newton’s method for cube roots is |
||||||
|
based on the fact that if |
||||||
|
y |
||||||
|
is an approximation to the cube root of |
||||||
|
x |
||||||
|
, |
||||||
|
then a better approximation is given by the value |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
x |
||||||
|
|
||||||
|
/ |
||||||
|
|
||||||
|
|
||||||
|
y |
||||||
|
2 |
||||||
|
|
||||||
|
|
||||||
|
+ |
||||||
|
2 |
||||||
|
y |
||||||
|
|
||||||
|
3 |
||||||
|
|
||||||
|
. |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Use this formula to implement a cube-root procedure analogous to the |
||||||
|
square-root procedure. (In 1.3.4 we will see how to implement |
||||||
|
Newton’s method in general as an abstraction of these square-root and cube-root |
||||||
|
procedures.) |
@ -0,0 +1,20 @@ |
|||||||
|
|
||||||
|
Exercise 1.9: Each of the following two |
||||||
|
procedures defines a method for adding two positive integers in terms of the |
||||||
|
procedures inc, which increments its argument by 1, and dec, |
||||||
|
which decrements its argument by 1. |
||||||
|
|
||||||
|
|
||||||
|
(define (+ a b) |
||||||
|
(if (= a 0) |
||||||
|
b |
||||||
|
(inc (+ (dec a) b)))) |
||||||
|
|
||||||
|
(define (+ a b) |
||||||
|
(if (= a 0) |
||||||
|
b |
||||||
|
(+ (dec a) (inc b)))) |
||||||
|
|
||||||
|
Using the substitution model, illustrate the process generated by each |
||||||
|
procedure in evaluating (+ 4 5). Are these processes iterative or |
||||||
|
recursive? |
@ -0,0 +1,6 @@ |
|||||||
|
|
||||||
|
Exercise 2.1: Define a better version of |
||||||
|
make-rat that handles both positive and negative arguments. |
||||||
|
Make-rat should normalize the sign so that if the rational number is |
||||||
|
positive, both the numerator and denominator are positive, and if the rational |
||||||
|
number is negative, only the numerator is negative. |
@ -0,0 +1,5 @@ |
|||||||
|
|
||||||
|
Exercise 2.10: Ben Bitdiddle, an expert systems |
||||||
|
programmer, looks over Alyssa’s shoulder and comments that it is not clear what |
||||||
|
it means to divide by an interval that spans zero. Modify Alyssa’s code to |
||||||
|
check for this condition and to signal an error if it occurs. |
@ -0,0 +1,35 @@ |
|||||||
|
|
||||||
|
Exercise 2.11: In passing, Ben also cryptically |
||||||
|
comments: “By testing the signs of the endpoints of the intervals, it is |
||||||
|
possible to break mul-interval into nine cases, only one of which |
||||||
|
requires more than two multiplications.” Rewrite this procedure using Ben’s |
||||||
|
suggestion. |
||||||
|
|
||||||
|
After debugging her program, Alyssa shows it to a potential user, who complains |
||||||
|
that her program solves the wrong problem. He wants a program that can deal |
||||||
|
with numbers represented as a center value and an additive tolerance; for |
||||||
|
example, he wants to work with intervals such as 3.5 |
||||||
|
± |
||||||
|
0.15 rather than |
||||||
|
[3.35, 3.65]. Alyssa returns to her desk and fixes this problem by supplying |
||||||
|
an alternate constructor and alternate selectors: |
||||||
|
|
||||||
|
|
||||||
|
(define (make-center-width c w) |
||||||
|
(make-interval (- c w) (+ c w))) |
||||||
|
|
||||||
|
(define (center i) |
||||||
|
(/ (+ (lower-bound i) |
||||||
|
(upper-bound i)) |
||||||
|
2)) |
||||||
|
|
||||||
|
(define (width i) |
||||||
|
(/ (- (upper-bound i) |
||||||
|
(lower-bound i)) |
||||||
|
2)) |
||||||
|
|
||||||
|
Unfortunately, most of Alyssa’s users are engineers. Real engineering |
||||||
|
situations usually involve measurements with only a small uncertainty, measured |
||||||
|
as the ratio of the width of the interval to the midpoint of the interval. |
||||||
|
Engineers usually specify percentage tolerances on the parameters of devices, |
||||||
|
as in the resistor specifications given earlier. |
@ -0,0 +1,6 @@ |
|||||||
|
|
||||||
|
Exercise 2.12: Define a constructor |
||||||
|
make-center-percent that takes a center and a percentage tolerance and |
||||||
|
produces the desired interval. You must also define a selector percent |
||||||
|
that produces the percentage tolerance for a given interval. The center |
||||||
|
selector is the same as the one shown above. |
@ -0,0 +1,88 @@ |
|||||||
|
|
||||||
|
Exercise 2.13: Show that under the assumption of |
||||||
|
small percentage tolerances there is a simple formula for the approximate |
||||||
|
percentage tolerance of the product of two intervals in terms of the tolerances |
||||||
|
of the factors. You may simplify the problem by assuming that all numbers are |
||||||
|
positive. |
||||||
|
|
||||||
|
After considerable work, Alyssa P. Hacker delivers her finished system. |
||||||
|
Several years later, after she has forgotten all about it, she gets a frenzied |
||||||
|
call from an irate user, Lem E. Tweakit. It seems that Lem has noticed that |
||||||
|
the formula for parallel resistors can be written in two algebraically |
||||||
|
equivalent ways: |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R |
||||||
|
1 |
||||||
|
|
||||||
|
|
||||||
|
R |
||||||
|
2 |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R |
||||||
|
1 |
||||||
|
|
||||||
|
+ |
||||||
|
|
||||||
|
R |
||||||
|
2 |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
and |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
1 |
||||||
|
|
||||||
|
1 |
||||||
|
|
||||||
|
/ |
||||||
|
|
||||||
|
|
||||||
|
R |
||||||
|
1 |
||||||
|
|
||||||
|
+ |
||||||
|
1 |
||||||
|
|
||||||
|
/ |
||||||
|
|
||||||
|
|
||||||
|
R |
||||||
|
2 |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
. |
||||||
|
|
||||||
|
|
||||||
|
He has written the following two programs, each of which computes the |
||||||
|
parallel-resistors formula differently: |
||||||
|
|
||||||
|
|
||||||
|
(define (par1 r1 r2) |
||||||
|
(div-interval |
||||||
|
(mul-interval r1 r2) |
||||||
|
(add-interval r1 r2))) |
||||||
|
|
||||||
|
(define (par2 r1 r2) |
||||||
|
(let ((one (make-interval 1 1))) |
||||||
|
(div-interval |
||||||
|
one |
||||||
|
(add-interval |
||||||
|
(div-interval one r1) |
||||||
|
(div-interval one r2))))) |
||||||
|
|
||||||
|
Lem complains that Alyssa’s program gives different answers for the two ways of |
||||||
|
computing. This is a serious complaint. |
@ -0,0 +1,27 @@ |
|||||||
|
|
||||||
|
Exercise 2.14: Demonstrate that Lem is right. |
||||||
|
Investigate the behavior of the system on a variety of arithmetic |
||||||
|
expressions. Make some intervals |
||||||
|
A |
||||||
|
and |
||||||
|
B |
||||||
|
, and use them in computing the |
||||||
|
expressions |
||||||
|
|
||||||
|
A |
||||||
|
|
||||||
|
/ |
||||||
|
|
||||||
|
A |
||||||
|
|
||||||
|
and |
||||||
|
|
||||||
|
A |
||||||
|
|
||||||
|
/ |
||||||
|
|
||||||
|
B |
||||||
|
|
||||||
|
. You will get the most insight by |
||||||
|
using intervals whose width is a small percentage of the center value. Examine |
||||||
|
the results of the computation in center-percent form (see Exercise 2.12). |
@ -0,0 +1,8 @@ |
|||||||
|
|
||||||
|
Exercise 2.15: Eva Lu Ator, another user, has |
||||||
|
also noticed the different intervals computed by different but algebraically |
||||||
|
equivalent expressions. She says that a formula to compute with intervals using |
||||||
|
Alyssa’s system will produce tighter error bounds if it can be written in such |
||||||
|
a form that no variable that represents an uncertain number is repeated. Thus, |
||||||
|
she says, par2 is a “better” program for parallel resistances than |
||||||
|
par1. Is she right? Why? |
@ -0,0 +1,5 @@ |
|||||||
|
|
||||||
|
Exercise 2.16: Explain, in general, why |
||||||
|
equivalent algebraic expressions may lead to different answers. Can you devise |
||||||
|
an interval-arithmetic package that does not have this shortcoming, or is this |
||||||
|
task impossible? (Warning: This problem is very difficult.) |
@ -0,0 +1,9 @@ |
|||||||
|
|
||||||
|
Exercise 2.17: Define a procedure |
||||||
|
last-pair that returns the list that contains only the last element of a |
||||||
|
given (nonempty) list: |
||||||
|
|
||||||
|
|
||||||
|
(last-pair (list 23 72 149 34)) |
||||||
|
(34) |
||||||
|
|
@ -0,0 +1,9 @@ |
|||||||
|
|
||||||
|
Exercise 2.18: Define a procedure reverse |
||||||
|
that takes a list as argument and returns a list of the same elements in |
||||||
|
reverse order: |
||||||
|
|
||||||
|
|
||||||
|
(reverse (list 1 4 9 16 25)) |
||||||
|
(25 16 9 4 1) |
||||||
|
|
@ -0,0 +1,54 @@ |
|||||||
|
|
||||||
|
Exercise 2.19: Consider the change-counting |
||||||
|
program of 1.2.2. It would be nice to be able to easily change |
||||||
|
the currency used by the program, so that we could compute the number of ways |
||||||
|
to change a British pound, for example. As the program is written, the |
||||||
|
knowledge of the currency is distributed partly into the procedure |
||||||
|
first-denomination and partly into the procedure count-change |
||||||
|
(which knows that there are five kinds of U.S. coins). It would be nicer to be |
||||||
|
able to supply a list of coins to be used for making change. |
||||||
|
|
||||||
|
We want to rewrite the procedure cc so that its second argument is a |
||||||
|
list of the values of the coins to use rather than an integer specifying which |
||||||
|
coins to use. We could then have lists that defined each kind of currency: |
||||||
|
|
||||||
|
|
||||||
|
(define us-coins |
||||||
|
(list 50 25 10 5 1)) |
||||||
|
|
||||||
|
(define uk-coins |
||||||
|
(list 100 50 20 10 5 2 1 0.5)) |
||||||
|
|
||||||
|
We could then call cc as follows: |
||||||
|
|
||||||
|
|
||||||
|
(cc 100 us-coins) |
||||||
|
292 |
||||||
|
|
||||||
|
|
||||||
|
To do this will require changing the program cc somewhat. It will still |
||||||
|
have the same form, but it will access its second argument differently, as |
||||||
|
follows: |
||||||
|
|
||||||
|
|
||||||
|
(define (cc amount coin-values) |
||||||
|
(cond ((= amount 0) |
||||||
|
1) |
||||||
|
((or (< amount 0) |
||||||
|
(no-more? coin-values)) |
||||||
|
0) |
||||||
|
(else |
||||||
|
(+ (cc |
||||||
|
amount |
||||||
|
(except-first-denomination |
||||||
|
coin-values)) |
||||||
|
(cc |
||||||
|
(- amount |
||||||
|
(first-denomination |
||||||
|
coin-values)) |
||||||
|
coin-values))))) |
||||||
|
|
||||||
|
Define the procedures first-denomination, |
||||||
|
except-first-denomination and no-more? in terms of primitive |
||||||
|
operations on list structures. Does the order of the list coin-values |
||||||
|
affect the answer produced by cc? Why or why not? |
@ -0,0 +1,26 @@ |
|||||||
|
|
||||||
|
Exercise 2.2: Consider the problem of |
||||||
|
representing line segments in a plane. Each segment is represented as a pair |
||||||
|
of points: a starting point and an ending point. Define a constructor |
||||||
|
make-segment and selectors start-segment and end-segment |
||||||
|
that define the representation of segments in terms of points. Furthermore, a |
||||||
|
point can be represented as a pair of numbers: the |
||||||
|
x |
||||||
|
coordinate and the |
||||||
|
|
||||||
|
y |
||||||
|
coordinate. Accordingly, specify a constructor make-point and |
||||||
|
selectors x-point and y-point that define this representation. |
||||||
|
Finally, using your selectors and constructors, define a procedure |
||||||
|
midpoint-segment that takes a line segment as argument and returns its |
||||||
|
midpoint (the point whose coordinates are the average of the coordinates of the |
||||||
|
endpoints). To try your procedures, you’ll need a way to print points: |
||||||
|
|
||||||
|
|
||||||
|
(define (print-point p) |
||||||
|
(newline) |
||||||
|
(display "(") |
||||||
|
(display (x-point p)) |
||||||
|
(display ",") |
||||||
|
(display (y-point p)) |
||||||
|
(display ")")) |
@ -0,0 +1,47 @@ |
|||||||
|
|
||||||
|
Exercise 2.20: The procedures +, |
||||||
|
*, and list take arbitrary numbers of arguments. One way to |
||||||
|
define such procedures is to use define with |
||||||
|
dotted-tail notation. |
||||||
|
In a procedure definition, a parameter list that has a dot before |
||||||
|
the last parameter name indicates that, when the procedure is called, the |
||||||
|
initial parameters (if any) will have as values the initial arguments, as |
||||||
|
usual, but the final parameter’s value will be a |
||||||
|
list of any |
||||||
|
remaining arguments. For instance, given the definition |
||||||
|
|
||||||
|
|
||||||
|
(define (f x y . z) ⟨body⟩) |
||||||
|
|
||||||
|
the procedure f can be called with two or more arguments. If we |
||||||
|
evaluate |
||||||
|
|
||||||
|
|
||||||
|
(f 1 2 3 4 5 6) |
||||||
|
|
||||||
|
then in the body of f, x will be 1, y will be 2, and |
||||||
|
z will be the list (3 4 5 6). Given the definition |
||||||
|
|
||||||
|
|
||||||
|
(define (g . w) ⟨body⟩) |
||||||
|
|
||||||
|
the procedure g can be called with zero or more arguments. If we |
||||||
|
evaluate |
||||||
|
|
||||||
|
|
||||||
|
(g 1 2 3 4 5 6) |
||||||
|
|
||||||
|
then in the body of g, w will be the list (1 2 3 4 5 |
||||||
|
6).77 |
||||||
|
|
||||||
|
Use this notation to write a procedure same-parity that takes one or |
||||||
|
more integers and returns a list of all the arguments that have the same |
||||||
|
even-odd parity as the first argument. For example, |
||||||
|
|
||||||
|
|
||||||
|
(same-parity 1 2 3 4 5 6 7) |
||||||
|
(1 3 5 7) |
||||||
|
|
||||||
|
(same-parity 2 3 4 5 6 7) |
||||||
|
(2 4 6) |
||||||
|
|
@ -0,0 +1,21 @@ |
|||||||
|
|
||||||
|
Exercise 2.21: The procedure square-list |
||||||
|
takes a list of numbers as argument and returns a list of the squares of those |
||||||
|
numbers. |
||||||
|
|
||||||
|
|
||||||
|
(square-list (list 1 2 3 4)) |
||||||
|
(1 4 9 16) |
||||||
|
|
||||||
|
|
||||||
|
Here are two different definitions of square-list. Complete both of |
||||||
|
them by filling in the missing expressions: |
||||||
|
|
||||||
|
|
||||||
|
(define (square-list items) |
||||||
|
(if (null? items) |
||||||
|
nil |
||||||
|
(cons ⟨??⟩ ⟨??⟩))) |
||||||
|
|
||||||
|
(define (square-list items) |
||||||
|
(map ⟨??⟩ ⟨??⟩)) |
@ -0,0 +1,32 @@ |
|||||||
|
|
||||||
|
Exercise 2.22: Louis Reasoner tries to rewrite |
||||||
|
the first square-list procedure of Exercise 2.21 so that it |
||||||
|
evolves an iterative process: |
||||||
|
|
||||||
|
|
||||||
|
(define (square-list items) |
||||||
|
(define (iter things answer) |
||||||
|
(if (null? things) |
||||||
|
answer |
||||||
|
(iter (cdr things) |
||||||
|
(cons (square (car things)) |
||||||
|
answer)))) |
||||||
|
(iter items nil)) |
||||||
|
|
||||||
|
Unfortunately, defining square-list this way produces the answer list in |
||||||
|
the reverse order of the one desired. Why? |
||||||
|
|
||||||
|
Louis then tries to fix his bug by interchanging the arguments to cons: |
||||||
|
|
||||||
|
|
||||||
|
(define (square-list items) |
||||||
|
(define (iter things answer) |
||||||
|
(if (null? things) |
||||||
|
answer |
||||||
|
(iter (cdr things) |
||||||
|
(cons answer |
||||||
|
(square |
||||||
|
(car things)))))) |
||||||
|
(iter items nil)) |
||||||
|
|
||||||
|
This doesn’t work either. Explain. |
@ -0,0 +1,22 @@ |
|||||||
|
|
||||||
|
Exercise 2.23: The procedure for-each is |
||||||
|
similar to map. It takes as arguments a procedure and a list of |
||||||
|
elements. However, rather than forming a list of the results, for-each |
||||||
|
just applies the procedure to each of the elements in turn, from left to right. |
||||||
|
The values returned by applying the procedure to the elements are not used at |
||||||
|
all—for-each is used with procedures that perform an action, such as |
||||||
|
printing. For example, |
||||||
|
|
||||||
|
|
||||||
|
(for-each |
||||||
|
(lambda (x) (newline) (display x)) |
||||||
|
(list 57 321 88)) |
||||||
|
|
||||||
|
57 |
||||||
|
321 |
||||||
|
88 |
||||||
|
|
||||||
|
|
||||||
|
The value returned by the call to for-each (not illustrated above) can |
||||||
|
be something arbitrary, such as true. Give an implementation of |
||||||
|
for-each. |
@ -0,0 +1,5 @@ |
|||||||
|
|
||||||
|
Exercise 2.24: Suppose we evaluate the |
||||||
|
expression (list 1 (list 2 (list 3 4))). Give the result printed by the |
||||||
|
interpreter, the corresponding box-and-pointer structure, and the |
||||||
|
interpretation of this as a tree (as in Figure 2.6). |
@ -0,0 +1,8 @@ |
|||||||
|
|
||||||
|
Exercise 2.25: Give combinations of cars |
||||||
|
and cdrs that will pick 7 from each of the following lists: |
||||||
|
|
||||||
|
|
||||||
|
(1 3 (5 7) 9) |
||||||
|
((7)) |
||||||
|
(1 (2 (3 (4 (5 (6 7)))))) |
@ -0,0 +1,15 @@ |
|||||||
|
|
||||||
|
Exercise 2.26: Suppose we define x and |
||||||
|
y to be two lists: |
||||||
|
|
||||||
|
|
||||||
|
(define x (list 1 2 3)) |
||||||
|
(define y (list 4 5 6)) |
||||||
|
|
||||||
|
What result is printed by the interpreter in response to evaluating each of the |
||||||
|
following expressions: |
||||||
|
|
||||||
|
|
||||||
|
(append x y) |
||||||
|
(cons x y) |
||||||
|
(list x y) |
@ -0,0 +1,19 @@ |
|||||||
|
|
||||||
|
Exercise 2.27: Modify your reverse |
||||||
|
procedure of Exercise 2.18 to produce a deep-reverse procedure |
||||||
|
that takes a list as argument and returns as its value the list with its |
||||||
|
elements reversed and with all sublists deep-reversed as well. For example, |
||||||
|
|
||||||
|
|
||||||
|
(define x |
||||||
|
(list (list 1 2) (list 3 4))) |
||||||
|
|
||||||
|
x |
||||||
|
((1 2) (3 4)) |
||||||
|
|
||||||
|
(reverse x) |
||||||
|
((3 4) (1 2)) |
||||||
|
|
||||||
|
(deep-reverse x) |
||||||
|
((4 3) (2 1)) |
||||||
|
|
@ -0,0 +1,16 @@ |
|||||||
|
|
||||||
|
Exercise 2.28: Write a procedure fringe |
||||||
|
that takes as argument a tree (represented as a list) and returns a list whose |
||||||
|
elements are all the leaves of the tree arranged in left-to-right order. For |
||||||
|
example, |
||||||
|
|
||||||
|
|
||||||
|
(define x |
||||||
|
(list (list 1 2) (list 3 4))) |
||||||
|
|
||||||
|
(fringe x) |
||||||
|
(1 2 3 4) |
||||||
|
|
||||||
|
(fringe (list x x)) |
||||||
|
(1 2 3 4 1 2 3 4) |
||||||
|
|
@ -0,0 +1,48 @@ |
|||||||
|
|
||||||
|
Exercise 2.29: A binary mobile consists of two |
||||||
|
branches, a left branch and a right branch. Each branch is a rod of a certain |
||||||
|
length, from which hangs either a weight or another binary mobile. We can |
||||||
|
represent a binary mobile using compound data by constructing it from two |
||||||
|
branches (for example, using list): |
||||||
|
|
||||||
|
|
||||||
|
(define (make-mobile left right) |
||||||
|
(list left right)) |
||||||
|
|
||||||
|
A branch is constructed from a length (which must be a number) together |
||||||
|
with a structure, which may be either a number (representing a simple |
||||||
|
weight) or another mobile: |
||||||
|
|
||||||
|
|
||||||
|
(define (make-branch length structure) |
||||||
|
(list length structure)) |
||||||
|
|
||||||
|
|
||||||
|
Write the corresponding selectors left-branch and right-branch, |
||||||
|
which return the branches of a mobile, and branch-length and |
||||||
|
branch-structure, which return the components of a branch. |
||||||
|
|
||||||
|
Using your selectors, define a procedure total-weight that returns the |
||||||
|
total weight of a mobile. |
||||||
|
|
||||||
|
A mobile is said to be |
||||||
|
balanced if the torque applied by its top-left |
||||||
|
branch is equal to that applied by its top-right branch (that is, if the length |
||||||
|
of the left rod multiplied by the weight hanging from that rod is equal to the |
||||||
|
corresponding product for the right side) and if each of the submobiles hanging |
||||||
|
off its branches is balanced. Design a predicate that tests whether a binary |
||||||
|
mobile is balanced. |
||||||
|
|
||||||
|
Suppose we change the representation of mobiles so that the constructors are |
||||||
|
|
||||||
|
|
||||||
|
(define (make-mobile left right) |
||||||
|
(cons left right)) |
||||||
|
|
||||||
|
(define (make-branch length structure) |
||||||
|
(cons length structure)) |
||||||
|
|
||||||
|
How much do you need to change your programs to convert to the new |
||||||
|
representation? |
||||||
|
|
||||||
|
|
@ -0,0 +1,8 @@ |
|||||||
|
|
||||||
|
Exercise 2.3: Implement a representation for |
||||||
|
rectangles in a plane. (Hint: You may want to make use of Exercise 2.2.) |
||||||
|
In terms of your constructors and selectors, create procedures that compute the |
||||||
|
perimeter and the area of a given rectangle. Now implement a different |
||||||
|
representation for rectangles. Can you design your system with suitable |
||||||
|
abstraction barriers, so that the same perimeter and area procedures will work |
||||||
|
using either representation? |
@ -0,0 +1,15 @@ |
|||||||
|
|
||||||
|
Exercise 2.30: Define a procedure |
||||||
|
square-tree analogous to the square-list procedure of |
||||||
|
Exercise 2.21. That is, square-tree should behave as follows: |
||||||
|
|
||||||
|
|
||||||
|
(square-tree |
||||||
|
(list 1 |
||||||
|
(list 2 (list 3 4) 5) |
||||||
|
(list 6 7))) |
||||||
|
(1 (4 (9 16) 25) (36 49)) |
||||||
|
|
||||||
|
|
||||||
|
Define square-tree both directly (i.e., without using any higher-order |
||||||
|
procedures) and also by using map and recursion. |
@ -0,0 +1,8 @@ |
|||||||
|
|
||||||
|
Exercise 2.31: Abstract your answer to |
||||||
|
Exercise 2.30 to produce a procedure tree-map with the property |
||||||
|
that square-tree could be defined as |
||||||
|
|
||||||
|
|
||||||
|
(define (square-tree tree) |
||||||
|
(tree-map square tree)) |
@ -0,0 +1,14 @@ |
|||||||
|
|
||||||
|
Exercise 2.32: We can represent a set as a list |
||||||
|
of distinct elements, and we can represent the set of all subsets of the set as |
||||||
|
a list of lists. For example, if the set is (1 2 3), then the set of |
||||||
|
all subsets is (() (3) (2) (2 3) (1) (1 3) (1 2) (1 2 3)). Complete the |
||||||
|
following definition of a procedure that generates the set of subsets of a set |
||||||
|
and give a clear explanation of why it works: |
||||||
|
|
||||||
|
|
||||||
|
(define (subsets s) |
||||||
|
(if (null? s) |
||||||
|
(list nil) |
||||||
|
(let ((rest (subsets (cdr s)))) |
||||||
|
(append rest (map ⟨??⟩ rest))))) |
@ -0,0 +1,15 @@ |
|||||||
|
|
||||||
|
Exercise 2.33: Fill in the missing expressions |
||||||
|
to complete the following definitions of some basic list-manipulation |
||||||
|
operations as accumulations: |
||||||
|
|
||||||
|
|
||||||
|
(define (map p sequence) |
||||||
|
(accumulate (lambda (x y) ⟨??⟩) |
||||||
|
nil sequence)) |
||||||
|
|
||||||
|
(define (append seq1 seq2) |
||||||
|
(accumulate cons ⟨??⟩ ⟨??⟩)) |
||||||
|
|
||||||
|
(define (length sequence) |
||||||
|
(accumulate ⟨??⟩ 0 sequence)) |
@ -0,0 +1,182 @@ |
|||||||
|
|
||||||
|
Exercise 2.34: Evaluating a polynomial in |
||||||
|
x |
||||||
|
|
||||||
|
at a given value of |
||||||
|
x |
||||||
|
can be formulated as an accumulation. We evaluate |
||||||
|
the polynomial |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
a |
||||||
|
n |
||||||
|
|
||||||
|
|
||||||
|
x |
||||||
|
n |
||||||
|
|
||||||
|
|
||||||
|
+ |
||||||
|
|
||||||
|
|
||||||
|
a |
||||||
|
|
||||||
|
n |
||||||
|
− |
||||||
|
1 |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
x |
||||||
|
|
||||||
|
n |
||||||
|
− |
||||||
|
1 |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
+ |
||||||
|
⋯ |
||||||
|
+ |
||||||
|
|
||||||
|
|
||||||
|
a |
||||||
|
1 |
||||||
|
|
||||||
|
x |
||||||
|
|
||||||
|
+ |
||||||
|
|
||||||
|
a |
||||||
|
0 |
||||||
|
|
||||||
|
|
||||||
|
using a well-known algorithm called |
||||||
|
Horner’s rule, which structures |
||||||
|
the computation as |
||||||
|
|
||||||
|
|
||||||
|
( |
||||||
|
… |
||||||
|
( |
||||||
|
|
||||||
|
a |
||||||
|
n |
||||||
|
|
||||||
|
x |
||||||
|
|
||||||
|
+ |
||||||
|
|
||||||
|
|
||||||
|
a |
||||||
|
|
||||||
|
n |
||||||
|
− |
||||||
|
1 |
||||||
|
|
||||||
|
|
||||||
|
) |
||||||
|
x |
||||||
|
|
||||||
|
+ |
||||||
|
⋯ |
||||||
|
+ |
||||||
|
|
||||||
|
|
||||||
|
a |
||||||
|
1 |
||||||
|
|
||||||
|
) |
||||||
|
x |
||||||
|
|
||||||
|
+ |
||||||
|
|
||||||
|
|
||||||
|
a |
||||||
|
0 |
||||||
|
|
||||||
|
. |
||||||
|
|
||||||
|
|
||||||
|
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 |
||||||
|
|
||||||
|
.82 |
||||||
|
|
||||||
|
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 |
||||||
|
|
||||||
|
. |
||||||
|
|
||||||
|
|
||||||
|
(define |
||||||
|
(horner-eval x coefficient-sequence) |
||||||
|
(accumulate |
||||||
|
(lambda (this-coeff higher-terms) |
||||||
|
⟨??⟩) |
||||||
|
0 |
||||||
|
coefficient-sequence)) |
||||||
|
|
||||||
|
For example, to compute |
||||||
|
|
||||||
|
1 |
||||||
|
+ |
||||||
|
3 |
||||||
|
x |
||||||
|
|
||||||
|
+ |
||||||
|
|
||||||
|
5 |
||||||
|
|
||||||
|
x |
||||||
|
3 |
||||||
|
|
||||||
|
+ |
||||||
|
|
||||||
|
x |
||||||
|
5 |
||||||
|
|
||||||
|
|
||||||
|
at |
||||||
|
|
||||||
|
x |
||||||
|
= |
||||||
|
2 |
||||||
|
|
||||||
|
you |
||||||
|
would evaluate |
||||||
|
|
||||||
|
|
||||||
|
(horner-eval 2 (list 1 3 0 5 0 1)) |
@ -0,0 +1,7 @@ |
|||||||
|
|
||||||
|
Exercise 2.35: Redefine count-leaves from |
||||||
|
2.2.2 as an accumulation: |
||||||
|
|
||||||
|
|
||||||
|
(define (count-leaves t) |
||||||
|
(accumulate ⟨??⟩ ⟨??⟩ (map ⟨??⟩ ⟨??⟩))) |
@ -0,0 +1,18 @@ |
|||||||
|
|
||||||
|
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: |
||||||
|
|
||||||
|
|
||||||
|
(define (accumulate-n op init seqs) |
||||||
|
(if (null? (car seqs)) |
||||||
|
nil |
||||||
|
(cons (accumulate op init ⟨??⟩) |
||||||
|
(accumulate-n op init ⟨??⟩)))) |
@ -0,0 +1,250 @@ |
|||||||
|
|
||||||
|
Exercise 2.37: |
||||||
|
Suppose we represent vectors v = |
||||||
|
|
||||||
|
( |
||||||
|
|
||||||
|
v |
||||||
|
i |
||||||
|
|
||||||
|
) |
||||||
|
|
||||||
|
as sequences of numbers, and |
||||||
|
matrices m = |
||||||
|
|
||||||
|
( |
||||||
|
|
||||||
|
m |
||||||
|
|
||||||
|
i |
||||||
|
j |
||||||
|
|
||||||
|
|
||||||
|
) |
||||||
|
|
||||||
|
as sequences of vectors (the rows of the |
||||||
|
matrix). For example, the matrix |
||||||
|
|
||||||
|
|
||||||
|
( |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
1 |
||||||
|
|
||||||
|
|
||||||
|
2 |
||||||
|
|
||||||
|
|
||||||
|
3 |
||||||
|
|
||||||
|
|
||||||
|
4 |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
4 |
||||||
|
|
||||||
|
|
||||||
|
5 |
||||||
|
|
||||||
|
|
||||||
|
6 |
||||||
|
|
||||||
|
|
||||||
|
6 |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
6 |
||||||
|
|
||||||
|
|
||||||
|
7 |
||||||
|
|
||||||
|
|
||||||
|
8 |
||||||
|
|
||||||
|
|
||||||
|
9 |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
) |
||||||
|
|
||||||
|
|
||||||
|
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: |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(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 |
||||||
|
|
||||||
|
i |
||||||
|
j |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
v |
||||||
|
j |
||||||
|
|
||||||
|
; |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(matrix-*-matrix m n) |
||||||
|
|
||||||
|
|
||||||
|
returns the matrix |
||||||
|
|
||||||
|
|
||||||
|
p |
||||||
|
|
||||||
|
, |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
where |
||||||
|
|
||||||
|
|
||||||
|
p |
||||||
|
|
||||||
|
i |
||||||
|
j |
||||||
|
|
||||||
|
|
||||||
|
= |
||||||
|
|
||||||
|
Σ |
||||||
|
k |
||||||
|
|
||||||
|
|
||||||
|
m |
||||||
|
|
||||||
|
i |
||||||
|
k |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
n |
||||||
|
|
||||||
|
k |
||||||
|
j |
||||||
|
|
||||||
|
|
||||||
|
; |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(transpose m) |
||||||
|
|
||||||
|
|
||||||
|
returns the matrix |
||||||
|
|
||||||
|
|
||||||
|
n |
||||||
|
|
||||||
|
, |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
where |
||||||
|
|
||||||
|
|
||||||
|
n |
||||||
|
|
||||||
|
i |
||||||
|
j |
||||||
|
|
||||||
|
|
||||||
|
= |
||||||
|
|
||||||
|
m |
||||||
|
|
||||||
|
j |
||||||
|
i |
||||||
|
|
||||||
|
|
||||||
|
. |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
We can define the dot product as83 |
||||||
|
|
||||||
|
|
||||||
|
(define (dot-product v w) |
||||||
|
(accumulate + 0 (map * v w))) |
||||||
|
|
||||||
|
Fill in the missing expressions in the following procedures for computing the |
||||||
|
other matrix operations. (The procedure accumulate-n is defined in |
||||||
|
Exercise 2.36.) |
||||||
|
|
||||||
|
|
||||||
|
(define (matrix-*-vector m v) |
||||||
|
(map ⟨??⟩ m)) |
||||||
|
|
||||||
|
(define (transpose mat) |
||||||
|
(accumulate-n ⟨??⟩ ⟨??⟩ mat)) |
||||||
|
|
||||||
|
(define (matrix-*-matrix m n) |
||||||
|
(let ((cols (transpose n))) |
||||||
|
(map ⟨??⟩ m))) |
@ -0,0 +1,27 @@ |
|||||||
|
|
||||||
|
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: |
||||||
|
|
||||||
|
|
||||||
|
(define (fold-left op initial sequence) |
||||||
|
(define (iter result rest) |
||||||
|
(if (null? rest) |
||||||
|
result |
||||||
|
(iter (op result (car rest)) |
||||||
|
(cdr rest)))) |
||||||
|
(iter initial sequence)) |
||||||
|
|
||||||
|
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. |
@ -0,0 +1,13 @@ |
|||||||
|
|
||||||
|
Exercise 2.39: Complete the following |
||||||
|
definitions of reverse (Exercise 2.18) in terms of |
||||||
|
fold-right and fold-left from Exercise 2.38: |
||||||
|
|
||||||
|
|
||||||
|
(define (reverse sequence) |
||||||
|
(fold-right |
||||||
|
(lambda (x y) ⟨??⟩) nil sequence)) |
||||||
|
|
||||||
|
(define (reverse sequence) |
||||||
|
(fold-left |
||||||
|
(lambda (x y) ⟨??⟩) nil sequence)) |
@ -0,0 +1,14 @@ |
|||||||
|
|
||||||
|
Exercise 2.4: Here is an alternative procedural |
||||||
|
representation of pairs. For this representation, verify that (car (cons |
||||||
|
x y)) yields x for any objects x and y. |
||||||
|
|
||||||
|
|
||||||
|
(define (cons x y) |
||||||
|
(lambda (m) (m x y))) |
||||||
|
|
||||||
|
(define (car z) |
||||||
|
(z (lambda (p q) p))) |
||||||
|
|
||||||
|
What is the corresponding definition of cdr? (Hint: To verify that this |
||||||
|
works, make use of the substitution model of 1.1.5.) |
@ -0,0 +1,27 @@ |
|||||||
|
|
||||||
|
Exercise 2.40: Define a procedure |
||||||
|
unique-pairs that, given an integer |
||||||
|
n |
||||||
|
, generates the sequence of |
||||||
|
pairs |
||||||
|
|
||||||
|
( |
||||||
|
i |
||||||
|
, |
||||||
|
j |
||||||
|
) |
||||||
|
|
||||||
|
with |
||||||
|
|
||||||
|
1 |
||||||
|
≤ |
||||||
|
j |
||||||
|
|
||||||
|
< |
||||||
|
|
||||||
|
i |
||||||
|
≤ |
||||||
|
n |
||||||
|
|
||||||
|
. Use unique-pairs |
||||||
|
to simplify the definition of prime-sum-pairs given above. |
@ -0,0 +1,14 @@ |
|||||||
|
|
||||||
|
Exercise 2.41: Write a procedure to find all |
||||||
|
ordered triples of distinct positive integers |
||||||
|
i |
||||||
|
, |
||||||
|
j |
||||||
|
, and |
||||||
|
k |
||||||
|
less than |
||||||
|
or equal to a given integer |
||||||
|
n |
||||||
|
that sum to a given integer |
||||||
|
s |
||||||
|
. |
@ -0,0 +1,142 @@ |
|||||||
|
|
||||||
|
Exercise 2.42: The “eight-queens puzzle” asks |
||||||
|
how to place eight queens on a chessboard so that no queen is in check from any |
||||||
|
other (i.e., no two queens are in the same row, column, or diagonal). One |
||||||
|
possible solution is shown in Figure 2.8. One way to solve the puzzle is |
||||||
|
to work across the board, placing a queen in each column. Once we have placed |
||||||
|
|
||||||
|
|
||||||
|
k |
||||||
|
− |
||||||
|
1 |
||||||
|
|
||||||
|
queens, we must place the |
||||||
|
|
||||||
|
k |
||||||
|
|
||||||
|
th |
||||||
|
|
||||||
|
|
||||||
|
queen in a position where it does |
||||||
|
not check any of the queens already on the board. We can formulate this |
||||||
|
approach recursively: Assume that we have already generated the sequence of all |
||||||
|
possible ways to place |
||||||
|
|
||||||
|
k |
||||||
|
− |
||||||
|
1 |
||||||
|
|
||||||
|
queens in the first |
||||||
|
|
||||||
|
k |
||||||
|
− |
||||||
|
1 |
||||||
|
|
||||||
|
columns of the |
||||||
|
board. For each of these ways, generate an extended set of positions by |
||||||
|
placing a queen in each row of the |
||||||
|
|
||||||
|
k |
||||||
|
|
||||||
|
th |
||||||
|
|
||||||
|
|
||||||
|
column. Now filter these, keeping |
||||||
|
only the positions for which the queen in the |
||||||
|
|
||||||
|
k |
||||||
|
|
||||||
|
th |
||||||
|
|
||||||
|
|
||||||
|
column is safe with |
||||||
|
respect to the other queens. This produces the sequence of all ways to place |
||||||
|
|
||||||
|
k |
||||||
|
queens in the first |
||||||
|
k |
||||||
|
columns. By continuing this process, we will |
||||||
|
produce not only one solution, but all solutions to the puzzle. |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
SVG |
||||||
|
|
||||||
|
|
||||||
|
Figure 2.8: A solution to the eight-queens puzzle. |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
We implement this solution as a procedure queens, which returns a |
||||||
|
sequence of all solutions to the problem of placing |
||||||
|
n |
||||||
|
queens on an |
||||||
|
|
||||||
|
|
||||||
|
n |
||||||
|
× |
||||||
|
n |
||||||
|
|
||||||
|
chessboard. Queens has an internal procedure |
||||||
|
queen-cols that returns the sequence of all ways to place queens in the |
||||||
|
first |
||||||
|
k |
||||||
|
columns of the board. |
||||||
|
|
||||||
|
|
||||||
|
(define (queens board-size) |
||||||
|
(define (queen-cols k) |
||||||
|
(if (= k 0) |
||||||
|
(list empty-board) |
||||||
|
(filter |
||||||
|
(lambda (positions) |
||||||
|
(safe? k positions)) |
||||||
|
(flatmap |
||||||
|
(lambda (rest-of-queens) |
||||||
|
(map (lambda (new-row) |
||||||
|
(adjoin-position |
||||||
|
new-row |
||||||
|
k |
||||||
|
rest-of-queens)) |
||||||
|
(enumerate-interval |
||||||
|
1 |
||||||
|
board-size))) |
||||||
|
(queen-cols (- k 1)))))) |
||||||
|
(queen-cols board-size)) |
||||||
|
|
||||||
|
In this procedure rest-of-queens is a way to place |
||||||
|
|
||||||
|
k |
||||||
|
− |
||||||
|
1 |
||||||
|
|
||||||
|
queens in |
||||||
|
the first |
||||||
|
|
||||||
|
k |
||||||
|
− |
||||||
|
1 |
||||||
|
|
||||||
|
columns, and new-row is a proposed row in which to |
||||||
|
place the queen for the |
||||||
|
|
||||||
|
k |
||||||
|
|
||||||
|
th |
||||||
|
|
||||||
|
|
||||||
|
column. Complete the program by implementing |
||||||
|
the representation for sets of board positions, including the procedure |
||||||
|
adjoin-position, which adjoins a new row-column position to a set of |
||||||
|
positions, and empty-board, which represents an empty set of positions. |
||||||
|
You must also write the procedure safe?, which determines for a set of |
||||||
|
positions, whether the queen in the |
||||||
|
|
||||||
|
k |
||||||
|
|
||||||
|
th |
||||||
|
|
||||||
|
|
||||||
|
column is safe with respect to the |
||||||
|
others. (Note that we need only check whether the new queen is safe—the |
||||||
|
other queens are already guaranteed safe with respect to each other.) |
@ -0,0 +1,28 @@ |
|||||||
|
|
||||||
|
Exercise 2.43: Louis Reasoner is having a |
||||||
|
terrible time doing Exercise 2.42. His queens procedure seems to |
||||||
|
work, but it runs extremely slowly. (Louis never does manage to wait long |
||||||
|
enough for it to solve even the |
||||||
|
|
||||||
|
6 |
||||||
|
× |
||||||
|
6 |
||||||
|
|
||||||
|
case.) When Louis asks Eva Lu Ator for |
||||||
|
help, she points out that he has interchanged the order of the nested mappings |
||||||
|
in the flatmap, writing it as |
||||||
|
|
||||||
|
|
||||||
|
(flatmap |
||||||
|
(lambda (new-row) |
||||||
|
(map (lambda (rest-of-queens) |
||||||
|
(adjoin-position |
||||||
|
new-row k rest-of-queens)) |
||||||
|
(queen-cols (- k 1)))) |
||||||
|
(enumerate-interval 1 board-size)) |
||||||
|
|
||||||
|
Explain why this interchange makes the program run slowly. Estimate how long |
||||||
|
it will take Louis’s program to solve the eight-queens puzzle, assuming that |
||||||
|
the program in Exercise 2.42 solves the puzzle in time |
||||||
|
T |
||||||
|
. |
@ -0,0 +1,5 @@ |
|||||||
|
|
||||||
|
Exercise 2.44: Define the procedure |
||||||
|
up-split used by corner-split. It is similar to |
||||||
|
right-split, except that it switches the roles of below and |
||||||
|
beside. |
@ -0,0 +1,11 @@ |
|||||||
|
|
||||||
|
Exercise 2.45: Right-split and |
||||||
|
up-split can be expressed as instances of a general splitting operation. |
||||||
|
Define a procedure split with the property that evaluating |
||||||
|
|
||||||
|
|
||||||
|
(define right-split (split beside below)) |
||||||
|
(define up-split (split below beside)) |
||||||
|
|
||||||
|
produces procedures right-split and up-split with the same |
||||||
|
behaviors as the ones already defined. |
@ -0,0 +1,151 @@ |
|||||||
|
|
||||||
|
Exercise 2.46: A two-dimensional vector |
||||||
|
v |
||||||
|
|
||||||
|
running from the origin to a point can be represented as a pair consisting of |
||||||
|
an |
||||||
|
x |
||||||
|
-coordinate and a |
||||||
|
y |
||||||
|
-coordinate. Implement a data abstraction for |
||||||
|
vectors by giving a constructor make-vect and corresponding selectors |
||||||
|
xcor-vect and ycor-vect. In terms of your selectors and |
||||||
|
constructor, implement procedures add-vect, sub-vect, and |
||||||
|
scale-vect that perform the operations vector addition, vector |
||||||
|
subtraction, and multiplying a vector by a scalar: |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
( |
||||||
|
|
||||||
|
x |
||||||
|
1 |
||||||
|
|
||||||
|
, |
||||||
|
|
||||||
|
y |
||||||
|
1 |
||||||
|
|
||||||
|
) |
||||||
|
+ |
||||||
|
( |
||||||
|
|
||||||
|
x |
||||||
|
2 |
||||||
|
|
||||||
|
, |
||||||
|
|
||||||
|
y |
||||||
|
2 |
||||||
|
|
||||||
|
) |
||||||
|
|
||||||
|
|
||||||
|
= |
||||||
|
|
||||||
|
|
||||||
|
( |
||||||
|
|
||||||
|
x |
||||||
|
1 |
||||||
|
|
||||||
|
+ |
||||||
|
|
||||||
|
x |
||||||
|
2 |
||||||
|
|
||||||
|
, |
||||||
|
|
||||||
|
y |
||||||
|
1 |
||||||
|
|
||||||
|
+ |
||||||
|
|
||||||
|
y |
||||||
|
2 |
||||||
|
|
||||||
|
) |
||||||
|
, |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
( |
||||||
|
|
||||||
|
x |
||||||
|
1 |
||||||
|
|
||||||
|
, |
||||||
|
|
||||||
|
y |
||||||
|
1 |
||||||
|
|
||||||
|
) |
||||||
|
− |
||||||
|
( |
||||||
|
|
||||||
|
x |
||||||
|
2 |
||||||
|
|
||||||
|
, |
||||||
|
|
||||||
|
y |
||||||
|
2 |
||||||
|
|
||||||
|
) |
||||||
|
|
||||||
|
|
||||||
|
= |
||||||
|
|
||||||
|
|
||||||
|
( |
||||||
|
|
||||||
|
x |
||||||
|
1 |
||||||
|
|
||||||
|
− |
||||||
|
|
||||||
|
x |
||||||
|
2 |
||||||
|
|
||||||
|
, |
||||||
|
|
||||||
|
y |
||||||
|
1 |
||||||
|
|
||||||
|
− |
||||||
|
|
||||||
|
y |
||||||
|
2 |
||||||
|
|
||||||
|
) |
||||||
|
, |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
s |
||||||
|
⋅ |
||||||
|
( |
||||||
|
x |
||||||
|
, |
||||||
|
y |
||||||
|
) |
||||||
|
|
||||||
|
|
||||||
|
= |
||||||
|
|
||||||
|
|
||||||
|
( |
||||||
|
s |
||||||
|
x |
||||||
|
, |
||||||
|
s |
||||||
|
y |
||||||
|
) |
||||||
|
. |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,13 @@ |
|||||||
|
|
||||||
|
Exercise 2.47: Here are two possible |
||||||
|
constructors for frames: |
||||||
|
|
||||||
|
|
||||||
|
(define (make-frame origin edge1 edge2) |
||||||
|
(list origin edge1 edge2)) |
||||||
|
|
||||||
|
(define (make-frame origin edge1 edge2) |
||||||
|
(cons origin (cons edge1 edge2))) |
||||||
|
|
||||||
|
For each constructor supply the appropriate selectors to produce an |
||||||
|
implementation for frames. |
@ -0,0 +1,7 @@ |
|||||||
|
|
||||||
|
Exercise 2.48: A directed line segment in the |
||||||
|
plane can be represented as a pair of vectors—the vector running from the |
||||||
|
origin to the start-point of the segment, and the vector running from the |
||||||
|
origin to the end-point of the segment. Use your vector representation from |
||||||
|
Exercise 2.46 to define a representation for segments with a constructor |
||||||
|
make-segment and selectors start-segment and end-segment. |
@ -0,0 +1,15 @@ |
|||||||
|
|
||||||
|
Exercise 2.49: Use segments->painter |
||||||
|
to define the following primitive painters: |
||||||
|
|
||||||
|
|
||||||
|
The painter that draws the outline of the designated frame. |
||||||
|
|
||||||
|
The painter that draws an “X” by connecting opposite corners of the frame. |
||||||
|
|
||||||
|
The painter that draws a diamond shape by connecting the midpoints of the sides |
||||||
|
of the frame. |
||||||
|
|
||||||
|
The wave painter. |
||||||
|
|
||||||
|
|
@ -0,0 +1,21 @@ |
|||||||
|
|
||||||
|
Exercise 2.5: Show that we can represent pairs of |
||||||
|
nonnegative integers using only numbers and arithmetic operations if we |
||||||
|
represent the pair |
||||||
|
a |
||||||
|
and |
||||||
|
b |
||||||
|
as the integer that is the product |
||||||
|
|
||||||
|
|
||||||
|
2 |
||||||
|
a |
||||||
|
|
||||||
|
|
||||||
|
3 |
||||||
|
b |
||||||
|
|
||||||
|
|
||||||
|
. |
||||||
|
Give the corresponding definitions of the procedures cons, |
||||||
|
car, and cdr. |
@ -0,0 +1,4 @@ |
|||||||
|
|
||||||
|
Exercise 2.50: Define the transformation |
||||||
|
flip-horiz, which flips painters horizontally, and transformations that |
||||||
|
rotate painters counterclockwise by 180 degrees and 270 degrees. |
@ -0,0 +1,8 @@ |
|||||||
|
|
||||||
|
Exercise 2.51: Define the below operation |
||||||
|
for painters. Below takes two painters as arguments. The resulting |
||||||
|
painter, given a frame, draws with the first painter in the bottom of the frame |
||||||
|
and with the second painter in the top. Define below in two different |
||||||
|
ways—first by writing a procedure that is analogous to the beside |
||||||
|
procedure given above, and again in terms of beside and suitable |
||||||
|
rotation operations (from Exercise 2.50). |
@ -0,0 +1,18 @@ |
|||||||
|
|
||||||
|
Exercise 2.52: Make changes to the square limit |
||||||
|
of wave shown in Figure 2.9 by working at each of the levels |
||||||
|
described above. In particular: |
||||||
|
|
||||||
|
|
||||||
|
Add some segments to the primitive wave painter of Exercise 2.49 |
||||||
|
(to add a smile, for example). |
||||||
|
|
||||||
|
Change the pattern constructed by corner-split (for example, by using |
||||||
|
only one copy of the up-split and right-split images instead of |
||||||
|
two). |
||||||
|
|
||||||
|
Modify the version of square-limit that uses square-of-four so as |
||||||
|
to assemble the corners in a different pattern. (For example, you might make |
||||||
|
the big Mr. Rogers look outward from each corner of the square.) |
||||||
|
|
||||||
|
|
@ -0,0 +1,12 @@ |
|||||||
|
|
||||||
|
Exercise 2.53: What would the interpreter print |
||||||
|
in response to evaluating each of the following expressions? |
||||||
|
|
||||||
|
|
||||||
|
(list 'a 'b 'c) |
||||||
|
(list (list 'george)) |
||||||
|
(cdr '((x1 x2) (y1 y2))) |
||||||
|
(cadr '((x1 x2) (y1 y2))) |
||||||
|
(pair? (car '(a short list))) |
||||||
|
(memq 'red '((red shoes) (blue socks))) |
||||||
|
(memq 'red '(red shoes blue socks)) |
@ -0,0 +1,21 @@ |
|||||||
|
|
||||||
|
Exercise 2.54: Two lists are said to be |
||||||
|
equal? if they contain equal elements arranged in the same order. For |
||||||
|
example, |
||||||
|
|
||||||
|
|
||||||
|
(equal? '(this is a list) |
||||||
|
'(this is a list)) |
||||||
|
|
||||||
|
is true, but |
||||||
|
|
||||||
|
|
||||||
|
(equal? '(this is a list) |
||||||
|
'(this (is a) list)) |
||||||
|
|
||||||
|
is false. To be more precise, we can define equal? recursively in |
||||||
|
terms of the basic eq? equality of symbols by saying that a and |
||||||
|
b are equal? if they are both symbols and the symbols are |
||||||
|
eq?, or if they are both lists such that (car a) is equal? |
||||||
|
to (car b) and (cdr a) is equal? to (cdr b). Using |
||||||
|
this idea, implement equal? as a procedure.102 |
@ -0,0 +1,8 @@ |
|||||||
|
|
||||||
|
Exercise 2.55: Eva Lu Ator types to the |
||||||
|
interpreter the expression |
||||||
|
|
||||||
|
|
||||||
|
(car ''abracadabra) |
||||||
|
|
||||||
|
To her surprise, the interpreter prints back quote. Explain. |
@ -0,0 +1,59 @@ |
|||||||
|
|
||||||
|
Exercise 2.56: Show how to extend the basic |
||||||
|
differentiator to handle more kinds of expressions. For instance, implement |
||||||
|
the differentiation rule |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
d |
||||||
|
( |
||||||
|
|
||||||
|
u |
||||||
|
|
||||||
|
|
||||||
|
n |
||||||
|
|
||||||
|
|
||||||
|
) |
||||||
|
|
||||||
|
|
||||||
|
d |
||||||
|
x |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
= |
||||||
|
|
||||||
|
|
||||||
|
n |
||||||
|
|
||||||
|
u |
||||||
|
|
||||||
|
|
||||||
|
n |
||||||
|
− |
||||||
|
1 |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
d |
||||||
|
u |
||||||
|
|
||||||
|
|
||||||
|
d |
||||||
|
x |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
by adding a new clause to the deriv program and defining appropriate |
||||||
|
procedures exponentiation?, base, exponent, and |
||||||
|
make-exponentiation. (You may use the symbol ** to denote |
||||||
|
exponentiation.) Build in the rules that anything raised to the power 0 is 1 |
||||||
|
and anything raised to the power 1 is the thing itself. |
@ -0,0 +1,12 @@ |
|||||||
|
|
||||||
|
Exercise 2.57: Extend the differentiation |
||||||
|
program to handle sums and products of arbitrary numbers of (two or more) |
||||||
|
terms. Then the last example above could be expressed as |
||||||
|
|
||||||
|
|
||||||
|
(deriv '(* x y (+ x 3)) 'x) |
||||||
|
|
||||||
|
Try to do this by changing only the representation for sums and products, |
||||||
|
without changing the deriv procedure at all. For example, the |
||||||
|
addend of a sum would be the first term, and the augend would be |
||||||
|
the sum of the rest of the terms. |
@ -0,0 +1,22 @@ |
|||||||
|
|
||||||
|
Exercise 2.58: Suppose we want to modify the |
||||||
|
differentiation program so that it works with ordinary mathematical notation, |
||||||
|
in which + and * are infix rather than prefix operators. Since |
||||||
|
the differentiation program is defined in terms of abstract data, we can modify |
||||||
|
it to work with different representations of expressions solely by changing the |
||||||
|
predicates, selectors, and constructors that define the representation of the |
||||||
|
algebraic expressions on which the differentiator is to operate. |
||||||
|
|
||||||
|
|
||||||
|
Show how to do this in order to differentiate algebraic expressions presented |
||||||
|
in infix form, such as (x + (3 * (x + (y + 2)))). To simplify the task, |
||||||
|
assume that + and * always take two arguments and that |
||||||
|
expressions are fully parenthesized. |
||||||
|
|
||||||
|
The problem becomes substantially harder if we allow standard algebraic |
||||||
|
notation, such as (x + 3 * (x + y + 2)), which drops unnecessary |
||||||
|
parentheses and assumes that multiplication is done before addition. Can you |
||||||
|
design appropriate predicates, selectors, and constructors for this notation |
||||||
|
such that our derivative program still works? |
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue