solutions to 3.12 to 3.19
authorRamakrishnan Muthukrishnan <vu3rdd@gmail.com>
Wed, 9 Feb 2011 14:27:34 +0000 (19:57 +0530)
committerRamakrishnan Muthukrishnan <vu3rdd@gmail.com>
Wed, 9 Feb 2011 14:27:34 +0000 (19:57 +0530)
src/sicp/ex3_12.rkt [new file with mode: 0644]
src/sicp/ex3_13.rkt [new file with mode: 0644]
src/sicp/ex3_14.rkt [new file with mode: 0644]
src/sicp/ex3_16.rkt [new file with mode: 0644]
src/sicp/ex3_17.rkt [new file with mode: 0644]
src/sicp/ex3_18.rkt [new file with mode: 0644]
src/sicp/ex3_19.rkt [new file with mode: 0644]

diff --git a/src/sicp/ex3_12.rkt b/src/sicp/ex3_12.rkt
new file mode 100644 (file)
index 0000000..2c043df
--- /dev/null
@@ -0,0 +1,24 @@
+#lang r5rs
+
+(define (append! x y)
+  (set-cdr! (last-pair x) y)
+  x)
+
+(define (last-pair x)
+  (if (null? (cdr x))
+      x
+      (last-pair (cdr x))))
+
+#|
+
+x => a -> b -> ()
+y => c -> d -> ()
+
+(cdr x) => (b->()) => (b)
+
+w => (a->b->c->d->()) and
+x => (a->b->c->d->())
+
+(cdr x) => b->c->d->() (b c d)
+   
+|#
\ No newline at end of file
diff --git a/src/sicp/ex3_13.rkt b/src/sicp/ex3_13.rkt
new file mode 100644 (file)
index 0000000..3a9e3ae
--- /dev/null
@@ -0,0 +1,7 @@
+#lang racket
+
+#|
+
+Last pair of z will loop for ever, as it will never find the end of the list.
+
+|#
\ No newline at end of file
diff --git a/src/sicp/ex3_14.rkt b/src/sicp/ex3_14.rkt
new file mode 100644 (file)
index 0000000..5c6c1a1
--- /dev/null
@@ -0,0 +1,17 @@
+#lang r5rs
+
+#|
+
+mystery is trying to find the reverse of the list x. Too lazy to draw the ascii art. 
+Too lazy to scan my notebook.
+
+|#
+
+(define (mystery x)
+  (define (loop x y)
+    (if (null? x)
+        y
+        (let ((temp (cdr x)))
+          (set-cdr! x y)
+          (loop temp x))))
+  (loop x '()))
\ No newline at end of file
diff --git a/src/sicp/ex3_16.rkt b/src/sicp/ex3_16.rkt
new file mode 100644 (file)
index 0000000..142612c
--- /dev/null
@@ -0,0 +1,34 @@
+#lang r5rs
+
+(define (count-pairs x)
+  (if (not (pair? x))
+      0
+      (+ (count-pairs (car x))
+         (count-pairs (cdr x))
+         1)))
+
+;; list of exactly 3 pairs which counts as 3
+(define z1 (cons 'a (cons 'b (cons 'c '()))))
+(count-pairs z1)
+
+;; list of 3 pairs but counts as 4
+(define x (list 'a 'b))
+(define z2 (cons (cons 'c '()) x))
+(count-pairs z2)
+
+;; list of 3 pairs but counts as 7
+(define x3 (cons 'a 'b))
+(define y3 (cons x3 x3))
+(define z3 (cons y3 y3))
+(count-pairs z3)
+
+;; list of 3 pairs but count never returns
+;;; DON'T RUN THIS. IT WILL GO INTO An INF LOOP
+(define z4 (cons 'a (cons 'y (cons 'z '()))))
+(define (last-pair x)
+  (if (null? (cdr x))
+      x
+      (last-pair (cdr x))))
+
+(set-cdr! (last-pair z4) z4)
+(count-pairs z4)
diff --git a/src/sicp/ex3_17.rkt b/src/sicp/ex3_17.rkt
new file mode 100644 (file)
index 0000000..94d3b45
--- /dev/null
@@ -0,0 +1,44 @@
+#lang r5rs
+
+(define (traverse-tree! x)
+  (cond 
+    ((not (pair? x)) x)
+    ((eqv? (car x) 'traversed)
+     (cons (traverse-tree! (car (cdr x)))
+           (traverse-tree! (cdr (cdr x)))))
+    (else 
+     (begin
+       (set! x (cons 'traversed (cons (car x) (cdr x))))
+       (traverse-tree! x)))))
+
+(define (count-tree x)
+  (cond
+    ((not (pair? x)) 0)
+    ((traversed? x) (+ (count-tree (left x))
+                       (count-tree (right x))))
+    (else 
+     (begin
+       (set-car! x (traverse x))
+       (+ (count-tree (left x))
+          (count-tree (right x))
+          1)))))
+
+(define (traversed? x)
+  (if (pair? (car x))
+      (eqv? (car (car x)) 'traversed)
+      #f))
+
+(define (left x)
+  (if (traversed? x)
+      (cdr (car x))
+      (car x)))
+
+(define (right x)
+  (cdr x))
+
+(define (traverse x)
+  (cons 'traversed 
+        (car x)))
+
+(define x (list 'a 'b))
+(define z (cons x x))
diff --git a/src/sicp/ex3_18.rkt b/src/sicp/ex3_18.rkt
new file mode 100644 (file)
index 0000000..557f51f
--- /dev/null
@@ -0,0 +1,29 @@
+#lang r5rs
+
+#|
+we use a unique hash and store them into a set. If we again hit an element
+with the same hash, we have hit a cycle. For simplicity, we use car of a cell
+as the hash. So for this procedure to work, we will need unique values in each
+cell.
+|#
+
+(define (last-pair x)
+  (if (null? (cdr x))
+      x
+      (last-pair (cdr x))))
+
+(define (make-cycle x)
+  (set-cdr! (last-pair x) x)
+  x)
+
+(define z (make-cycle (list 'a 'b 'c)))
+
+(define (cycle? x)
+  (define (contains-cycle? x trail)
+    (let ((f (car x))
+          (n (cdr x)))
+      (cond
+        ((not (pair? n)) #f)
+        ((memq f trail)  #t)
+        (else (contains-cycle? (cdr x) (cons f trail))))))
+  (contains-cycle? x '()))
diff --git a/src/sicp/ex3_19.rkt b/src/sicp/ex3_19.rkt
new file mode 100644 (file)
index 0000000..189f957
--- /dev/null
@@ -0,0 +1,26 @@
+#lang r5rs
+
+(define (contains-cycle? x y)
+  (if (or (not (pair? x))
+          (not (pair? y)))
+      #f
+      (let ((t (cdr x))
+            (h (cdr (cdr y))))
+        (if (eqv? t h)
+            #t
+            (contains-cycle? t h)))))
+
+(define (last-pair x)
+  (if (null? (cdr x))
+      x
+      (last-pair (cdr x))))
+
+(define (make-cycle x)
+  (set-cdr! (last-pair x) x)
+  x)
+
+(define z (make-cycle (list 'a 'b 'c)))
+(define z1 (list 'a 'b 'c))
+
+(contains-cycle? z (cdr z))
+(contains-cycle? z1 (cdr z1))
\ No newline at end of file