timothy235 icon

sicp-1-1-the-elements-of-programming

timothy235 | PRO | 12/19/24 01:23:05 AM UTC (Edited) | 0 ⭐ | 404 👁️ | Never ⏰ | []
Racket |

4.07 KB

|

None

|

0 👍

/

0 👎

#lang racket
 
;; 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)
;; #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
 
;; 1.2
 
(/ (+ 5 4 (- 2 (- 3 (+ 6 (/ 1 5)))))
   (* 3 (- 6 2) (- 2 7)))
 
;; 1.3
 
(define (sum-of-squares-of-biggest-two-of-three x y z)
  (cond [(and (>= x z) (>= y z)) (+ (* x x) (* y y))]
        [(and (>= x y) (>= z y)) (+ (* x x) (* z z))]
        [else (+ (* y y) (* z z))]))
 
(sum-of-squares-of-biggest-two-of-three 3 4 2)
;; 25
(sum-of-squares-of-biggest-two-of-three 3 2 4)
;; 25
(sum-of-squares-of-biggest-two-of-three 2 3 4)
;; 25
 
;; 1.4
 
;; If b > 0, add b to a.  If b <= 0, subtract b from a.
 
(define (a-plus-abs-b a b)
  ((if (> b 0) + -) a b))
 
;; 1.5
 
;; Procedure p produces an infinite loop.  If the interpreter is using
;; applicative-order evaluation, the argument (p) to the function call will always
;; be evaluated, producing an infinite loop.  If the interpreter is using
;; normal-order evaluation, then the arguments will only be evaluated as needed by
;; the if form, and since the predicate is true, the (p) in the alternate clause
;; will never get evaluated, avoiding the infinite loop.
 
;; The Racket repl is using applicative-order evaluation.
 
(define (p) (p))
(define (test x y)
  (if (= x 0)
    0
    y))
 
;; (test 0 (p))
;; user break
 
;; 1.6
 
;; Using the new-if procedure instead of the if special form will produce an
;; infinte loop because the new-if procedure always evaluates the else-clause,
;; which calls sqrt-iter again.
 
(define (new-if predicate then-clause else-clause)
  (cond [predicate then-clause]
        [else else-clause]))
(define (average x y)
  (/ (+ x y) 2))
(define (improve guess x)
  (average guess (/ x guess)))
(define (good-enough? guess x)
  (< (abs (- (sqr guess) x)) 0.001))
 
(define (sqrt-iter guess x)
  (if (good-enough? guess x)
    guess
    (sqrt-iter (improve guess x)
               x)))
(define (my-sqrt x)
  (sqrt-iter 1.0 x))
 
(define (sqrt-iter-new-if guess x)
  (new-if (good-enough? guess x)
          guess
          (sqrt-iter-new-if (improve guess x)
                            x)))
(define (my-sqrt-new-if x)
  (sqrt-iter-new-if 1.0 x))
 
(sqrt 2) ; using the racket built-in
;; 1.4142135623730951
(my-sqrt 2)
;; 1.4142156862745097
;; (my-sqrt-new-if 2)
;; user break
 
;; 1.7
 
;; For large numbers my-sqrt can be very inefficient.
 
(time (sqrt 1e13))
;; cpu time: 0 real time: 0 gc time: 0
;; 3162277.6601683795
;; (time (my-sqrt 1e13))
;; user break
 
;; For small numbers the margin of error obscures the answer.
 
(sqrt 0.000004)
;; 0.002
(my-sqrt 0.000004)
;; 0.03129261341049664 ; this is basically the sqrt of the margin of error
(sqrt 0.001)
;; 0.03162277660168379
 
(define (new-good-enough? new-guess old-guess)
  (< (abs (/ (- new-guess old-guess)
             old-guess))
     0.001))
(define (new-sqrt-iter old-guess x)
  (let ([new-guess (improve old-guess x)])
    (if (new-good-enough? new-guess old-guess)
      new-guess
      (new-sqrt-iter new-guess x))))
(define (new-my-sqrt x)
  (new-sqrt-iter 1.0 x))
 
;; For large numbers new-my-sqrt is more efficient but less accurate.
 
(time (new-my-sqrt 1e13))
;; cpu time: 0 real time: 0 gc time: 0
;; 3162277.6640104805
 
;; For small numbers the margin of error no longer hides the answer.
 
(new-my-sqrt 0.000004)
;; 0.0020000003065983023
 
;; 1.8
 
(define (cbrt-improve guess x)
  (/ (+ (/ x (sqr guess)) (* 2 guess)) 3))
(define (cbrt-iter old-guess x)
  (let ([new-guess (cbrt-improve old-guess x)])
    (if (new-good-enough? new-guess old-guess)
      new-guess
      (cbrt-iter new-guess x))))
(define (my-cbrt x)
  (cbrt-iter 1.0 x))
 
(my-cbrt 8)
;; 2.000000000012062
(my-cbrt 27)
;; 3.0000005410641766
(my-cbrt 1e24)
;; 100000000.00081353

Comments