レイジーシーケンスを作成せずにバージョンを使用できます。それはより速くそしてより安く働きます:
(defn sieve* [res s]
(if (empty? s)
res
(recur (conj res (first s))
(filter #(not= 0 (mod % (first s)))
(rest s)))))
(defn sieve [n]
(sieve* [] (range 2 n)))
(sieve 10000)
=> [2 3 5 7 11 13 17 ... 9941 9949 9967 9973]
そして、ここにもっと効率的なバージョンがあります:
(defn sieve* [res n maxn]
(if (> n maxn)
res
(if (some #(= 0 (mod n %))
(take (round (sqrt (count res))) res))
(recur res (inc n) maxn)
(recur (conj res n) (inc n) maxn))))
(defn sieve [n]
(sieve* [] 2 n))
(last (sieve 1000000))
=> 999983
アップデート。かなり速い/安い怠惰なバージョン
(defn primes-seq* [primes]
(let [last-prime (last primes)]
(cons last-prime
(lazy-seq
(primes-seq*
(conj primes
(first (let [compare-primes
(take (round (sqrt (count primes)))
primes)]
(drop-while (fn [n]
(some #(= 0 (mod n %))
compare-primes))
(iterate inc (inc last-prime)))))))))))
(def primes-seq (primes-seq* [2]))
(last (take 50000 primes-seq))
=> 611953