learning-sicp

My embarrassing half assed SICP run.
Log | Files | Refs

commit e482146b055647ce836e4756cdb0a716ac25e4ac
parent b32210566cbde0ad630e39f24ad0b068c8e0231f
Author: Yuval Langer <yuval.langer@gmail.com>
Date:   Mon, 20 Nov 2023 17:08:03 +0200

Add tests for chapter-1 exercise-8, (1.8).

Diffstat:
Msicp/solutions/chapter-1/exercise-8.scm | 97+++++++++++++++++++++++++++++++++++++++----------------------------------------
Asicp/tests/chapter-1/exercise-8.scm | 24++++++++++++++++++++++++
2 files changed, 72 insertions(+), 49 deletions(-)

diff --git a/sicp/solutions/chapter-1/exercise-8.scm b/sicp/solutions/chapter-1/exercise-8.scm @@ -1,49 +1,48 @@ -#! - -*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.) - -!# - -(define (cube-root x) - (define (improve guess) - ;; (dp guess x) - - (/ (+ (/ x - (* guess guess)) - (* 2 guess)) - 3)) - - (define (good-enough? old-guess new-guess) - (define bound 0.0000000000001) - (define ratio (/ old-guess new-guess)) - - (define within-bounds - (< (- 1 bound) ratio (+ 1 bound))) - - ;; (dp bound ratio within-bounds) - - within-bounds) - - (define (cube-root-iter guess) - (define new-guess (improve guess)) - ;; (dp new-guess) - - (if (good-enough? guess new-guess) - guess - (cube-root-iter new-guess))) - - (cube-root-iter 1)) - -(format #t "(cube-root ~f) => ~f\n" 0.000000000001 (cube-root 0.000000000001)) -(format #t "(cube-root ~f) => ~f\n" (/ 1 0.000000000001) (cube-root (/ 1 0.000000000001))) +(define-library (sicp solutions chapter-1 exercise-8) + (import (scheme base)) + (export cube-root) + + (begin + #! + + *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.) + + !# + + (define (cube-root x) + (define (improve guess) + (/ (+ (/ x + (* guess guess)) + (* 2 guess)) + 3)) + + (define (good-enough? old-guess new-guess) + (define bound 0.0000000000001) + (define ratio (/ old-guess new-guess)) + + (define within-bounds + (< (- 1 bound) ratio (+ 1 bound))) + + within-bounds) + + (define (cube-root-iter guess) + (define new-guess (improve guess)) + (if (good-enough? guess new-guess) + guess + (cube-root-iter new-guess))) + + ;; Start with a floating point 1.0 instead of an integer 1 to + ;; avoid creating a rational with huge enumerator and + ;; denominator with the "/" procedure. + (cube-root-iter 1.0)))) diff --git a/sicp/tests/chapter-1/exercise-8.scm b/sicp/tests/chapter-1/exercise-8.scm @@ -0,0 +1,24 @@ +(define-library (sicp tests chapter-1 exercise-8) + (import (scheme base) + (scheme write) + (srfi :64) + (sicp solutions chapter-1 exercise-8)) + + (begin + (test-begin "chapter-1-exercise-8") + + (test-expect-fail 1) + ;; XXX: I don't get the approximation here. + (for-each + (lambda (x) + (let ((expected (expt (expt x 3) + (/ 1.0 3))) + (test-expr (cube-root (expt x 3))) + (error 0.01)) + (test-approximate + expected + test-expr + error))) + (list 20000000000000 + 2 + (/ 1 20000000000000)))))