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