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