mirror of
https://github.com/correl/sicp.git
synced 2024-11-23 11:09:57 +00:00
Section 1.1
This commit is contained in:
commit
448d4d00aa
1 changed files with 243 additions and 0 deletions
243
1-1.scm
Normal file
243
1-1.scm
Normal file
|
@ -0,0 +1,243 @@
|
|||
;; ====================================================================
|
||||
;; SICP - 1.1: The Elements of Programming
|
||||
;; ====================================================================
|
||||
|
||||
(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))
|
||||
|
||||
|
||||
;; ====================================================================
|
||||
;; *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
|
||||
;; 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
|
||||
|
||||
;; ===================================================================
|
||||
;; *Exercise 1.2:* Translate the following expression into prefix
|
||||
;; form.
|
||||
;;
|
||||
;; 5 + 4 + (2 - (3 - (6 + 4/5)))
|
||||
;; -----------------------------
|
||||
;; 3(6 - 2)(2 - 7)
|
||||
;; -------------------------------------------------------------------
|
||||
|
||||
(define ex1.2
|
||||
(/ (+ 5 4 (- 2 (- 3 (+ 6 (/ 4 5)))))
|
||||
(* 3 (- 6 2) (- 2 7))))
|
||||
|
||||
;; ===================================================================
|
||||
;; *Exercise 1.3:* Define a procedure that takes three numbers as
|
||||
;; arguments and returns the sum of the squares of the two larger
|
||||
;; numbers.
|
||||
;; -------------------------------------------------------------------
|
||||
|
||||
(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))))
|
||||
|
||||
;; ===================================================================
|
||||
;; *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))
|
||||
;; -------------------------------------------------------------------
|
||||
|
||||
;; 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:
|
||||
;;
|
||||
(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.)
|
||||
;; -------------------------------------------------------------------
|
||||
|
||||
;; 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':
|
||||
;;
|
||||
;; (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.
|
||||
;; -------------------------------------------------------------------
|
||||
|
||||
;; 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
|
||||
;;
|
||||
;; x/y^2 + 2y
|
||||
;; ----------
|
||||
;; 3
|
||||
;;
|
||||
;; 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.)
|
||||
;; -------------------------------------------------------------------
|
Loading…
Reference in a new issue