Structure and Interpretation of Computer Programs notes I
24 Jan 2014
environment:
There are multiple List dialects. The one used in this book is Scheme:
Then run “mit-scheme” in the shell.
I also installed Steel Bank Common Lisp:
Then run “sbcl” in the shell.
in “mit-scheme”, if you type something by mistake, or the expression is
invalid, We will enter “Error system”, like:
2 error>
To jump out of Error system, input (RESTART x) x is the option number
Chapter 1 Building Abstractions with Procedures
1. define variables
2. define functions
3. condition expression
4. Newton’s method to get square root
Whenever we have a guess y for the value of the square root of a number x, we can perform a simple manipulation to get a better guess by average y with x/y.
5. Internal definitions and block structure
It is not necessary to pass x explicitly to each of these procedures. Instead, we allow x to be a free variable in the internal definitions.
This discipline is called lexical scoping.
6. Linear Recursion and Iteration
Linear Recursion:
Linear Iterative:
Difference: bottom-up vs. top-down
Linear iterative does not grow and shrink. At each step, all we need to keep track of, are the current value of the variables product, counter and max-count.
Scheme will execute an iterative process in constant space even if the iterative process is described by a recursive procedure. An implementation with this property is called tail-recursive.
7. How many different ways can we make change of $1.00
The number of ways to change amount a using n kinds of coins equals:
The number of ways to change amount a using all but the first kind of coins, plus
The number of ways to change amount a-d using all n kinds of coins, where d is the denomination of the first kind of coin
8. GCD and Fibonacci number
Lame’s Theorem: If Euclid’s Algorithm requires k steps to compute the GCD of some pair, then the smaller number in the pair must be greater than or equal to the kth Fibonacci number.
Let n be the smaller of the two inputs to the procedure. If the process takes k steps, then we must have $n\geq Fib(k) \approx \phi^{k}/\sqrt{5}$, Hence the order of growth is $\Theta(log n)$
Fermat’s Little Theorem: If n is a prime number and a is any positive integer less than n, then a raised the nth power is congruent to a modulo n.
the Fermat test: If n is not prime, then, in general, most of the number a<n will not satisfy the above relation. This leads to the following algorithm for testing primality: Given a number n, pick a random number a<n and compute the remainder of a^n modulo n. If the result is not equal to a, then n is certainly not prime. If it is a, then chances are good that n is prime. Now pick another random number a and test it with the same method. If it also satisfies the equation, then we can be even more confident that n is prime. By trying more and more values of a, we can increase our confidence in the result.
Miller-Rabin primality test: if p is a prime, x is a positive integer less than p, and x^2 mod p=1, then x=1 or x=p-1.
10. Higher-order Procedure
Procedures that can accept procedures as arguments or return procedures as values are called high-order procedures
11. Procedures as Arguments
Consider the following 3 procedures. The first computes the sum of the integers from a through b
The second computes the sum of the cubes of the integers in the given range.
The third computes the sum of a sequence of terms in the series
1/(1*3) + 1/(5*7) + 1/(9*11) + …
which converges to pi/8 (very slowly):
We would like our language to be powerful enough so that we can write a procedure that express the concept of summation itself rather than only procedures that compute particular sums.
We can use it to define sum-cubes, sum-integers and pi-sum:
Once we have sum, we can use it as a building block in formulating further concept. For instance, the definition integeral of a function f between the limits a and b can be approximated numberically using the formula:
12. Construct procedure using Lambda
is equivalent to
a lambda expression can be used as the operator in a combination such as
13. Using let to create local variables
Suppose we wish to compute the function
f(r,y)=r(1+ry)^2+y(1-y)+(1+ry)(1-y)
which we could also express as
a=1+ry
b=1-y
f(r,y)=ra^2+yb+ab
Using let, the f procedure could be written as
the scope of the variable specified by a let expression is the body of let
The variables’ values are computed outside the let. For example, if the value of x is 2, the expression
will have the value 12 because, inside the body of the let, x will be 3 and y will be 4 (which is the outer x plus 2)
14. Find roots of equations by the half-interval method
15. Find fixed points of functions
A number x is called fixed point of a function f if x satisfies the equation f(x)=x. For some functions f we can locate a fixed point by beginning with an initial guess and applying f repeatedly.
f(x), f(f(x)), f(f(f(x))), …
We can try to compute square root as
Unfortunately, this fixed-point search does not converge. Consider an initial guess y1, the next guess y2=x/y1 and the next guess y3=x/y2=x/(x/y1)=y1
One way to control such oscillations is to prevent the guesses from changing so much. Since the answer is always between our guess y and x/y, we can make new guess that is not as far from y as x/y by averaging y with x/y, so that the next guess after y is (1/2)(y+x/y) instead of x/y
16. Procedures as Returned Values
Using average-damp, we can reformulate the square-root procedure as follows:
Notice that the cube root of x is a fixed point of the function f(y)=x/y^2, so we can generalize our square-root procedure:
17. Newton’s method
If g(x) is a differentiable function, then a solution of the equation g(x)=0 is a fixed point of the function f(x) where
With the aid of deriv, we can express Newton’s method as a fixed-point process:
To find the square root of x, we can use Newton’s method to find a zero of the function f(y)=y^2-x starting with an initial guess of 1
We’ve seen to ways to express the square-root computation as instance of a more general method. We can express this general idea idea itself as a procedure:
Using this abstraction, we can recast the first square-root computation as:
Similar, we can express the second square-root computation as:
Elements with the fewest restrictions are said to have first-class status. Some of the “rights and privileges” of first elements are:
They may be named by varialbes
They may be passed as arguments to procedures
They may be returned as the results of procedures
They may be included in data structures.
Lisp awards procedures full first-class status.
Exercise 1.1
10
12
8
3
ddd
19
false
4
16
6
16
Exercise 1.2
Exercise 1.3
Exercise 1.6
maximum recursion depth exceeded
Since the else-clause is always executed in new-if.
Exercise 1.8
Exercise 1.10
1024
65536
65536
(f n) = 2n
(g n) = 2^n
(h n) = 2^(2^(2^(…)))
Exercise 1.11
Exercise 1.12
Exercise 1.13
define $\widehat{\phi}=(1-\sqrt{5})/2$, both $\phi$ and $\widehat{\phi}$ are the roots of the equation $x^2-x-1=0$, so we have ${\phi}^2={\phi}+1$; ${\widehat{\phi}}^2={\widehat{\phi}}+1$
Suppose $Fib(k)=({\phi}^{k}-{\widehat{\phi}}^{k})/{\sqrt{5}}$ for all the $k<n$, then,