-
Notifications
You must be signed in to change notification settings - Fork 71
/
Copy pathe-3.18.scm
47 lines (38 loc) · 1.33 KB
/
e-3.18.scm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
; Exercise 3.18.
;
; Write a procedure that examines a list and
; determines whether it contains a cycle, that is, whether a
; program that tried to find the end of the list by taking
; successive cdrs would go into an infinite loop. Exercise 3.13
; constructed such lists.
; ------------------------------------------------------------
; I guess, the way to go there is to go through the list and if
; we end in a situation to get to the pair that has pointer to
; a pair that is already traversed then we are definitelly going to
; end up cycling through them.
(load "../helpers.scm")
(load "3.3.scm")
; by reusing history object, it is actually simple to write this
(define (cycled? l)
(cond ((or (null? l) (not (pair? l))) '#f)
((null? (cdr l)) '#f)
(((history 'visited?) (cdr l)) '#t)
(else
(begin ((history 'add) l)
(or (cycled? (car l))
(cycled? (cdr l)))))))
; we have to reset global history object every time.
; This can be improved by making new history local to the cycled? procedure.
(output (cycled? (list 1 2 3))) ; #f
(history 'reset)
(define l (list 1 2 3))
(append! l l) ; cycle
(history 'reset)
(output (cycled? l)) ; #t
(define m (list 1 2 3))
(define n (list 1 2 3))
(append! m n)
(history 'reset)
(output (cycled? m))
(history 'reset)
(output (cycled? n))