如何在scheme / racket中使用展开来编写Collat​​z序列?

时间:2016-12-10 19:28:20

标签: scheme racket collatz

以常规方式编写Collat​​z序列生成函数后:

(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"我就无法工作。作为展开的第二和第三参数。为什么? 为两个参数提供相同的论证似乎有点奇怪。

1 个答案:

答案 0 :(得分:3)

请注意,在您的两个解决方案中,您都排除了序列中的起始元素,而在基于unfold的解决方案中,生成的序列在某种程度上落后于一个位置,这就是您必须通过{ {1}}两次。

如果我们从给定的next-colatz-step数字开始,n的第二个参数只是unfold过程,这似乎更自然。但是这给我们留下了一个问题,即最后一个值(假设Collat​​z猜想为真,它应该总是identity)现在已经丢失了。这就是为什么现在我们必须提供一个额外的程序来生成列表的尾部。试试这个:

1