From 9b8a2340754ac1115099fd5c3d84076fd3b7a7c5 Mon Sep 17 00:00:00 2001 From: Ramakrishnan Muthukrishnan Date: Wed, 1 Sep 2010 12:39:01 +0530 Subject: [PATCH] Exercise solutions for section 2.2.4. Instead of looking at this commit, please look at the namespace pictlang instead. --- src/sicp/ex2_44.clj | 8 +++++ src/sicp/ex2_45.clj | 13 +++++++ src/sicp/ex2_46.clj | 32 +++++++++++++++++ src/sicp/ex2_47.clj | 21 ++++++++++++ src/sicp/ex2_48.clj | 14 ++++++++ src/sicp/ex2_49.clj | 84 +++++++++++++++++++++++++++++++++++++++++++++ src/sicp/ex2_50.clj | 15 ++++++++ src/sicp/ex2_51.clj | 19 ++++++++++ 8 files changed, 206 insertions(+) create mode 100644 src/sicp/ex2_44.clj create mode 100644 src/sicp/ex2_45.clj create mode 100644 src/sicp/ex2_46.clj create mode 100644 src/sicp/ex2_47.clj create mode 100644 src/sicp/ex2_48.clj create mode 100644 src/sicp/ex2_49.clj create mode 100644 src/sicp/ex2_50.clj create mode 100644 src/sicp/ex2_51.clj diff --git a/src/sicp/ex2_44.clj b/src/sicp/ex2_44.clj new file mode 100644 index 0000000..1864317 --- /dev/null +++ b/src/sicp/ex2_44.clj @@ -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 index 0000000..a7b7186 --- /dev/null +++ b/src/sicp/ex2_45.clj @@ -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 index 0000000..fe47f31 --- /dev/null +++ b/src/sicp/ex2_46.clj @@ -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 index 0000000..e15bdc1 --- /dev/null +++ b/src/sicp/ex2_47.clj @@ -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 index 0000000..1d799e7 --- /dev/null +++ b/src/sicp/ex2_48.clj @@ -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 index 0000000..f1c55bd --- /dev/null +++ b/src/sicp/ex2_49.clj @@ -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 index 0000000..7126002 --- /dev/null +++ b/src/sicp/ex2_50.clj @@ -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 index 0000000..cdbb1b1 --- /dev/null +++ b/src/sicp/ex2_51.clj @@ -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 -- 2.45.2