From 10fbbdd2ba68e5eca76752cce4b70b40555400ca Mon Sep 17 00:00:00 2001
From: Ramakrishnan Muthukrishnan <vu3rdd@gmail.com>
Date: Sun, 13 Jun 2010 01:41:59 +0530
Subject: [PATCH] solutions to 2.7 to 2.11.

---
 src/sicp/ch2_1_extended.clj | 25 +++++++++++++++++++
 src/sicp/ex2_10.clj         | 13 ++++++++++
 src/sicp/ex2_11.clj         | 48 +++++++++++++++++++++++++++++++++++++
 src/sicp/ex2_7.clj          | 12 ++++++++++
 src/sicp/ex2_8.clj          | 15 ++++++++++++
 src/sicp/ex2_9.clj          | 24 +++++++++++++++++++
 6 files changed, 137 insertions(+)
 create mode 100644 src/sicp/ch2_1_extended.clj
 create mode 100644 src/sicp/ex2_10.clj
 create mode 100644 src/sicp/ex2_11.clj
 create mode 100644 src/sicp/ex2_7.clj
 create mode 100644 src/sicp/ex2_8.clj
 create mode 100644 src/sicp/ex2_9.clj

diff --git a/src/sicp/ch2_1_extended.clj b/src/sicp/ch2_1_extended.clj
new file mode 100644
index 0000000..07e6790
--- /dev/null
+++ b/src/sicp/ch2_1_extended.clj
@@ -0,0 +1,25 @@
+(ns sicp.ch2_1_extended
+  (:use [sicp utils ex2_7]
+	[clojure.test]))
+
+;; 2.1.4 - interval arithmetic
+;;(declare make-interval lower-bound upper-bound)
+
+(defn add-interval [x y]
+  (make-interval (+ (lower-bound x) (lower-bound y))
+                 (+ (upper-bound x) (upper-bound y))))
+
+(defn mul-interval [x y]
+  (let [p1 (* (lower-bound x) (lower-bound y))
+	p2 (* (lower-bound x) (upper-bound y))
+	p3 (* (upper-bound x) (lower-bound y))
+	p4 (* (upper-bound x) (upper-bound y))]
+    (make-interval (min p1 p2 p3 p4)
+		   (max p1 p2 p3 p4))))
+
+(defn div-interval [x y]
+  (mul-interval x 
+                (make-interval (/ 1.0 (upper-bound y))
+                               (/ 1.0 (lower-bound y)))))
+
+
diff --git a/src/sicp/ex2_10.clj b/src/sicp/ex2_10.clj
new file mode 100644
index 0000000..e1da387
--- /dev/null
+++ b/src/sicp/ex2_10.clj
@@ -0,0 +1,13 @@
+(ns sicp.ex2_10
+  (:use [sicp utils ch2_1_extended ex2_7]
+	[clojure.test]))
+
+(defn new-div-interval [x y]
+  (let [l (lower-bound y)
+	u (upper-bound y)]
+    (if (or (and (pos? l)
+		 (neg? u))
+	    (and (pos? u)
+		 (neg? l)))
+      (error "Division by a range spanning 0")
+      (div-interval x y))))
\ No newline at end of file
diff --git a/src/sicp/ex2_11.clj b/src/sicp/ex2_11.clj
new file mode 100644
index 0000000..03fbfd0
--- /dev/null
+++ b/src/sicp/ex2_11.clj
@@ -0,0 +1,48 @@
+(ns sicp.ex2_11
+  (:use [sicp utils ch2_1_extended ex2_7]
+	[clojure.test]))
+
+;; let [l1, u2] be lower and upper bound of range x
+;; and [l2, u2] that of range y.
+
+;; based on the signs of l1, u1, l2, u2, we have 16 combinations
+
+;; l1 :u1 :l2 :u2
+;; +   +   +   +
+;; +   +   +   -
+;; +   +   -   +
+;; +   +   -   -
+;; +   -   +   +
+;; +   -   +   -
+;; +   -   -   +
+;; +   -   -   -
+;; -   +   +   +
+;; -   +   +   -
+;; -   +   -   +
+;; -   +   -   -
+;; -   -   +   +
+;; -   -   +   -
+;; -   -   -   +
+;; -   -   -   -
+
+;; Now, if lower bound is +ve and upper is -ve, then it is invalid. So,
+;; l1 :u1 :l2 :u2
+;; +   +   +   +
+;; +   +   +   -  => invalid
+;; +   +   -   +
+;; +   +   -   -
+;; +   -   +   +  => invalid
+;; +   -   +   -  => invalid
+;; +   -   -   +  => invalid
+;; +   -   -   -  => invalid
+;; -   +   +   +
+;; -   +   +   -  => invalid
+;; -   +   -   +
+;; -   +   -   -
+;; -   -   +   +
+;; -   -   +   -  => invalid
+;; -   -   -   +
+;; -   -   -   -
+
+
+;; too boring a problem. Skipping the rest of it.
diff --git a/src/sicp/ex2_7.clj b/src/sicp/ex2_7.clj
new file mode 100644
index 0000000..643920c
--- /dev/null
+++ b/src/sicp/ex2_7.clj
@@ -0,0 +1,12 @@
+(ns sicp.ex2_7
+  (:use [sicp utils ch2_1_extended]
+	[clojure.test]))
+
+(defn make-interval [x y]
+  (list x y))
+
+(defn upper-bound [i]
+  (first i))
+
+(defn lower-bound [i]
+  (first (rest i)))
diff --git a/src/sicp/ex2_8.clj b/src/sicp/ex2_8.clj
new file mode 100644
index 0000000..6e70f73
--- /dev/null
+++ b/src/sicp/ex2_8.clj
@@ -0,0 +1,15 @@
+(ns sicp.ex2_8
+  (:use [sicp utils ch2_1_extended ex2_7]
+	[clojure.test]))
+
+;; sub-interval
+(defn sub-interval [x y]
+  (make-interval (- (lower-bound x) (upper-bound y))
+		 (- (upper-bound x) (lower-bound y))))
+
+;; subtraction of an interval can be seen as addition of a
+;; negative range. Intuitively, if you plot a range in a 2-D graph,
+;; negative of a range, say [a1, a2] for say a1 and a2 positive
+;; is [-a2, -a1]. i.e. the reflection of the range w.r.t the x=0
+;; axis. In this new light, we are adding two ranges [-a2,-a2] and [b1,b2]
+;; and hence the above answer.
\ No newline at end of file
diff --git a/src/sicp/ex2_9.clj b/src/sicp/ex2_9.clj
new file mode 100644
index 0000000..8a80249
--- /dev/null
+++ b/src/sicp/ex2_9.clj
@@ -0,0 +1,24 @@
+(ns sicp.ex2_9
+  (:use [sicp utils ch2_1_extended ex2_7]
+	[clojure.test]))
+
+;; let us say, width of an interval [x,y] = d = (y-x)/2.
+;; add_interval [x,y] = [l1+l2, u1+u2]
+;; width of sum = (u1+u2 - (l1+l2))/2
+;;              = (u1-l1 + u2 - l2)/2
+;;              = d1  + d2
+;;
+;; sub_interval [x,y] = [l1-u2, u1-l2]
+;; width of diff = (u1-l2 - (l1-u2))/2
+;;               = (u1 - l2 - l1 + u2) / 2
+;;               = ((u1 - l1) + (u2 - l2))/2
+;;               = d1 + d2
+
+;; Now, intuitively multiplication (and division), scales a range
+;; up or down. Since mul-range was essentially non-linear (is that the
+;; right term? ) because of the min/max calculations, these depend on
+;; absolute values of the range rather than the width.
+;; eg: [2 3] [3 4]. Width (d1, d2) => (1,1)
+;; mul-interval => [6 12]
+
+;; same with division as well.
-- 
2.45.2