Skip to content

Instantly share code, notes, and snippets.

@tnoda
Created July 1, 2012 14:51
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tnoda/3028665 to your computer and use it in GitHub Desktop.
Save tnoda/3028665 to your computer and use it in GitHub Desktop.
Sieve of Eratosthenes in Clojure
(defn prime? [n]
(every? #(pos? (rem n %)) (range 2 (Math/sqrt (inc n)))))
(defn naive-primes [n]
(filter prime? (range 2 (inc n))))
(defn primes'
([^long n]
(let [not-prime (doto (boolean-array (inc n))
(aset 0 true)
(aset 1 true))
primes (long-array (inc n))]
(loop [p (int 0), i (int 2)]
(if (<= i n)
(if (aget ^booleans not-prime i)
(recur p (inc i))
(do
(aset ^longs primes p i)
(loop [j (* 2 i)]
(when (<= j n)
(aset ^booleans not-prime j true)
(recur (+ j i))))
(recur (inc p) (inc i))))
(take p primes))))))
(defn sieve [[xs ps]]
(let [[p & more] xs]
[(remove #(zero? (rem % p)) xs) (cons p ps)]))
(defn primes [n]
(if (< n 2)
[]
(->> [(range 2 (inc n)) nil]
(iterate sieve)
(drop-while #(< (ffirst %) (Math/sqrt n)))
first
(apply concat))))
@brian-a-clark
Copy link

I know it's 3.5 years later, but in the third example, I believe your drop-while condition should be <=, rather than <.

Try feeding it a square of a prime.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment