Thursday, December 26, 2019

SICP in Clojure: Chapter 1, Exercise 31

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

(ns sicp.ch1.ex31)

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

(defn factorial
  [n]
  (product identity 1 inc n))

(defn pi-approx
  [n]
  (* (product #(if (odd? %)
                 (/ (inc %) (+ 2 %))
                 (/ (+ 2 %) (inc %)))
              1
              inc
              n)
     4))

(defn product-iter
  [term a succ b]
  (letfn [(product-iter-step
            [a result]
            (if (> a b)
              result
              (product-iter-step (succ a) (* result (term a)))))]
    (product-iter-step a 1)))

(factorial 5) ; => 120

(double (pi-approx 1000)) ; => 3.143160705532266

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

Wednesday, December 18, 2019

SICP in Clojure: Chapter 1, Exercise 30

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

(ns sicp.ch1.ex30)

(defn sum-iter
  [term a succ b]
  (letfn [(sum-iter-step
            [a result]
            (if (> a b)
              result
              (sum-iter-step (succ a) (+ result (term a)))))]
    (sum-iter-step a 0)))

(sum-iter identity 0 inc 10) ; => 55

Monday, December 09, 2019

SICP in Clojure: Chapter 1, Exercise 29

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

(ns sicp.ch1.ex29
  (:require [sicp.ch1.ex15 :as ch1-ex15]))

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

(defn integral
  [f a b dx]
  (* (sum f (+ a (/ dx 2.0)) (partial + dx) b)
     dx))

(defn integral-simpson
  [f a b n]
  (let [h (/ (- b a) n)]
    (* (sum #(let [m (cond
                       (zero? %) 1
                       (= n %)   1
                       (even? %) 2
                       (odd? %)  4)]
               (* m (f (+ a (* % h)))))
            0
            inc
            n)
       (/ h 3))))

(integral ch1-ex15/cube 0 1 0.01) ; => 0.24998750000000042

(integral ch1-ex15/cube 0 1 0.001) ; => 0.249999875000001

(double (integral-simpson ch1-ex15/cube 0 1 100)) ; => 0.25

(double (integral-simpson ch1-ex15/cube 0 1 1000)) ; => 0.25

Monday, October 28, 2019

SICP in Clojure: Chapter 1, Exercise 28

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

(ns sicp.ch1.ex28)

(defn square-check
  [n m]
  (let [r (rem (* n n) m)]
    (if (and (not (or (= 1 n) (= (- m 1) n)))
             (= 1 r))
      0 r)))

(defn expmod
  [base exp m]
  (cond (zero? exp) 1
        (even? exp) (square-check (expmod base (/ exp 2) m) m)
        :else       (rem (* base (expmod base (dec exp) m))
                         m)))

(defn miller-rabin-test
  [n]
  (letfn [(try-it [a]
            (= (expmod a n n) a))]
    (try-it (inc (rand-int (dec n))))))

(def primes [1009 1013 1019 10007 10009 10037 100003 100019 100043
             1000003 1000033 1000037])

(every? miller-rabin-test primes) ; => true

(def carmichael-numbers [561 1105 1729 2465 2821 6601])

(map miller-rabin-test carmichael-numbers) ; => sometimes false

Tuesday, October 22, 2019

SICP in Clojure: Chapter 1, Exercise 27

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

(ns sicp.ch1.ex27
  (:require [sicp.ch1.ex25 :as sicp-ch1-ex25]))

(defn fermat-test
  [n a]
  (= (sicp-ch1-ex25/expmod a n n) a))

(defn fermat-full-test
  [n]
  (every? (partial fermat-test n) (range n)))

(def carmichael-numbers [561 1105 1729 2465 2821 6601])

(every? fermat-full-test carmichael-numbers) ; => true -- but not
                                        ; prime numbers!

SICP in Clojure: Chapter 1, Exercise 26

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

(ns sicp.ch1.ex26)

;; By replacing the call to square with an explicit multiplication,
;; we've changed the resultant process from a linear recursive

;; process to a tree recursion which changes the running-time from
;; O(log n) to O(log 2^n) = O(n).

Thursday, September 19, 2019

SICP in Clojure: Chapter 1, Exercise 25

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

