Sunday, June 13, 2010

modification of Ex 3.19 of SICP - use constant amount of space to determine if a list contains loop

There was a flaw in my last post and modified it as below.
前回のアルゴリズムに欠陥があり、修正した。
上次的算法有问题,修改后可以保证只是用固定的存储空间

(define (loop? x)
  (define (iter y mk)
    (if (null? y) #f
      (if (eq? (car y) mk) #t
 (iter (cdr y) mk))))
  (if (null? x) #f
    (let ((mark (car x)))
      (iter (cdr x) mark))))
gosh> loop?
gosh>  (define s '( 1 2 3))
s
gosh>  (set-cdr! (cddr s) s)
#
gosh> 
(loop? s)
#t
gosh> (loop? '(1 2 3))
#f

Saturday, June 12, 2010

Ex 3.19 of SICP - use constant amount of space to find if a list contains a cycle

We can set a mark of a list,e.g. the address of the
head of a list and to see if this mark is accessed twice.
リストの頭のアドレスを記憶し、2回目アクセスされるときに、ロープが
あると判断できる。

可以记录一下list的头地址,如果此地址第二次被访问说明有循环在里面。
不是很确定是否为正解。因为要求使用一定量的空间。而记录头地址实际上
要记录整个list。但不须记录嵌套的list。

(define (loop? x)
  (define (iter y mk)
    (if (null? y) #f
      (if (eq? y mk) #t
(iter (cdr y) mk))))
  
  (if (null? x) #f
    (let ((mark x))
      (iter (cdr x) mark))))
loop?

gosh> loop?
gosh> (loop? '( 1 2 3))
#f
gosh> (define s '( 1 2 3))
s
gosh> (set-cdr! (cddr s) s)
#
gosh> 
#t
gosh> (loop? s)
#t

Ex3.16 a& Ex3.17 count-pairs

Paste here the answer of Ex3.16 and Ex3.17.
count-pairs function may return unexpected result
due to the introduction of set-car! etc.
Here we can show how it return 7 when there are just 3 pairs.
Also show the modified version of this function.

set-car!などにより、count-pairs関数が予想外の結果
を返してしまうことがある。ペアが三つなのに、7を返すケースを示します。
また、修正後の関数は以下の通りになります。

使用set-car!等可以任意改变pair的内容,导致count-pairs函数返回
我们并不期待的值。比如下面的例子显示此函数返回7。而实际上只有3个pair。

(define (count-pairs x)
  (let ((ref '()))
    (define (count-iter z)
      (if (not (pair? z))
  0
(if (counted? z ref) 0
  (begin
    (set! ref (append ref (list z)))
    (+ (count-iter (car z))
       (count-iter (cdr z))
       1)))))
    (count-iter x)))

(define (counted? y rf)
  (if (null? rf) #f
    (if (eq? y (car rf)) #t
      (counted? y (cdr rf)))))
counted?
gosh> (count-pairs '(1 2 3))
3
gosh> (define k '( 1 2 3))
k
gosh> (set-car! k (cdr k))
gosh> (set-car! (cdr k) (cddr k))
gosh> (count-pairs k)
3