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