以常规方式编写Collatz序列生成函数后:
(define (colatz-seq #;starting@ n)
(cond ((= n 1) '())
((even? n) (cons (/ n 2) (colatz-seq (/ n 2))))
((odd? n) (cons (+ (* n 3) 1) (colatz-seq (+ (* n 3) 1))))))
我想用展开来写它:
(define (next-colatz-step n)
(cond ((even? n) (/ n 2))
((odd? n) (+ (* n 3) 1))))
(define (one? n)
(= n 1))
(define (colatz-seq #;starting@ n)
(unfold one? next-colatz-step next-colatz-step n))
它按预期工作但是如果不使用" next-colatz-step"我就无法工作。作为展开的第二和第三参数。为什么? 为两个参数提供相同的论证似乎有点奇怪。
答案 0 :(得分:3)
请注意,在您的两个解决方案中,您都排除了序列中的起始元素,而在基于unfold
的解决方案中,生成的序列在某种程度上落后于一个位置,这就是您必须通过{ {1}}两次。
如果我们从给定的next-colatz-step
数字开始,n
的第二个参数只是unfold
过程,这似乎更自然。但是这给我们留下了一个问题,即最后一个值(假设Collatz猜想为真,它应该总是identity
)现在已经丢失了。这就是为什么现在我们必须提供一个额外的程序来生成列表的尾部。试试这个:
1