所有素数低于2000000的clojure总和

时间:2013-06-15 05:30:55

标签: optimization clojure functional-programming primes

这是项目欧拉问题。

我从Fastest way to list all primes below N学习 并实施了一个clojure:

(defn get-primes [n]
  (loop [numbers (set (range 2 n))
         primes []]
    (let [item (first numbers)]
      (cond 
        (empty? numbers)
        primes
        :else
        (recur (clojure.set/difference numbers (set (range item n item)))
               (conj primes item))))))

使用如下:

(reduce + (get-primes 2000000))

但它太慢了..

我想知道为什么,有人能开导我吗?

1 个答案:

答案 0 :(得分:3)

这个算法甚至不正确:在每次迭代之外,除了最后一次迭代之外,它将(first numbers)的值加到primes,但不能保证它实际上是一个素数,因为使用的设置数据结构是无序的。 (对于Python原文也是如此,正如其作者在您链接到的问题的编辑中所提到的那样。)因此,您首先需要通过将(set (range ...))更改为(into (sorted-set) (range ...))来修复它。

即便如此,这根本不是寻找素数的好算法。为了做得更好,您可能希望使用Java数组和loop / recur编写Sieve of Eratosthenes的命令式实现,或者像Melissa中描述的类似SoE的函数算法。 E.奥尼尔的精美论文The Genuine Sieve of Eratosthenes