SICP Solutions: 1.8

July 7th, 2008

Here’s my solution for 1.8:

Scheme:

This is pretty simple. All we have to do is update the improve function to use our new equation, and change the names of the sqrt-* functions to crt-*:

> (define (improve guess x)
(/ (+ (* 2 guess) (/ x (square guess))) 3)
)
> (my-crt 27)
3.0000005410641766

SICP Solutions: 1.7

July 7th, 2008

Here’s my solution to 1.7:

So, first of all, I had to rename the function ‘my-sqrt’ because DrScheme complained about redefining ’sqrt’. Anyway, you can see some of the problem when running any simple square root:

> (my-sqrt 9)
3.00009155413138
> (sqrt 9)
3

The issue is that computers don’t have an infinite amount of precision. Rounding errors start to add up the more and more times we iterate. If this variance happens to be greater than our tolerance, we can keep going into infinity, as our guess bounces too large and too small to ever terminate.

> (my-sqrt 99999999999999999)
. . user break
> (sqrt 99999999999999999)
316227766.01683795

So we’ll re-implement with the strategy in the text:

> (define (good-enough? guess x)
(< (/ (abs (- guess x)) guess) 0.001))
> (define (sqrt-iter guess prev x)
(if (good-enough? guess prev)
guess
(sqrt-iter (improve guess x)
guess
x)
)
)
> (define (my-sqrt x) (sqrt-iter 1.0 x x))
> (my-sqrt 9)
3.000000001396984
> (my-sqrt 99999999999999999)
316227766.01784706

As we can see, we change the good-enough? predicate to check the ratio of the guess’s change. That’s where the division comes from. The only other modifications we have to do is include the previous guess in our calls. I’ve made the initial call use the number we’re trying to find the root of as an initial guess, because it is. As you can see, this is much more precise, and actually terminates for large numbers.

SICP Solutions: 1.6

July 7th, 2008

Here’s my solution to 1.6:

This is very similar to 1.5 (go figure). Because our new if is a function, it evaluates the parameters first. This results in an infinite loop, since the third parameter to ‘new-if’ is another call to ’square-iter,’ which adds a new ‘new-if’…

SICP Solutions, 1.5:

July 7th, 2008

Here’s my solution to 1.5:

Applicative order will cause the interpreter to go into an infinite loop. It will expand ‘p’ to ‘p’ over and over and over and over and over… normal order will just return (p).

SICP Solutions: 1.4

July 7th, 2008

Here’s my solution to 1.4:

The condition checks on the sign of b. If b is positive, a ‘+’ is returned, while if b is negative, a ‘-’. This has the same affect as adding the absolute value of b, because subtracting a negative is the same as adding a positive.

SICP Solutions: 1.3

July 5th, 2008

Here’s my solution for 1.3:

Scheme:

(define (f x y z)
(cond ((and (<= z x) (<= z y)) (+ (* x x) (* y y)))
((and (<= y z) (<= y x)) (+ (* z z) (* x x)))
((and (<= x y) (<= x z)) (+ (* y y) (* z z)))
))

SICP Solutions: 1.2

July 5th, 2008

Here’s my solution for 1.2:

Scheme:

(/ (+ 5 4 (- 2 (- 3 (+ 6 (/ 4 5))))) (* 3 (- 6 2) (- 2 7)))

SICP Solutions: 1.1

July 5th, 2008

Here’s my answer for 1.1:

10: 10
(+ 5 3 4): 12
(- 9 1): 8
(/ 6 2): 3
(+ (* 2 4) (- 4 6)): 6
(define a 3):
(define b (+ a 1)):
(+ a b (* a b)): 19
(= a b): false
(if (and (> b a) (< b (* a b)))
b
a): I thought this would say ‘4′ but it actually says ‘(make-promise …)’
(cond ((= a 4) 6)
((= b 4) (+ 6 7 a))
(else 25)):same thing, though I thought ‘16′
(+ 2 (if (> b a) b a)): 6
(* (cond ((> a b) a)
((< a b) b)
(else -1))
(+ a 1)): 16

SICP Solutions: 1.44

July 5th, 2008

Here’s my solution to 1.44:

Scheme:

(define (smooth f dx)
(lambda (x)
(average (f (- x dx)) (f x) (f (+ x dx)))))

SICP Solutions: 1.43

July 5th, 2008

Here’s my solution to 1.43:

Scheme:

(define (repeated f n)
(lambda (x)
(if (= n 1)
(f x)
((my-compose f (repeated f (- n 1))) x)
)))