From: Ramakrishnan Muthukrishnan Date: Wed, 9 Feb 2011 14:27:34 +0000 (+0530) Subject: solutions to 3.12 to 3.19 X-Git-Url: https://git.rkrishnan.org/about.html?a=commitdiff_plain;h=bbcb59ccafb27181b4805573e9ea2fa3d77e7951;p=sicp.git solutions to 3.12 to 3.19 --- diff --git a/src/sicp/ex3_12.rkt b/src/sicp/ex3_12.rkt new file mode 100644 index 0000000..2c043df --- /dev/null +++ b/src/sicp/ex3_12.rkt @@ -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 index 0000000..3a9e3ae --- /dev/null +++ b/src/sicp/ex3_13.rkt @@ -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 index 0000000..5c6c1a1 --- /dev/null +++ b/src/sicp/ex3_14.rkt @@ -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 index 0000000..142612c --- /dev/null +++ b/src/sicp/ex3_16.rkt @@ -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 index 0000000..94d3b45 --- /dev/null +++ b/src/sicp/ex3_17.rkt @@ -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 index 0000000..557f51f --- /dev/null +++ b/src/sicp/ex3_18.rkt @@ -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 index 0000000..189f957 --- /dev/null +++ b/src/sicp/ex3_19.rkt @@ -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