Fast Prime Number Generation in Clojure

后端 未结 16 1858
萌比男神i
萌比男神i 2020-12-02 12:30

I\'ve been working on solving Project Euler problems in Clojure to get better, and I\'ve already run into prime number generation a couple of times. My problem is that it is

16条回答
  •  鱼传尺愫
    2020-12-02 12:51

    After coming to this thread and searching for a faster alternative to those already here, I am surprised nobody linked to the following article by Christophe Grand :

    (defn primes3 [max]
      (let [enqueue (fn [sieve n factor]
                      (let [m (+ n (+ factor factor))]
                        (if (sieve m)
                          (recur sieve m factor)
                          (assoc sieve m factor))))
            next-sieve (fn [sieve candidate]
                         (if-let [factor (sieve candidate)]
                           (-> sieve
                             (dissoc candidate)
                             (enqueue candidate factor))
                           (enqueue sieve candidate candidate)))]
        (cons 2 (vals (reduce next-sieve {} (range 3 max 2))))))
    

    As well as a lazy version :

    (defn lazy-primes3 []
      (letfn [(enqueue [sieve n step]
                (let [m (+ n step)]
                  (if (sieve m)
                    (recur sieve m step)
                    (assoc sieve m step))))
              (next-sieve [sieve candidate]
                (if-let [step (sieve candidate)]
                  (-> sieve
                    (dissoc candidate)
                    (enqueue candidate step))
                  (enqueue sieve candidate (+ candidate candidate))))
              (next-primes [sieve candidate]
                (if (sieve candidate)
                  (recur (next-sieve sieve candidate) (+ candidate 2))
                  (cons candidate 
                    (lazy-seq (next-primes (next-sieve sieve candidate) 
                                (+ candidate 2))))))]
        (cons 2 (lazy-seq (next-primes {} 3)))))
    

提交回复
热议问题