Lazy Pascal在Clojure的三角形

Luk*_*itt 1 clojure lazy-evaluation pascals-triangle

我正在尝试在Clojure中编写一个简洁,懒惰的Pascal三角形,旋转使得行/列跟随三角形的对角线.也就是说,我想生成以下lazy-seq的lazy-seq:

((1 1 1 1 ...)
 (1 2 3 4 ...)
 (1 3 6 10 ...)
 ...
 )
Run Code Online (Sandbox Code Playgroud)

我写的代码是:

(def pascal
  (cons (repeat 1)
        (lazy-seq
          (map #(map + %1 %2)
               (map #(cons 0 %) (rest pascal)))
               pascal
          )))
Run Code Online (Sandbox Code Playgroud)

这样每一行都是通过将自身的右移版本添加到前一行来形成的.问题是它永远不会越过第一行,因为那时(map #(cons 0 %) (rest pascal)))是空的.

=> (take 5 (map #(take 5 %) pascal))
((1 1 1 1 1))
Run Code Online (Sandbox Code Playgroud)

什么是解决这个问题的合理方法?我对Clojure中的编程很新,并且考虑到它涉及的问题的方式非常不同,所以我非常感谢任何有这方面经验的人的建议.

A. *_*ebb 6

简洁而懒惰

(def pascal (iterate (partial reductions +') (repeat 1)))

(map (partial take 5) (take 5 pascal))
;=> ((1 1 1 1 1) 
;    (1 2 3 4 5) 
;    (1 3 6 10 15) 
;    (1 4 10 20 35) 
;    (1 5 15 35 70))
Run Code Online (Sandbox Code Playgroud)

但是太懒了?

(take 5 (nth pascal 10000))
;=> StackOverflowError
Run Code Online (Sandbox Code Playgroud)

再试一次

(take 5 (nth pascal 10000))
;=> (0)
Run Code Online (Sandbox Code Playgroud)

呃 - 哦,重新开始,尝试再试一次

(def pascal (iterate (partial reductions +') (repeat 1)))
(count (flatten (map (partial take 5) (take 100000 pascal))))
;=> 500000
Run Code Online (Sandbox Code Playgroud)

现在这些都在你的堆里

(take 5 (nth pascal 100000))
;=> (1 100001 5000150001 166676666850001 4167083347916875001)
Run Code Online (Sandbox Code Playgroud)