]> git.rkrishnan.org Git - sicp.git/commitdiff
Exercise solutions for section 2.2.4. Instead of looking at this
authorRamakrishnan Muthukrishnan <vu3rdd@gmail.com>
Wed, 1 Sep 2010 07:09:01 +0000 (12:39 +0530)
committerRamakrishnan Muthukrishnan <vu3rdd@gmail.com>
Wed, 1 Sep 2010 07:09:01 +0000 (12:39 +0530)
commit, please look at the namespace pictlang instead.

src/sicp/ex2_44.clj [new file with mode: 0644]
src/sicp/ex2_45.clj [new file with mode: 0644]
src/sicp/ex2_46.clj [new file with mode: 0644]
src/sicp/ex2_47.clj [new file with mode: 0644]
src/sicp/ex2_48.clj [new file with mode: 0644]
src/sicp/ex2_49.clj [new file with mode: 0644]
src/sicp/ex2_50.clj [new file with mode: 0644]
src/sicp/ex2_51.clj [new file with mode: 0644]

diff --git a/src/sicp/ex2_44.clj b/src/sicp/ex2_44.clj
new file mode 100644 (file)
index 0000000..1864317
--- /dev/null
@@ -0,0 +1,8 @@
+(ns sicp.ex2_44
+  (:use [sicp.ch2-2 :only (beside below)]))
+
+(defn up-split [painter n]
+  (if (= n 0)
+    painter
+    (let [smaller (up-split painter (- n 1))]
+      (below painter (beside smaller smaller)))))
diff --git a/src/sicp/ex2_45.clj b/src/sicp/ex2_45.clj
new file mode 100644 (file)
index 0000000..a7b7186
--- /dev/null
@@ -0,0 +1,13 @@
+(ns sicp.ex2_45)
+
+(defn split [f1 f2]
+  (fn (painter n)
+    (if (= n 0)
+      painter
+      (let [smaller ((split f1 f2) painter (- n 1))]
+        (f1 painter (f2 smaller smaller))))))
+
+(def right-split (split beside below))
+(def up-split    (split below beside))
+
+    
\ No newline at end of file
diff --git a/src/sicp/ex2_46.clj b/src/sicp/ex2_46.clj
new file mode 100644 (file)
index 0000000..fe47f31
--- /dev/null
@@ -0,0 +1,32 @@
+(ns sicp.ex2_46
+  (:use [clojure.test]))
+
+(defn make-vect [x y]
+  (list x y))
+
+(defn xcor-vect [v]
+  (first v))
+
+(defn ycor-vect [v]
+  (second v))
+
+(defn add-vect [v1 v2]
+  (make-vect (+ (xcor-vect v1)
+                (xcor-vect v2))
+             (+ (ycor-vect v1)
+                (ycor-vect v2))))
+
+(defn sub-vect [v1 v2]
+  (make-vect (- (xcor-vect v1)
+                (xcor-vect v2))
+             (- (ycor-vect v1)
+                (ycor-vect v2))))
+
+(defn scale-vect [v s]
+  (make-vect (* s (xcor-vect v))
+             (* s (ycor-vect v))))
+
+(deftest test-add-vectors
+  (let [v1 (make-vect 1 1)
+        v2 (make-vect 2 2)]
+    (is (= (add-vect v1 v2) (make-vect 3 3)))))
diff --git a/src/sicp/ex2_47.clj b/src/sicp/ex2_47.clj
new file mode 100644 (file)
index 0000000..e15bdc1
--- /dev/null
@@ -0,0 +1,21 @@
+(ns sicp.ex2_47
+  (:use [clojure.test]))
+
+;; first approach
+(defn make-frame [origin edge1 edge2]
+  (list origin edge1 edge2))
+
+;; second approach
+(defn make-frame [origin]
+  (cons origin (cons edge1 (list edge2))))
+
+;; for both of them the following selectors will work
+(defn origin-frame [frame]
+  (first frame))
+
+(defn edge1-frame [frame]
+  (second frame))
+
+(defn edge2-frame [frame]
+  (first (rest (rest frame))))
+
diff --git a/src/sicp/ex2_48.clj b/src/sicp/ex2_48.clj
new file mode 100644 (file)
index 0000000..1d799e7
--- /dev/null
@@ -0,0 +1,14 @@
+(ns sicp.ex2_48
+  (:use [clojure.test]
+        [sicp.ex2_46]
+        [sicp.ch2_2 :only (segments->painter)]))
+
+;; we define a segment as a list of 2 vectors
+(defn make-segment [v1 v2]
+  (list v1 v2))
+
+(defn start-segment [segment]
+  (first segment))
+
+(defn end-segment [segment]
+  (second segment))
\ No newline at end of file
diff --git a/src/sicp/ex2_49.clj b/src/sicp/ex2_49.clj
new file mode 100644 (file)
index 0000000..f1c55bd
--- /dev/null
@@ -0,0 +1,84 @@
+(ns sicp.ex2_49
+  (:use [sicp [ch2_2 :only (segments->painter)]]
+        [clojure.test]))
+
+;;; Use segments->painter to define the following primitive painters:
+
+;;   a.  The painter that draws the outline of the designated frame.
+
+(def o  (make-vect 0 0))
+(def lr (make-vect 0 1))
+(def ul (make-vect 1 0))
+(def ur (make-vect 1 1))
+
+(defn frame-outline [frame]
+  (let [s1 (make-segment o lr)
+        s2 (make-segment lr ur)
+        s3 (make-segment ur ul)
+        s4 (make-segment ul o)]
+    ((segments->painter (list s1 s2 s3 s4)) frame)))
+
+;; b The painter that draws an ``X'' by connecting opposite corners
+;;   of the frame.
+(defn cross-segments [frame]
+  (let [s1 (make-segment ul lr)
+        s2 (make-segment o ur)]
+    ((segments->painter (list s1 s2)) frame)))
+
+;; c.  The painter that draws a diamond shape by connecting the midpoints
+;;     of the sides of the frame.
+(defn connect [vs]
+  (let [new-list   (append vs (list (car vs)))
+        vect-pairs (partition 2 1 new-list)
+        segments   (map #(apply make-segment %) vect-pairs)]
+    segments))
+
+(defn diamond-segments [frame]
+  (let [m1 (make-vect 0 0.5)
+        m2 (make-vect 0.5 1)
+        m3 (make-vect 1 0.5)
+        m4 (make-vect 0.5 0)]
+    ((segments->painter (connect (list m1 m2 m3 m4))) frame)))
+
+;; d. wave painter
+(defn wave [frame]
+  (let [p01 (make-vect 0.40 1.00)
+        p02 (make-vect 0.60 1.00)
+        p03 (make-vect 0.00 0.80)
+        p04 (make-vect 0.35 0.80)
+        p05 (make-vect 0.65 0.80)
+        p06 (make-vect 0.00 0.60)
+        p07 (make-vect 0.30 0.60)
+        p08 (make-vect 0.40 0.60)
+        p09 (make-vect 0.60 0.60)
+        p10 (make-vect 0.70 0.60)
+        p11 (make-vect 0.20 0.55)
+        p12 (make-vect 0.30 0.55)
+        p13 (make-vect 0.35 0.50)
+        p14 (make-vect 0.65 0.50)
+        p15 (make-vect 0.20 0.45)
+        p16 (make-vect 1.00 0.40)
+        p17 (make-vect 0.50 0.20)
+        p18 (make-vect 1.00 0.20)
+        p19 (make-vect 0.25 0.00)
+        p20 (make-vect 0.40 0.00)
+        p21 (make-vect 0.60 0.00)
+        p22 (make-vect 0.75 0.00)]
+    ((segments->painter
+      (list (make-segment p01 p04)
+            (make-segment p04 p08)
+            (make-segment p08 p07)
+            (make-segment p07 p11)
+            (make-segment p11 p03)
+            (make-segment p06 p15)
+            (make-segment p15 p12)
+            (make-segment p12 p13)
+            (make-segment p13 p19)
+            (make-segment p20 p17)
+            (make-segment p17 p21)
+            (make-segment p22 p14)
+            (make-segment p14 p18)
+            (make-segment p16 p10)
+            (make-segment p10 p09)
+            (make-segment p09 p05)
+            (make-segment p05 p02))) frame)))
diff --git a/src/sicp/ex2_50.clj b/src/sicp/ex2_50.clj
new file mode 100644 (file)
index 0000000..7126002
--- /dev/null
@@ -0,0 +1,15 @@
+(ns sicp.ex2_50
+  (:use [clojure.test]
+        [sicp.ch2_2 :only (rotate90)]))
+
+(defn flip-horiz [painter]
+  (transform-painter painter
+                     (make-vect 1 0)
+                     (make-vect 0 0)
+                     (make-vect 1 1)))
+
+(defn rotate180 [painter]
+  ((repeatedly 2 rotate90) painter))
+
+(defn rotate270 [painter]
+  ((repeatedly 3 rotate90) painter))
\ No newline at end of file
diff --git a/src/sicp/ex2_51.clj b/src/sicp/ex2_51.clj
new file mode 100644 (file)
index 0000000..cdbb1b1
--- /dev/null
@@ -0,0 +1,19 @@
+(ns sicp.ex2_51
+  (:use [clojure.test]
+        [sicp.ch2_2 :only (transform-painter)]))
+
+(defn below1 [painter1 painter2]
+  (let [paint-low (transform-painter painter1
+                                     (make-vect 0 0)
+                                     (make-vect 1 0)
+                                     (make-vect 0 0.5))
+        paint-high (transform-painter painter2
+                                      (make-vect 0 0.5)
+                                      (make-vect 1 0)
+                                      (make-vect 0 1))]
+    (fn [frame]
+      (paint-low frame)
+      (paint-high frame))))
+
+(defn below2 [painter1 painter2]
+  (rotate90 (beside (rotate270 painter1) (rotate270 painter2))))
\ No newline at end of file