Skip to content

Commit d74cfb0

Browse files
committed
Add solution for exercise3-17
1 parent 402100a commit d74cfb0

File tree

1 file changed

+58
-0
lines changed

1 file changed

+58
-0
lines changed

chapter3/exercise3-17.rkt

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#lang racket
2+
3+
(define (count-pairs x)
4+
(let ((seen '()))
5+
(define (helper v)
6+
(cond ((not (pair? v))
7+
0)
8+
((memq v seen)
9+
0)
10+
(else (set! seen (cons v seen))
11+
(+ (helper (car v))
12+
(helper (cdr v))
13+
1))))
14+
(helper x)))
15+
16+
(module+ test
17+
(require rackunit)
18+
19+
(test-case "Test for count-pairs return 3, without shared"
20+
(define a (list '1 '2 '3))
21+
(check-equal? (count-pairs a) 3))
22+
23+
(test-case "Test for count-pairs return 3, with shared cons"
24+
(define shared (cons 1 2))
25+
(define b (cons shared (cons shared '())))
26+
(check-equal? (count-pairs b) 3))
27+
28+
(test-case "Test for count-pairs return 3, with multiple shared cons"
29+
(define shared (cons 1 2))
30+
(define c (cons shared shared))
31+
(define d (cons c c))
32+
(check-equal? (count-pairs d) 3)
33+
)
34+
35+
(test-case "Test for circular reference - mutable version"
36+
;; racket 不支持 Scheme set-cdr! 操作, 只支持针对 mutable 对象的
37+
;; set-mcdr!, 但如果要使用 set-mcdr!, 就需要使用相应的 mpair?,
38+
;; mcdr, mcar 函数, 那干脆在定义一个 mutable 版本的 count-pairs
39+
(define (mcount-pairs x)
40+
(let ((seen '()))
41+
(define (helper v)
42+
(cond ((not (mpair? v))
43+
0)
44+
((memq v seen)
45+
0)
46+
(else (set! seen (cons v seen))
47+
(+ (helper (mcar v))
48+
(helper (mcdr v))
49+
1))))
50+
(helper x)))
51+
52+
(define cycle (mcons 1 (mcons 2 null)))
53+
(set-mcdr! (mcdr cycle) cycle)
54+
(check-equal? (mcount-pairs cycle) 2))
55+
)
56+
57+
58+

0 commit comments

Comments
 (0)