58 lines
1.3 KiB
Racket
58 lines
1.3 KiB
Racket
;;#lang planet neil/sicp
|
|
#lang sicp
|
|
(#%require racket/trace)
|
|
|
|
(define (last-pair x)
|
|
(if (null? (cdr x))
|
|
x
|
|
(last-pair (cdr x))))
|
|
|
|
(define (count-pairs x)
|
|
(if (not (pair? x))
|
|
0
|
|
(+ (count-pairs (car x))
|
|
(count-pairs (cdr x))
|
|
1)))
|
|
|
|
(define (count-unique-pairs l)
|
|
(define (adjoin p pairs)
|
|
(cond ((null? pairs) (list p))
|
|
((not (pair? p)) pairs)
|
|
((eq? p (car pairs)) pairs)
|
|
(else (cons (car pairs)
|
|
(adjoin p (cdr pairs))))))
|
|
(trace-define (count l seen-pairs)
|
|
(cond ((not (pair? l)) 0)
|
|
((memq l seen-pairs) 0)
|
|
(else
|
|
(+ (count (car l)
|
|
(adjoin l seen-pairs))
|
|
(count (cdr l)
|
|
(adjoin l
|
|
(adjoin (car l)
|
|
seen-pairs)))
|
|
1))))
|
|
(count l '()))
|
|
|
|
;; Both give 3
|
|
(define l1 '(a b c))
|
|
|
|
;; count-pairs never stops
|
|
(define l2 '(a b c))
|
|
(set-cdr! (last-pair l2) l2)
|
|
|
|
;; count-pairs returns 4
|
|
(define a '(a b))
|
|
(define l3 (cons (last-pair a) a))
|
|
|
|
(define l4-3 (cons 'a '()))
|
|
(define l4-2 (cons l4-3 l4-3))
|
|
(define l4-1 (cons l4-2 '()))
|
|
(define l4 l4-1)
|
|
|
|
|
|
(define l5-3 (cons 'a '()))
|
|
(define l5-2 (cons l5-3 l5-3))
|
|
(define l5-1 (cons l5-2 l5-2))
|
|
(define l5 l5-1)
|