范围内的素数序列

时间:2018-01-05 20:52:59

标签: math clojure

我想编写一个函数prime-seq,使用fromto显示两个数字之间的列表。

这是我的代码,我认为如果列表中的数字为真,则显示它们。但我不知道如何写它,我对这种语言很新。

(defn is-prime? [n]
  (empty?
    (filter #(= 0 (mod n %)) (range 2 n))))

(defn prime-seq [from to]
  (drop from (take to is-prime?)))

结果应该是:

(prime-seq 1 5)
=> (2 3 5)

2 个答案:

答案 0 :(得分:1)

你非常接近:

(defn is-prime? [n]
  (empty? (filter #(= 0 (mod n %)) (range 2 n))))

(defn prime-seq [from to]
  (filter is-prime? (range from (inc to))))

(prime-seq 1 29)
=> (1 2 3 5 7 11 13 17 19 23 29)

这是使用range生成fromto(包括)之间所有数字的序列,然后filter使用is-prime?谓词is-prime?该列表

对于您的(mod 1 1) => 0谓词,有很多方法可以确定素数。在您评论false时,您的谓词将返回true,但1不是素数。您只需在谓词中为此添加一个特殊情况,这样任何小于2的数字都会返回(defn is-prime? [n] (if (< 1 n) (empty? (filter #(= 0 (mod n %)) (range 2 n))) false))

and

使用(defn is-prime? [n] (and (< 1 n) (not (some #(= 0 (mod n %)) (range 2 n))))) 稍微简洁:

{{1}}

答案 1 :(得分:0)

如果人们来到这里找到一个用于查找在Clojure中实现的素数的合理快速算法,这里是Clojure中Sieve of Eratosthenes的一个实现(使用JVM数组):

(defn find-primes
 "Finds all prime numbers less than n, returns them sorted in a vector"
  [n]
  (if (< n 2)
    []
    (let [^booleans sieve (boolean-array n false)
          s (-> n Math/sqrt Math/floor int)]
      (loop [p 2]
        (if (> p s)
          (into []
            (remove #(aget sieve %))
            (range 2 n))
          (do
            (when-not (aget sieve p)
              (loop [i (* 2 p)]
                (when (< i n)
                  (aset sieve i true)
                  (recur (+ i p)))))
            (recur (inc p))))))))

示例:

(find-primes 100)
=> [2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97]

还有一些基准测试:

(require '[criterium.core :as bench])

(bench/bench
  (find-primes 100000))

;Evaluation count : 17940 in 60 samples of 299 calls.
;             Execution time mean : 3.370834 ms
;    Execution time std-deviation : 217.730604 µs
;   Execution time lower quantile : 3.040426 ms ( 2.5%)
;   Execution time upper quantile : 3.792958 ms (97.5%)
;                   Overhead used : 1.755126 ns