我想编写一个函数prime-seq
,使用from
和to
显示两个数字之间的列表。
这是我的代码,我认为如果列表中的数字为真,则显示它们。但我不知道如何写它,我对这种语言很新。
(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)
答案 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
生成from
和to
(包括)之间所有数字的序列,然后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