Clojure fibonacci

时间:2016-10-18 18:14:58

标签: clojure

#(take %
  (map first
    (iterate (fn [[i1 i2]]
                 [i2 (+ i1 i2)])
             [1 1])))

这是在clojure中生成fib seq的函数。 我不明白这一部分:

(fn [[i1 i2]]
          [i2 (+ i1 i2)])
          [1 1])

从[i1 i2]到[i2(+ i1 i2)]。 如何使这个序列继续增长?在我看来它始终是2个元素。 需要帮忙。谢谢!

3 个答案:

答案 0 :(得分:3)

功能

(fn [[i1 i2]]
  [i2 (+ i1 i2)])

接受序列的一个步骤并产生该过程的下一步。因此,每次调用都会在序列中产生一个步骤。这是一个中间解决方案,其中每个步骤都有两个元素。第一个元素是到目前为止的答案,第二个元素提供了足够的上下文来产生下一步。所以输出看起来像:

user> (take 5  
            (iterate (fn [[i1 i2]]
                         [i2 (+ i1 i2)])
                     [1 1]))
([1 1] [1 2] [2 3] [3 5] [5 8])

然后,后一阶段将完成整个序列并删除额外信息,只留下每一步的答案。

user> (map first
           (take 5  
                 (iterate (fn [[i1 i2]]
                            [i2 (+ i1 i2)])
                          [1 1])))
(1 1 2 3 5)

这是一个很好的应用程序,将问题分解为可分离的部分,然后组成这些部分以形成最终答案。

答案 1 :(得分:1)

传递给iterate的函数是

(fn [[i1 i2]]
    [i2 (+ i1 i2)])

所有函数都会生成给定前一个序列的下一个术语(使用模式匹配将名称i1和i2分配给传入向量的成员)。

iterate有两个参数,即生成序列中下一个术语的函数,以及序列的起始值。函数iterate负责生成惰性序列。

为了更简单的示例(没有模式匹配),您可以使用

生成一个正整数的惰性序列
(iterate inc 0)

答案 2 :(得分:0)

You are quite right. The function ...

(fn [[i1 i2]] [i2 (+ i1 i2)])

... does produce one pair of numbers from another. For example,

((fn [[i1 i2]] [i2 (+ i1 i2)]) [6 19])

; [19 25]

Its iterate that produces the sequence, by repeatedly applying the function. This yields a sequence of pairs:

(iterate (fn [[i1 i2]] [i2 (+' i1 i2)]) [1 1])

;([1 1] [1 2] [2 3] [3 5] [5 8] [8 13] [13 21] ...)

The first or the second elements of these pairs form a Fibonacci sequence, depending where you want to start. To get the former, we just wrap the above in (map first ...):

(map first (iterate (fn [[i1 i2]] [i2 (+' i1 i2)]) [1 1]))

;(1 1 2 3 5 8 13 21 ...)

If you're familiar with the ->> threading macro, you might find it easier to read as

(->> [1 1]
     (iterate (fn [[i1 i2]] [i2 (+ i1 i2)]))
     (map first))

;(1 1 2 3 5 8 13 21 ...)