在clojure连锁电话?

Kon*_*rus 4 algorithm functional-programming clojure

我正试图在Clojure中实施Eratosthenes的筛子.我想测试的一种方法是:

  1. 获得范围(2 3 4 5 6 ... N)
  2. 对于2 <= i<= N.
    • 通过我的范围filter,删除倍数i
    • 对于i+1迭代,使用先前过滤的结果

我知道我可以用它loop/recur,但这会导致堆栈溢出错误(由于某种原因,不应用尾调用优化).

我怎么能迭代地做呢?我的意思是调用N次调用相同的例程,将i迭代的结果传递给i+1th.

Mic*_*ent 5

(defn sieve [beg end]
  (letfn [(siever [to-sieve sieved]
                  (if (empty? to-sieve) sieved
                  (let [[f & r] to-sieve]
                    (if (> f (Math/sqrt end)) (into sieved to-sieve)
                        (recur (remove #(zero? (mod % f)) r) 
                           (conj sieved f))))))]
    (siever (range beg (inc end)) [])))
Run Code Online (Sandbox Code Playgroud)

这个似乎工作得很好.用(筛2 1000000)测试它并在几秒钟内返回而不吹.

  • 实际上它是迭代的 - "recur"跳转到`siever`的主体顶部而不消耗堆栈.我想`remove`可以使用`doall`,但这是一个单独的问题. (3认同)