mirror of
https://github.com/correl/sicp.git
synced 2024-11-23 11:09:57 +00:00
279 lines
7.9 KiB
Org Mode
279 lines
7.9 KiB
Org Mode
#+BEGIN_HTML
|
|
---
|
|
title: 1.1 - The Elements of Programming
|
|
layout: org
|
|
---
|
|
#+END_HTML
|
|
|
|
* Code
|
|
#+BEGIN_SRC scheme :tangle yes
|
|
(define (square x)
|
|
(* x x))
|
|
|
|
|
|
(define (sum-of-squares a b)
|
|
(+ (square a) (square b)))
|
|
|
|
;; (define (abs x)
|
|
;; (cond ((< x 0) (- x))
|
|
;; ((= x 0) 0)
|
|
;; ((> x 0) x)))
|
|
|
|
(define (abs x)
|
|
(if (< x 0) (- x)
|
|
x))
|
|
|
|
(define (average x y)
|
|
(/ (+ x y) 2))
|
|
|
|
(define (sqrt x)
|
|
(define (sqrt-iter guess x)
|
|
(if (good-enough? guess x)
|
|
guess
|
|
(sqrt-iter (improve guess x)
|
|
x)))
|
|
|
|
(define (improve guess x)
|
|
(average guess (/ x guess)))
|
|
|
|
(define (good-enough? guess x)
|
|
(< (abs (- (square guess) x)) 0.001))
|
|
|
|
(sqrt-iter 1.0 x))
|
|
|
|
#+END_SRC
|
|
* Exercises
|
|
** 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 whichit is presented.
|
|
|
|
#+BEGIN_SRC scheme
|
|
;; -------------------------------------------------------------------
|
|
;; Exercise 1.1
|
|
;; -------------------------------------------------------------------
|
|
|
|
10
|
|
;; 10
|
|
|
|
(+ 5 3 4)
|
|
;; 12
|
|
|
|
(- 9 1)
|
|
;; 8
|
|
|
|
(/ 6 2)
|
|
;; 3
|
|
|
|
(+ (* 2 4) (- 4 6))
|
|
;; 10
|
|
|
|
(define a 3)
|
|
;; 3
|
|
|
|
(define b (+ a 1))
|
|
;; 4
|
|
|
|
(+ a b (* a b))
|
|
;; 19
|
|
|
|
(= a b)
|
|
;; #f
|
|
|
|
(if (and (> b a) (< b (* a b)))
|
|
b
|
|
a)
|
|
;; 4
|
|
|
|
(cond ((= a 4) 6)
|
|
((= b 4) (+ 6 7 a))
|
|
(else 25))
|
|
;; 16
|
|
|
|
(+ 2 (if (> b a) b a))
|
|
;; 6
|
|
|
|
(* (cond ((> a b) a)
|
|
((< a b) b)
|
|
(else -1))
|
|
(+ a 1))
|
|
;; 16
|
|
#+END_SRC
|
|
** Exercise 1.2
|
|
Translate the following expression into prefix form.
|
|
|
|
#+BEGIN_EXAMPLE
|
|
5 + 4 + (2 - (3 - (6 + 4/5)))
|
|
-----------------------------
|
|
3(6 - 2)(2 - 7)
|
|
#+END_EXAMPLE
|
|
|
|
#+BEGIN_SRC scheme :tangle yes
|
|
;; -------------------------------------------------------------------
|
|
;; Exercise 1.2
|
|
;; -------------------------------------------------------------------
|
|
|
|
(define ex1.2
|
|
(/ (+ 5 4 (- 2 (- 3 (+ 6 (/ 4 5)))))
|
|
(* 3 (- 6 2) (- 2 7))))
|
|
#+END_SRC
|
|
** Exercise 1.3
|
|
Define a procedure that takes three numbers as arguments and
|
|
returns the sum of the squares of the two larger numbers.
|
|
|
|
#+BEGIN_SRC scheme :tangle yes
|
|
;; -------------------------------------------------------------------
|
|
;; Exercise 1.3
|
|
;; -------------------------------------------------------------------
|
|
|
|
(define (ex1.3 a b c)
|
|
(cond ((and (> b a) (> c a)) (sum-of-squares b c))
|
|
((and (> a b) (> c b)) (sum-of-squares a c))
|
|
(#t (sum-of-squares a b))))
|
|
|
|
(define (ex1.3-fancy a b c)
|
|
(let* ((sorted (sort (list a b c) >))
|
|
(x (car sorted))
|
|
(y (cadr sorted)))
|
|
(+ (square x) (square y))))
|
|
#+END_SRC
|
|
|
|
** 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:
|
|
|
|
#+BEGIN_SRC scheme
|
|
(define (a-plus-abs-b a b)
|
|
((if (> b 0) + -) a b))
|
|
#+END_SRC
|
|
|
|
-------------------------------------------------------------------
|
|
|
|
When the function is called, the following will happen:
|
|
|
|
* The first expression in the list, (if (> b 0) + -) will be
|
|
evaluated. Within it, (> b 0) will be evaluated first, and based
|
|
on the value of b, the result of the evaluation will be + or -.
|
|
* The remaining expressions (a and b) will be evaluated to their
|
|
passed-in values.
|
|
* The resulting expression will be evaluated, e.g. (+ 3 2)
|
|
* The final result will be the result of applying the + or -
|
|
operator to the operands a and b
|
|
|
|
** 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:
|
|
|
|
#+BEGIN_SRC scheme
|
|
(define (p) (p))
|
|
|
|
(define (test x y)
|
|
(if (= x 0)
|
|
0
|
|
y))
|
|
#+END_SRC
|
|
|
|
Then he evaluates the expression
|
|
|
|
#+BEGIN_SRC scheme
|
|
(test 0 (p))
|
|
#+END_SRC
|
|
|
|
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.)
|
|
|
|
-------------------------------------------------------------------
|
|
|
|
Applicative order evaluation will evaluate test, 0 and (p), then
|
|
evaluate the application of the operator test on its
|
|
operands. However, attempting to evaluate (p) will hang, as it is a
|
|
recursive function that never exits.
|
|
|
|
Normal order evaluation will first apply the operator test on its
|
|
operands, which will then evaluate 0 in the if statment. The
|
|
conditional expression will succeed, and so the function will
|
|
return 0, never evaluating (p).
|
|
|
|
** 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':
|
|
|
|
#+BEGIN_SRC scheme
|
|
(define (new-if predicate then-clause else-clause)
|
|
(cond (predicate then-clause)
|
|
(else else-clause)))
|
|
#+END_SRC
|
|
|
|
Eva demonstrates the program for Alyssa:
|
|
|
|
#+BEGIN_SRC scheme
|
|
(new-if (= 2 3) 0 5)
|
|
5
|
|
|
|
(new-if (= 1 1) 0 5)
|
|
0
|
|
#+END_SRC
|
|
|
|
Delighted, Alyssa uses `new-if' to rewrite the square-root program:
|
|
|
|
#+BEGIN_SRC scheme
|
|
(define (sqrt-iter guess x)
|
|
(new-if (good-enough? guess x)
|
|
guess
|
|
(sqrt-iter (improve guess x)
|
|
x)))
|
|
#+END_SRC
|
|
|
|
What happens when Alyssa attempts to use this to compute square
|
|
roots? Explain.
|
|
|
|
-------------------------------------------------------------------
|
|
|
|
Calls to sqrt-iter will recurse indefinitely. This is because both
|
|
the then-clause and the else-clause passed to new-if will be
|
|
evaluated before the function new-if is applied.
|
|
|
|
** 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?
|
|
|
|
-------------------------------------------------------------------
|
|
|
|
** 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
|
|
|
|
#+BEGIN_EXAMPLE
|
|
x/y^2 + 2y
|
|
----------
|
|
3
|
|
#+END_EXAMPLE
|
|
|
|
Use this formula to implement a cube-root procedure analogous to
|
|
the square-root procedure. (In section *Note 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.)
|
|
|
|
-------------------------------------------------------------------
|