(ns sicp.ch1.ex25
  (:require [sicp.ch1.ex22 :as sicp-ch1-ex22]
            [sicp.ch1.ex24 :as sicp-ch1-ex24]))

(defn square ; supports arbitrary precision
  [n]
  (*' n n))

(defn fast-expt ; supports arbitrary precision
  [b n]
  (cond (zero? n) 1
        (even? n) (square (fast-expt b (/ n 2)))
        :else     (*' b (fast-expt b (dec n)))))

(defn expmod
  [base exp m]
  (rem (fast-expt base exp) m))

(defn fermat-test
  [n]
  (letfn [(try-it [a]
            (= (expmod a n n) a))]
    (try-it (inc (rand-int (dec n))))))

(defn fast-prime?
  [n times]
  (cond (zero? times)   true
        (fermat-test n) (fast-prime? n (dec times))
        :else           false))

(defn start-prime-test
  [n start-time]
  (let [p (fast-prime? n 10)]
    (when p
      (sicp-ch1-ex22/report-prime n (- (sicp-ch1-ex22/runtime)
                                       start-time)))
    p))

(defn timed-prime-test
  [n]
  (start-prime-test n (sicp-ch1-ex22/runtime)))

(def primes [1009 1013 1019 10007 10009 10037 100003 100019 100043
             1000003 1000033 1000037])

(map sicp-ch1-ex24/timed-prime-test primes)

(map timed-prime-test (take 6 primes))

(def old-times [50052 44905 62564 53861 82539 51227 59000 60004 59868
                66958 66804 61172])

(def new-times [2082324 667264 671594 29729704 25477811 25314029])

(map #(double (/ %1 %2)) old-times new-times) ; 0.0018--0.09x disimprovement

Sunday, September 15, 2019

SICP in Clojure: Chapter 1, Exercise 24

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

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

(defn expmod
  [base exp m]
  (cond (zero? exp) 1
        (even? exp) (rem (sicp-ch1-ex16/square (expmod base
                                                       (/ exp 2)
                                                       m))
                         m)
        :else       (rem (* base (expmod base (dec exp) m))
                         m)))

(defn fermat-test
  [n]
  (letfn [(try-it [a]
            (= (expmod a n n) a))]
    (try-it (inc (rand-int (dec n))))))

(defn fast-prime?
  [n times]
  (cond (zero? times)   true
        (fermat-test n) (fast-prime? n (dec times))
        :else           false))

(defn start-prime-test
  [n start-time]
  (let [p (fast-prime? n 10)]
    (when p
      (sicp-ch1-ex22/report-prime n (- (sicp-ch1-ex22/runtime)
                                       start-time)))
    p))

(defn timed-prime-test
  [n]
  (start-prime-test n (sicp-ch1-ex22/runtime)))

(def primes [1009 1013 1019 10007 10009 10037 100003 100019 100043
             1000003 1000033 1000037])

(map sicp-ch1-ex22/timed-prime-test primes)

(map timed-prime-test primes)

(def old-times [131134 49417 48302 153392 159432 167507 523204 498113
                357480 815095 580023 253359])

(def new-times [461622 142283 171243 156552 274436 89991 78386 77681
                74216 99555 79155 85534])

(map #(double (/ %1 %2)) old-times new-times) ; 0.28--8.19x (dis)improvement

Tuesday, September 10, 2019

SICP in Clojure: Chapter 1, Exercise 23

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

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

(defn next-divisor
  [test-divisor]
  (cond (= 2 test-divisor) 3
        :else              (+ 2 test-divisor)))

(defn find-divisor
  [n test-divisor]
  (cond (> (sicp-ch1-ex16/square
            test-divisor) n)       n
        (zero? (rem n
                    test-divisor)) test-divisor
        :else                      (find-divisor n
                                                 (next-divisor
                                                  test-divisor))))

(defn smallest-divisor
  [n]
  (find-divisor n 2))

(defn prime?
  [n]
  (= n (smallest-divisor n)))

(defn start-prime-test
  [n start-time]
  (let [p (prime? n)]
    (when p
      (sicp-ch1-ex22/report-prime n (- (sicp-ch1-ex22/runtime)
                                       start-time)))
    p))

(defn timed-prime-test
  [n]
  (start-prime-test n (sicp-ch1-ex22/runtime)))

(def primes [1009 1013 1019 10007 10009 10037 100003 100019 100043
             1000003 1000033 1000037])

(map sicp-ch1-ex22/timed-prime-test primes)

(map timed-prime-test primes)

(def old-times [14074 7304 6946 18528 18431 17979 56382 54608 54627
                167110 166381 166168])

(def new-times [9383 5812 5227 13593 14283 13093 38618 38156 38717
                119032 118839 118661])

(map #(double (/ %1 %2)) old-times new-times) ; 1.2--1.5x improvement

Saturday, September 07, 2019

SICP in Clojure: Chapter 1, Exercise 22

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

(ns sicp.ch1.ex22
  (:require [sicp.ch1.ex21 :as sicp-ch1-ex21]))

(defn prime?
  [n]
  (= n (sicp-ch1-ex21/smallest-divisor n)))

(defn report-prime
  [n elapsed-time]
  (println "* " n elapsed-time))

(defn runtime
  []
  (System/nanoTime))

(defn start-prime-test
  [n start-time]
  (let [p (prime? n)]
    (when p
      (report-prime n (- (runtime) start-time)))
    p))

(defn timed-prime-test
  [n]
  (start-prime-test n (runtime)))

(defn search-for-primes
  [start cnt]
  (reduce
   (fn [acc x]
     (if (= cnt (count acc))
       (reduced acc)
       (if (timed-prime-test x)
         (conj acc x)
         acc)))
   []
   (filter #(= 1 (rem % 2))
           (iterate inc start))))

(search-for-primes 1000 3) ; ~5,000ns

(search-for-primes 10000 3) ; ~15,000ns

(search-for-primes 100000 3) ; ~50,000ns

(search-for-primes 1000000 3) ; ~160,000ns

Tuesday, September 03, 2019

SICP in Clojure: Chapter 1, Exercise 21

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

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

(defn find-divisor
  [n test-divisor]
  (cond (> (sicp-ch1-ex16/square test-divisor) n) n
        (zero? (rem n test-divisor)) test-divisor
        :else (find-divisor n (inc test-divisor))))

(defn smallest-divisor
  [n]
  (find-divisor n 2))

(smallest-divisor 199) ; => 199

(smallest-divisor 1999) ; => 1999

(smallest-divisor 19999) ; => 7

Wednesday, August 28, 2019

SICP in Clojure: Chapter 1, Exercise 20

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

(ns sicp.ch1.ex20)

(defn gcd-pseudo-normal
  [a b]
  (if-not (and (ifn? a) (ifn? b))
    (gcd-pseudo-normal #(identity a) #(identity b))
    (if (zero? (b))
      (a)
      (gcd-pseudo-normal b #(do
                              (println "Computing remainder")
                              (rem (a) (b)))))))

(defn gcd
  [a b]
  (if (zero? b)
    a
    (gcd b (do
             (println "Computing remainder")
             (rem a b)))))

(gcd-pseudo-normal (constantly 206)
                   (constantly 40)) ; => 18 remainder computations

(gcd 206 40) ; => 4 remainder computations

Saturday, August 24, 2019

SICP in Clojure: Chapter 1, Exercise 19

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

(ns sicp.ch1.ex19
  (:require [sicp.ch1.ex13 :as sicp-ch1-ex13]))

(defn fast-fib-iter
  ([n]
   (fast-fib-iter 1 0 0 1 n))
  ([a b p q i]
   (cond (zero? i) b
         (even? i) (fast-fib-iter a
                                  b
                                  (+ (* p p) (* q q)) ; compute p'
                                  (+ (* q q) (* 2 p q)) ; compute q'
                                  (/ i 2))
         :else (fast-fib-iter (+ (* b q) (* a q) (* a p))
                              (+ (* b p) (* a q))
                              p
                              q
                              (dec i)))))

(fast-fib-iter 0) ; => 0

(fast-fib-iter 1) ; => 1

(fast-fib-iter 2) ; => 1

(fast-fib-iter 3) ; => 2

(fast-fib-iter 4) ; => 3

(fast-fib-iter 5) ; => 5

(every? #(= (sicp-ch1-ex13/fib %) (fast-fib-iter %))
        (range 10)) ; => true


Thursday, August 22, 2019

SICP in Clojure: Chapter 1, Exercise 18

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

(ns sicp.ch1.ex18
  (:require [sicp.ch1.ex17 :as sicp-ch1-ex17]))

(defn fast-multiply-iter
  ([b n]
   (fast-multiply-iter 0 b n))
  ([a b n]
   (cond (zero? n) a
         (even? n) (fast-multiply-iter a (sicp-ch1-ex17/double-it b)
                                       (sicp-ch1-ex17/halve-it n))
         :else (fast-multiply-iter (+ a b) b (dec n)))))

(fast-multiply-iter 2 8) ; => 16

(fast-multiply-iter 2 9) ; => 18

(every? #(= (sicp-ch1-ex17/fast-multiply 2 %)
            (fast-multiply-iter 2 %))
        (range 10)) ; => true

Tuesday, August 20, 2019

SICP in Clojure: Chapter 1, Exercise 17

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

(ns sicp.ch1.ex17)

(defn multiply
  [a b]
  (if (zero? b)
    0
    (+ a (multiply a (dec b)))))

(multiply 5 8) ; => 40

(defn double-it
  [n]
  (* 2 n))

(defn halve-it
  [n]
  (/ n 2))

(defn fast-multiply
  [a b]
  (cond (zero? b) 0
        (= b 1) a
        (even? b) (double-it (fast-multiply a (halve-it b)))
        :else (+ a (fast-multiply a (dec b)))))

(fast-multiply 5 8) ; => 40

(every? #(= (apply multiply %) (apply fast-multiply %))
        (for [i (range 10) j (range 10)] [i j])) ; => true

Saturday, August 10, 2019

SICP in Clojure: Chapter 1, Exercise 16

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

(ns sicp.ch1.ex16)

(defn square
  [n]
  (* n n))

(defn fast-expt
  [b n]
  (cond (zero? n) 1
        (even? n) (square (fast-expt b (/ n 2)))
        :else (* b (fast-expt b (dec n)))))

(defn fast-expt-iter
  ([b n]
   (fast-expt-iter 1 b n))
  ([a b n]
   (cond (zero? n) a
         (even? n) (fast-expt-iter a (square b) (/ n 2))
         :else (fast-expt-iter (* a b) b (dec n)))))

(fast-expt 2 8) ; => 256

(fast-expt 2 9) ; => 512

(every? #(= (fast-expt 2 %) (fast-expt-iter 2 %))
        (range 10)) ; => true


SICP in Clojure: Chapter 1, Exercise 15

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

(ns sicp.ch1.ex15)

(defn cube
  [x]
  (* x x x))

(defn p
  [x]
  (- (* 3 x) (* 4 (cube x))))

(defn sine
  [angle]
  (if (not (> (Math/abs angle) 0.1))
    angle
    (p (sine (/ angle 3.0)))))

(sine 12.15) ; => -0.39 -- p is applied 5 times

;; if a is the angle then the space complexity (or the maximum height
;; of the tree) is O(log a) else the time complexity (or the number of
;; nodes in the tree) is also O(log a)

Monday, July 15, 2019

SICP in Clojure: Chapter 1, Exercise 14

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

(ns sicp.ch1.ex14
  (:require [clojure.java.io :as io]
            [clojure.shell :as shell]
            [clojure.string :as s]))

(defn first-denomination
  [kinds-of-coins]
  (condp = kinds-of-coins
    1 1
    2 5
    3 10
    4 25
    5 50))

(def ^{:dynamic true :private true} *writer* nil)

(defn- cc
  [amount kinds-of-coins prev-call calls]
  (let [this-call (inc (count @calls))
        step [prev-call this-call]]
    (when (some? *writer*)
      (.write *writer* (str (s/join " -> " step) \newline)))
    (swap! calls conj step)
    (cond (zero? amount) 1
          (or (neg? amount) (zero? kinds-of-coins)) 0
          :else (+ (cc amount
                       (dec kinds-of-coins)
                       this-call
                       calls)
                   (cc (- amount
                          (first-denomination kinds-of-coins))
                       kinds-of-coins
                       this-call
                       calls)))))

(defn count-change
  [amount & {:keys [dot-file] :or [dot-file false]}]
  (let [calls (atom [])]
    (if dot-file
      (with-open [writer (io/writer "/tmp/cc.dot")]
        (binding [*writer* writer]
          (.write *writer* "digraph {\n")
          (let [answer (cc amount 5 0 calls)]
            (.write *writer* "}\n")
            answer)))
      (cc amount 5 0 calls))))

(count-change 100) ; => 292

(count-change 11 :dot-file true) ; => 4

;; draw the call graph

(shell/sh "/usr/local/bin/dot" "-Kdot" "-Tsvg" "/tmp/cc.dot" "-O")

(shell/sh "/usr/bin/open" "/tmp/cc.dot.svg")

;; if n is the amount to be changed and k is the number of
;; denominations then: the space complexity (or the maximum height of
;; the tree) is O(n + k) the time complexity (or the number of nodes
;; in the tree) is O(n^k)

Tuesday, July 09, 2019

SICP in Clojure: Chapter 1, Exercise 13

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

(ns sicp.ch1.ex13)

(defn fib
  [n]
  (if (< n 2)
    n
    (+ (fib (- n 1)) (fib (- n 2)))))

(def phi (/ (+ 1 (Math/sqrt 5)) 2))

(def psi (/ (- 1 (Math/sqrt 5)) 2))

(defn fib-exact
  [n]
  (Math/round (/ (- (Math/pow phi n) (Math/pow psi n))
                 (Math/sqrt 5))))

(every? #(= (fib %) (fib-exact %)) (range 10)) ; => true

;; assume f(n) = (phi^n - psi^n)/5^-2
;; assume f(n + 1) = (phi^(n + 1) - psi^(n + 1)/5^-2
;; prove that f(n + 2) = (phi^(n + 2) - psi^(n + 2)/5^-2 where
;; f(n + 2) = f(n + 1) + f(n)

Friday, June 21, 2019

SICP in Clojure: Chapter 1, Exercise 12

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

(ns sicp.ch1.ex12)

(defn pascal
  [i j]
  (if (or (zero? j) (= i j))
    1
    (+ (pascal (dec i) (dec j)) (pascal (dec i) j))))

(for [i (range 10)]
  (for [j (range (inc i))]
    (pascal i j))) ; Pascal's triangle

SICP in Clojure: Chapter 1, Exercise 11

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

(ns sicp.ch1.ex11)

(defn f
  [n]
  (if (< n 3)
    n
    (+ (f (dec n))
       (* 2 (f (- n 2)))
       (* 3 (f (- n 3))))))

(defn f-iter
  ([n]
   (f-iter 2 1 0 n))
  ([a b c n]
   (if (zero? n)
     c
     (f-iter (+ a (* 2 b) (* 3 c)) a b (dec n)))))

(every? #(= (f %) (f-iter %)) (range 10)) ; => true

Thursday, May 23, 2019

SICP in Clojure: Chapter 1, Exercise 10

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

(ns sicp.ch1.ex10)

(defn A
  [x y]
  (cond (zero? y) 0
        (zero? x) (* 2 y)
        (= y 1) 2
        :else (A (dec x)
                 (A x (dec y)))))

(A 1 10) ; => 1024

(A 2 4) ; => 65536

(A 3 3) ; => 65536

(defn f
  [n]
  (A 0 n))

(defn g
  [n]
  (A 1 n))

(defn h
  [n]
  (A 2 n))

(every? #(= (* 2 %)
            (f %))
        (range 1 5)) ; => true -- f is multiplication

(every? #(= (Math/pow 2 %)
            (double (g %)))
        (range 1 5)) ; => true -- g is exponentiation

(every? (fn [i]
          (= (nth (iterate #(Math/pow 2 %) 1) i)
             (double (h i))))
        (range 1 5)) ; => true -- h is iterated exponentiation or tetration

Tuesday, April 23, 2019

SICP in Clojure: Chapter 1, Exercise 9

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

(ns sicp.ch1.ex09)

(defn add-1
  [a b]
  (if (zero? a)
    b
    (inc (add-1 (dec a) b))))

(defn add-2
  [a b]
  (if (zero? a)
    b
    (add-2 (dec a) (inc b))))

(add-1 5 10) ; => 15 -- a recursive process


(add-2 5 10) ; => 15 -- an iterative process

Saturday, April 20, 2019

SICP in Clojure: Chapter 1, Exercise 8

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

(ns sicp.ch1.ex08)

(defn good-enough-cube-root?
  [guess x]
  (< (Math/abs (- (Math/pow guess 3) x)) 0.001))

(defn improve-cube-root
  [guess x]
  (/ (+ (/ x (Math/pow guess 2)) (* 2 guess))
     3))

(defn cube-root-iter
  [guess x]
  (if (good-enough-cube-root? guess x)
    guess
    (cube-root-iter (improve-cube-root guess x)
                    x)))

Friday, March 22, 2019

SICP in Clojure: Chapter 1, Exercise 7

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

(ns sicp.ch1.ex07
  (:require [sicp.ch1.ex06 :as sicp-ch1-ex06]))

(double (sicp-ch1-ex06/sqrt-iter 1 0.0001)) ; => 0.032... -- should
                                        ; be 0.01

(double (sicp-ch1-ex06/sqrt-iter 1 0.00001)) ; => 0.031... -- should
                                        ; be 0.0031...

(double (sicp-ch1-ex06/sqrt-iter 1 1000000)) ; => 1000 -- good

(defn good-enough?
  [guess prev-guess]
  (< (/ (Math/abs (double (- guess prev-guess))) guess) 0.001))

(defn sqrt-iter
  ([guess x]
   (sqrt-iter guess (inc guess) x))
  ([guess prev-guess x]
   (if (good-enough? guess prev-guess)
     guess
     (sqrt-iter (sicp-ch1-ex06/improve guess x)
                guess
                x))))

(double (sqrt-iter 1 0.0001)) ; => 0.01... -- good

(double (sqrt-iter 1 0.00001)) ; => 0.0031... -- better

(double (sqrt-iter 1 1000000)) ; => 1000 -- still good

Wednesday, March 20, 2019

SICP in Clojure: Chapter 1, Exercise 6

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

(ns sicp.ch1.ex06)

(defn good-enough?
  [guess x]
  (< (Math/abs (- (Math/pow guess 2) x)) 0.001))

(defn average
  [x y]
  (/ (+ x y) 2))

(defn improve
  [guess x]
  (average guess (/ x guess)))

(defn sqrt-iter
  [guess x]
  (if (good-enough? guess x)
    guess
    (sqrt-iter (improve guess x)
               x)))

(double (sqrt-iter 1 2)) ; => 1.41421568627451

(defn new-if
  [predicate then-clause else-clause]
  (cond predicate then-clause
        :else else-clause))

(new-if (= 2 3) 0 5) ; => 5

(new-if (= 1 1) 0 5) ; => 0

(defn new-sqrt-iter
  [guess x]
  (new-if (good-enough? guess x)
          guess
          (new-sqrt-iter (improve guess x)
                         x)))

(new-sqrt-iter 1 2) ; => infinite loop

Thursday, March 07, 2019

SICP in Clojure: Chapter 1, Exercise 5

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

(ns sicp.ch1.ex05)

(defn p
  []
  (p))

(defn test-order
  [x y]
  (if (zero? x)
    0
    y))

(test-order 6 (p)) ; => applicative order

Sunday, March 03, 2019

SICP in Clojure: Chapter 1, Exercise 4

Expressions are either primitive or compound. Procedures are either primitive or compound. A combination is an expression of the form (operator operands ...). This is my Clojure solution to Chapter 1, Exercise 4:

(ns sicp.ch1.ex04)

(defn a-plus-abs-b
  [a b]
  ((if (pos? b) + -) a b))

(a-plus-abs-b 5 -10) ; => 15

(a-plus-abs-b 5 10) ; => 15

Wednesday, February 27, 2019

SICP in Clojure: Chapter 1, Exercise 3

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

(ns sicp.ch1.ex03)

(defn f
  [x y z]
  (reduce #(+ %1 (* %2 %2))
          (drop 1 (sort [x y z]))))