; Copyright (c) 2009, Michael Cook ; http://www.foobarsoft.com (def primes (list 2)) (defn is-prime-by-list? ([number prime-list] (is-prime-by-list? number (inc (int (. Math sqrt number))) prime-list) ) ([number number-sqrt prime-list] (do ; Go through our list and see if we're prime (if (or (nil? prime-list) (= (. prime-list size) 0)) ; If the list is empty, we're prime true ; Else (let [current (first prime-list) remaining (rest prime-list)] (if (> number-sqrt current) ; If we've checked up to sqrt(number), we know we're prime true ; Else (if (= number current) ; Is the number the one at true ; the top of the list? Return yes ; Else (if (= (rem number current) 0) ; Can we prove not prime? false ; Not prime! ; Else (recur number number-sqrt remaining) ; Keep checking! ) ) ) ) ) ) ) ) (defn generate-primes [nums-end] (let [nums-start (inc (last primes)) nums-to-test (range nums-start nums-end)] (doall (for [x nums-to-test] (do (if (is-prime-by-list? x (reverse primes)) (def primes (concat primes (list x))) ) ) ) ) ; We don't want a real return value, so we'll do this nil ) ) (defn is-prime? [number] ; Simple sanity checks first (if (not (integer? number)) (throw (new Exception "Number must be an integer")) ) (if (< number 0) (throw (new Exception "Number can't be negative")) ) (if (or (nil? primes) (= (. primes size) 0)) ; Make sure we have a list to start with (def primes (list 2)) ) ; OK, do the work, things are sane (let [result (is-prime-by-list? number primes) number-root (int (. Math ceil (. Math sqrt number)))] (if (= false result) ; If we know it's not prime, we don't need to generate more numbers to test with false ; Else (do (if (> number-root (last primes)) ; OK, we'll need more numbers, we won't be able to tell from what we have now (generate-primes (inc number-root)) ) ; We should be set (is-prime-by-list? number primes) ) ) ) )