SICP/ex-1_1-8.scm

134 lines
3.5 KiB
Scheme

(display "ex-1.1 - solutions in comments\n")
; 10 -> 10
; (+ 5 3 4) -> 12
; (- 9 1) -> 8
; (/ 6 2) -> 3
; (+ (* 2 4) (- 4 6)) -> 6
; (define a 3) -> a
; (define b (+ a 1)) -> b
; (+ a b (* a b)) -> 19
; (= a b) -> #f
; (if (and (> b a) (< b (* a b))) b a) ; -> b -> 4
; (cond ((= a 4) 6)
; ((= b 4) (+ 6 7 a))
; (else 25)) -> 126
; (+ 2 (if (> b a) b a)) -> 6
; (* (cond ((> a b) a)
; ((< a b) b)
; (else -1))
; (+ a 1)) ->
(display "ex-1.2 - ")
(display (/ (+ 5 4 (- 2 (- 3 (+ 6 (/ 4 5)))))
(* 3 (- 6 2) (- 2 7))))
(newline)
(display "ex-1.3 - ")
(define (sum-squares a b) (+ (* a a) (* b b)))
(define (sum-squares-max a b c)
(cond ((and (>= a c) (>= b c)) (sum-squares a b))
((and (>= a b) (>= c b)) (sum-squares a c))
(else (sum-squares b c))))
(display (sum-squares-max 2 -6 1))
(newline)
(display "ex-1.4 - Operator becomes + or - depending on the value of b\n")
; (define (a-plus-abs-b a b)
; ((if (> b 0) + -) a b))
(display "ex-1.5 - Only normal-order terminates\n")
;(define (p) (p))
;(define (test x y)
; (if (= x 0) 0 y))
;(display (if (= 0 0) 0 (p)))
; Will not terminate:
;(display (test 0 (p)))
(display "\n; Square roots via Newton's Method") (newline)
(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 (average a b) (/ (+ a b) 2))
(define (good-enough? guess x)
(< (abs (- (square guess) x)) 0.0001))
(define (square a) (* a a))
(define (sqrt x) (sqrt-iter 1.0 x))
(display (sqrt 9))
(newline)
(display (sqrt (+ 100 37)))
(newline)
(display (sqrt (+ (sqrt 2) (sqrt 3))))
(newline)
(display (square (sqrt 1000)))
(newline)
(display "\nex-1.6 - see comment\n")
(define (new-if predicate then-clause else-clause)
(cond (predicate then-clause)
(else else-clause)))
;(define (sqrt-iter guess x)
; (new-if (good-enough? guess x)
; guess
; (sqrt-iter (improve guess x)
; x)))
;(display (sqrt 9))
; sqrt-iter doesn't terminate because new-if is evaluated in applicative
; order which results in an endless recursion of sqrt-iter -> new-if.
(display "\nex-1.7 - see comments for explanation\nwrong behavior:\n")
(display (sqrt 9)) (newline)
; Very small numbers don't work because the delta between the initial
; guess and the expected solution is in a smaller dimension than the
; value used in good-enough?
(display (sqrt 0.0000001)) (newline)
; For very large numbers, good-enough? will never return true because the
; representation of floating point numbers is not accurate enough for their
; difference to ever fall below the tolerance value.
;(display (sqrt 9732402478147293489)) (newline)
(display "better:\n")
(define (good-enough2? guess new-guess)
(< (/ (abs (- new-guess guess)) new-guess) 0.00000000001))
(define (sqrt-iter-precise guess x)
(if (good-enough2? guess (improve guess x))
guess
(sqrt-iter-precise (improve guess x)
x)))
(display (sqrt 9)) (newline)
(display (sqrt 0.00000001)) (newline)
; (display (sqrt 9732402478147293489))
; works with racket and newer MIT Scheme versions
(display "\nex-1.8 - cube-root") (newline)
(define (improve-cubic y x) (/ (+ (/ x (* y y)) (* 2 y)) 3))
(define (cbrt-iter guess x)
(if (good-enough2? guess (improve-cubic guess x))
guess
(cbrt-iter (improve-cubic guess x) x)))
(define (cbrt x) (cbrt-iter 1.0 x))
(display (cbrt 27)) (newline)
(display (cbrt 0.001)) (newline)