238 lines
5.9 KiB
Scheme
238 lines
5.9 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 "\nex-1.2 - ")
|
|
(display (/ (+ 5 4 (- 2 (- 3 (+ 6 (/ 4 5)))))
|
|
(* 3 (- 6 2) (- 2 7))))
|
|
(newline)
|
|
|
|
(display "\nex-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 "\nex-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 "\nex-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 "\nexample - 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)
|
|
|
|
|
|
(newline) (display "ex-1.9 - see comments in code\n")
|
|
|
|
;(define (+ a b)
|
|
; (if (= a 0)
|
|
; b
|
|
; (inc (+ (dec a) b))))
|
|
; + 3 2
|
|
; (inc (+ 2 2))
|
|
; (inc (inc (+ 1 2)))
|
|
; (inc (inc (inc (+ 0 2)))
|
|
; (inc (inc (inc 2)))
|
|
; -> recursive process
|
|
|
|
;(define (+ a b)
|
|
; (if (= a 0)
|
|
; b
|
|
; (+ (dec a) (inc b))))
|
|
; (+ 3 2)
|
|
; (+ 2 3)
|
|
; (+ 1 4)
|
|
; (+ 0 5)
|
|
; 5
|
|
; -> iterative process
|
|
|
|
|
|
(display "\nex-1.10 - Ackermann") (newline)
|
|
(define (A x y)
|
|
(cond ((= y 0) 0)
|
|
((= x 0) (* 2 y))
|
|
((= y 1) 2)
|
|
(else (A (- x 1)
|
|
(A x (- y 1))))))
|
|
|
|
(display (A 1 10)) (newline)
|
|
; (A 1 10)
|
|
; (A 0 (A 1 9))
|
|
; (* 2 (A 1 9))
|
|
; (* 2 (A 0 (A 1 8))
|
|
; (* 2 (* 2 (A 1 8))
|
|
; -> 2^10 = 1024
|
|
(display (A 2 4)) (newline)
|
|
; (A 2 4)
|
|
; (A 1 (A 2 3))
|
|
; (2 ^ (A 2 3))
|
|
; (2 ^ (A 1 (A 2 2))
|
|
; (2 ^ 2 ^ (A 2 2)
|
|
; -> 2^2^2^2 = 65536
|
|
(display (A 3 3)) (newline)
|
|
; (A 3 3)
|
|
; (A 2 (A 3 2))
|
|
; (2 ^* (A 3 2))
|
|
; (2 ^* (A 2 (A 3 1)))
|
|
; (2 ^* 2 ^* 2)
|
|
; (2 ^* (2^2))
|
|
; (2^2^2^2) = 65536
|
|
|
|
(define (f n) (A 0 n)) ; f(n)=2*n
|
|
(display (f 111)) (newline)
|
|
|
|
(define (g n) (A 1 n)) ; g(n)=2^n
|
|
(display (g 12)) (newline)
|
|
|
|
(define (h n) (A 2 n)) ; h(n)=2^2^2^... or 2^(h(n-1))
|
|
(display (h 4)) (newline)
|
|
|
|
|
|
(newline) (display "example - Couting Change") (newline)
|
|
|
|
(define (dec x) (- x 1))
|
|
|
|
(define (counting-change-iter amount current-coin)
|
|
(cond ((= amount 0) 1)
|
|
((= current-coin 0) 0)
|
|
((< amount 0) 0)
|
|
(else (+ (counting-change-iter (- amount (list-of-coins current-coin)) current-coin)
|
|
(counting-change-iter amount (dec current-coin)))
|
|
)))
|
|
|
|
(define (list-of-coins coin-index)
|
|
(cond ((= coin-index 1) 1)
|
|
((= coin-index 2) 5)
|
|
((= coin-index 3) 10)
|
|
((= coin-index 4) 25)
|
|
((= coin-index 5) 50)))
|
|
|
|
(define (count-change amount) (counting-change-iter amount 5))
|
|
|
|
(display "(count-change 100) = ")
|
|
(display (count-change 100)) (newline)
|
|
|
|
; Try to implement a better version. Worked in Python. See Euler.
|
|
;(define (counting-change-iter amount count-coin current-coin)
|
|
; (cond ((= current-coin 0) 0)
|
|
; ((<= amount 0) 0)
|
|
; (else (+ (counting-change-iter (- amount (list-of-coins current-coin)) (+ count-coin 1) current-coin)
|
|
; (if (and (= count-coin 0)(= (modulo amount (list-of-coins current-coin)) 0)) 1 0)
|
|
; (counting-change-iter amount 0 (- current-coin 1))
|
|
; ))))
|
|
|
|
;(display "(count-change 100) = ")
|
|
;(display (counting-change-iter 100 0 5)) (newline)
|
|
|