Exercise 3.19. Redo exercise 3.18 using an algorithm that takes only a constant amount of space. (This requires a very clever idea.) ———————————————————————————————————————————————————————————————————————— (define (cyclical? x) (define (go n m ancestor x) (cond ((null? x) false) ((eq? ancestor x) true) ((= m n) (go (* 2 n) (+ 1 m) x (cdr x))) (else (go n (+ 1 m) ancestor (cdr x))))) (go 1 1 '(unused) x)) We begin with a list x which may or may not contain a cycle. If the list contains a cycle, we will eventually see the same pair twice. If we can choose the correct pair to store, then we only need to compare each following pair to that one ancestor, and if there is a cycle we will eventually find a match. The first idea would be to simply compare every pair to the first pair of the whole list. However, it is possible that the list starts with a segment that leads into a cycle but does not participate in it. This means that we must advance the stored ancestor to avoid missing loops that come later in the structure. However, if we advance the ancestor too frequently, we will miss loops that are too long. m is the number of elements already seen. ancestor is the floor(log₂ m)th pair of the list. n is ceil(log₂ m).