From: Ramakrishnan Muthukrishnan Date: Sat, 4 Sep 2010 03:37:15 +0000 (+0530) Subject: solution to 2.57 X-Git-Url: https://git.rkrishnan.org/pf/content/en/seg/statistics?a=commitdiff_plain;h=5130f871c9e6cfe0cab1923f78d26e34f3230025;p=sicp.git solution to 2.57 --- diff --git a/src/sicp/ex2_57.clj b/src/sicp/ex2_57.clj new file mode 100644 index 0000000..16c10ad --- /dev/null +++ b/src/sicp/ex2_57.clj @@ -0,0 +1,77 @@ +(ns sicp.ex2_57 + (:use [clojure.test] + [sicp.utils])) + +(defn exponentiation? [exp] + (= (first exp) '**)) + +(defn base [exp] + (second exp)) + +(defn exponent [exp] + (second (rest exp))) + +(defn variable? [x] + (symbol? x)) + +(defn same-variable? [v1 v2] + (and (variable? v1) + (variable? v2) + (= v1 v2))) + +(defn =number? [exp num] + (and (number? exp) (= exp num))) + +(defn make-sum [a1 a2] + (cond (=number? a1 0) a2 + (=number? a2 0) a1 + (and (number? a1) (number? a2)) (+ a1 a2) + :else (list '+ a1 a2))) + +(defn make-product [m1 m2] + (cond (or (=number? m1 0) (=number? m2 0)) 0 + (=number? m1 1) m2 + (=number? m2 1) m1 + (and (number? m1) (number? m2)) (* m1 m2) + :else (list '* m1 m2))) + +(defn sum? [x] + (and (list? x) (= (first x) '+))) + +(defn addend [s] + (second s)) + +(defn augend [s] + (reduce make-sum 0 (rest (rest s)))) + +(defn product? [x] + (and (list? x) (= (first x) '*))) + +(defn multiplier [p] + (second p)) + +(defn multiplicand [p] + (reduce make-product 1 (rest (rest p)))) + +(defn make-exponentiation [b n] + (cond (=number? b 1) 1 + (=number? b 0) 0 + (=number? n 1) b + (=number? n 0) 1 + (and (number? b) (number? n)) (Math/pow b n) + :else (list '** b n))) + +(defn deriv [exp var] + (cond (number? exp) 0 + (variable? exp) (if (same-variable? exp var) 1 0) + (sum? exp) (make-sum (deriv (addend exp) var) + (deriv (augend exp) var)) + (product? exp) (make-sum (make-product (multiplier exp) + (deriv (multiplicand exp) var)) + (make-product (deriv (multiplier exp) var) + (multiplicand exp))) + (exponentiation? exp) (make-product (exponent exp) + (make-product (make-exponentiation (base exp) + (- (exponent exp) 1)) + (deriv (base exp) var))) + :else (str "unknown expression type -- derive " exp)))