Sunday, December 27, 2020

SICP in Clojure: Chapter 1, Exercise 44

This is my Clojure solution to Chapter 1, Exercise 44:

(ns sicp.ch1.ex44
  (:require [sicp.ch1.ex16 :as ch1-ex16]
            [sicp.ch1.ex40 :as ch1-ex40]
            [sicp.ch1.ex43 :as ch1-ex43]))

(defn smooth
  [f]
  #(/ (+ (f (- % ch1-ex40/dx))
         (f %)
         (f (+ % ch1-ex40/dx)))
      3))

(defn n-fold-smooth
  [f n]
  ((ch1-ex43/repeated smooth n) f))

(comment
  ((smooth ch1-ex16/square) 5) ; => ~25

  ((n-fold-smooth ch1-ex16/square 2) 5) ; => ~25
  #__)

 

SICP in Clojure: Chapter 1, Exercise 43

This is my Clojure solution to Chapter 1, Exercise 43:

(ns sicp.ch1.ex43
  (:require [sicp.ch1.ex16 :as ch1-ex16]
            [sicp.ch1.ex42 :as ch1-ex42]))

(defn repeated
  [f n]
  (loop [g identity n n]
    (if (zero? n)
      g
      (recur (ch1-ex42/compose f g) (dec n)))))

(comment
  ((repeated ch1-ex16/square 2) 5) ; => 625
  #__)

 

Wednesday, December 23, 2020

SICP in Clojure: Chapter 1, Exercise 42

This is my Clojure solution to Chapter 1, Exercise 42:

(ns sicp.ch1.ex42
  (:require [sicp.ch1.ex16 :as ch1-ex16]))

(defn compose
  [f g]
  #(f (g %))) ; could use comp

(comment
  ((compose ch1-ex16/square inc) 6)
  #__)

 

SICP in Clojure: Chapter 1, Exercise 41

 This is my Clojure solution to Chapter 1, Exercise 41:

(ns sicp.ch1.ex41)

(defn double-it
  [f]
  #(f (f %))) ; could use comp

(comment
  (((double-it (double-it double-it)) inc) 5) ; => 21
  #__)
 

Sunday, November 29, 2020

SICP in Clojure: Chapter 1, Exercise 40

This is my Clojure solution to Chapter 1, Exercise 40:

(ns sicp.ch1.ex40
  (:require [sicp.ch1.ex15 :as ch1-ex15]
            [sicp.ch1.ex16 :as ch1-ex16]
            [sicp.ch1.ex35 :as ch1-ex35]))

(def dx 0.00001)

(defn deriv
  [f]
  #(/ (- (f (+ % dx)) (f %)) dx))

(defn newton-transform
  [f]
  #(- % (/ (f %) ((deriv f) %))))

(defn newtons-method
  [f guess]
  (ch1-ex35/fixed-point (newton-transform f) guess))

(defn cubic
  [a b c]
  #(+ (ch1-ex15/cube %)
      (* a (ch1-ex16/square %) (* b %) c)))

(comment
  (< ((cubic 1 2 3) (newtons-method (cubic 1 2 3) 1.0)) dx)
  #__)
 

Tuesday, September 01, 2020

SICP in Clojure: Chapter 1, Exercise 39

  This is my Clojure solution to Chapter 1, Exercise 39:

 (ns sicp.ch1.ex39
  (:require [sicp.ch1.ex16 :as ch1-ex16]
            [sicp.ch1.ex37 :as ch1-ex37]))

(defn tan-cf
  [x k]
  (/
   (ch1-ex37/cont-frac (constantly (- (ch1-ex16/square x)))
                       #(inc (* 2 (dec %)))
                       k)
   (- x)))

(comment
  (double (tan-cf (/ Math/PI 6) 10)) ; => 0.5773502691896257
  #__)

 

Monday, August 31, 2020

SICP in Clojure: Chapter 1, Exercise 38

 This is my Clojure solution to Chapter 1, Exercise 38:

(ns sicp.ch1.ex38
  (:require [sicp.ch1.ex37 :as ch1-ex37]))

(defn d
  [i]
  (let [j (- i 2)]
    (if (zero? (mod j 3))
      (* 2 (inc (/ j 3)))
      1)))

(comment
  (double (+ 2
             (ch1-ex37/cont-frac (constantly 1)
                                 d
                                 10))) ; => 2.718281718281718
  #__)
 

Tuesday, July 28, 2020

SICP in Clojure: Chapter 1, Exercise 37

This is my Clojure solution to Chapter 1, Exercise 37:

(ns sicp.ch1.ex37
  (:require [sicp.ch1.ex32 :as ch1-ex32]))

(def n (constantly 1))

(def d (constantly 1))

(defn cont-frac
  [n d k]
  (ch1-ex32/accumulate #(/ (n %1) (+ (d %1) %2))
                       0
                       identity
                       1
                       inc
                       k))

(defn cont-frac-iter
  [n d k]
  (ch1-ex32/accumulate-iter #(/ (n %1) (+ (d %1) %2))
                            0
                            identity
                            1
                            inc
                            k))

(double (/ 1
           (cont-frac (constantly 1)
                      (constantly 1)
                      12))) ; => 1.618055555555556 - accurate to 4
                                        ; decimal places

(double (/ 1 (cont-frac-iter (constantly 1)
                             (constantly 1)
                             12))) ; => 1.618055555555556

 

Sunday, June 14, 2020

SICP in Clojure: Chapter 1, Exercise 36

This is my Clojure solution to Chapter 1, Exercise 36:

(ns sicp.ch1.ex36
  (:require [sicp.ch1.ex35 :as ch1-ex35]))

(defn try-guess
  [f guess]
  (let [next-guess (f guess)]
    (println (double next-guess))
    (if (ch1-ex35/close-enough? guess next-guess)
      next-guess
      (try-guess f next-guess))))

(defn fixed-point
  [f first-guess]
  (try-guess f first-guess))

(defn try-guess-with-avg-damping
  [f guess]
  (let [next-guess (f guess)]
    (println (double next-guess))
    (if (ch1-ex35/close-enough? guess next-guess)
      next-guess
      (try-guess-with-avg-damping f (/ (+ next-guess guess) 2)))))

(defn fixed-point-with-avg-damping
  [f first-guess]
  (try-guess-with-avg-damping f first-guess))

(double (fixed-point #(/ (Math/log 1000) (Math/log %))
                     1.1)) ; => 4.555538934848503 -- 38 steps

(double (fixed-point-with-avg-damping #(/ (Math/log 1000)
                                          (Math/log %))
                                      1.1))
                                        ; => 4.555533149860501 in 14
                                        ; steps
 

Thursday, June 11, 2020

SICP in Clojure: Chapter 1, Exercise 35

This is my Clojure solution to Chapter 1, Exercise 35:

(ns sicp.ch1.ex35)

;; x = 1 + 1 / x
;; x^2 = x + 1
;; x^2 - x - 1 = 0
;; => use quadratic formula

(def tolerance 0.00001)

(defn close-enough?
  [v1 v2]
  (< (Math/abs (double (- v1 v2))) tolerance))

(defn try-guess
  [f guess]
  (let [next-guess (f guess)]
    (if (close-enough? guess next-guess)
      next-guess
      (try-guess f next-guess))))

(defn fixed-point
  [f first-guess]
  (try-guess f first-guess))

(double (fixed-point #(inc (/ 1 %)) 1)) ; => 1.618032786885246

 

Tuesday, April 07, 2020

SICP in Clojure: Chapter 1, Exercise 34

This is my Clojure solution to Chapter 1, Exercise 34:

(ns sicp.ch1.ex34
  (:require [sicp.ch1.ex16 :as ch1-ex16]))

(defn f
  [g]
  (g 2))

(f ch1-ex16/square) ; => 4

(f #(* % (inc %))) ; => 6

(f f) ; => -> (f 2) -> (2 2) -- error

 

Friday, March 13, 2020

SICP in Clojure: Chapter 1, Exercise 33

This is my Clojure solution to Chapter 1, Exercise 33:

(ns sicp.ch1.ex33
  (:require [sicp.ch1.ex16 :as ch1-ex16]
            [sicp.ch1.ex20 :as ch1-ex20]
            [sicp.ch1.ex23 :as ch1-ex23]))

(defn filtered-accumulate
  [combiner null-value term a succ b pred]
  (if (> a b)
    null-value
    (if (pred a)
      (combiner (term a)
                (filtered-accumulate combiner
                                     null-value
                                     term
                                     (succ a)
                                     succ
                                     b
                                     pred))
      (filtered-accumulate combiner
                           null-value
                           term
                           (succ a)
                           succ
                           b
                           pred))))

(defn sum-of-prime-squares
  [a b]
  (filtered-accumulate +
                       0
                       ch1-ex16/square a
                       inc
                       b
                       ch1-ex23/prime?))

(defn coprime?
  [a b]
  (= 1 (ch1-ex20/gcd a b)))

(defn product-of-coprimes
  [n]
  (filtered-accumulate * 1 identity 1 inc n (partial coprime? n)))

(sum-of-prime-squares 2 10) ; => 87

(sum-of-prime-squares 2 100) ; => 65797

(product-of-coprimes 10) ; => 189

(product-of-coprimes 11) ; => 3628800

Wednesday, January 22, 2020

SICP in Clojure: Chapter 1, Exercise 32

This is my Clojure solution to Chapter 1, Exercise 32:

(ns sicp.ch1.ex32
  (:require [sicp.ch1.ex29 :as ch1-ex29]
            [sicp.ch1.ex30 :as ch1-ex30]
            [sicp.ch1.ex31 :as ch1-ex31]))

(defn accumulate
  [combiner null-value term a succ b]
  (if (> a b)
    null-value
    (combiner (term a)
              (accumulate combiner null-value term (succ a) succ b))))

(defn sum
  [term a succ b]
  (accumulate + 0 term a succ b))

(defn product
  [term a succ b]
  (accumulate * 1 term a succ b))

(defn accumulate-iter
  [combiner null-value term a succ b]
  (letfn [(accumulate-iter-step
            [a result]
            (if (> a b)
              result
              (accumulate-iter-step (succ a)
                                    (combiner (term a) result))))]
    (accumulate-iter-step a null-value)))

(defn sum-iter
  [term a succ b]
  (accumulate-iter + 0 term a succ b))

(defn product-iter
  [term a succ b]
  (accumulate-iter * 1 term a succ b))

(= (ch1-ex29/sum identity 1 inc 10)
   (sum identity 1 inc 10)) ; => true

(= (ch1-ex30/sum-iter identity 1 inc 10)
   (sum-iter identity 1 inc 10)) ; => true

(= (ch1-ex31/product identity 1 inc 10)
   (product identity 1 inc 10)) ; => true

(= (ch1-ex31/product-iter identity 1 inc 10)
   (product-iter identity 1 inc 10)) ; => true