clojure-project euler primes超时
我正在尝试解决欧拉项目的问题,该问题要求您提供第n个素数,例如第6个素数是13 我的代码如下所示:clojure-project euler primes超时,clojure,Clojure,我正在尝试解决欧拉项目的问题,该问题要求您提供第n个素数,例如第6个素数是13 我的代码如下所示: (ns scratch.core (require [clojure.string :as str :only (split-lines join)])) (def t "2\n3\n6") (defn work [input] (let [lines (map read-string (str/split-lines input))] (letfn [(is-prime? [
(ns scratch.core
(require [clojure.string :as str :only (split-lines join)]))
(def t "2\n3\n6")
(defn work [input]
(let [lines (map read-string (str/split-lines input))]
(letfn [(is-prime? [n]
(or
(= n 2)
(empty? (filter #(= 0 (mod n %)) (range 2 (inc (Math/sqrt n)))))))
(parse-primes [[x & xs]]
(prn (last (take x (filter #(is-prime? %) (iterate inc 2)))))
(if (seq xs)
(recur xs)))]
(parse-primes (rest lines)))))
(work t)
def t 2\n3\n6只是我的测试数据,我不知道验证答案的程序的实际数字是多少,尽管最大值是10^4
我很惊讶这段代码超时了,有人能告诉我潜在的瓶颈是什么吗?首先,你为什么要解析primes rest行而不是最后解析primes行?当输入字符串仅包含1个值(例如6)时,它会生成异常 然后,正如@ntalbs所建议的,您应该在每个函数中分离一些关注点。保留算法的思想,您可以让解析素数生成无限素数序列,而不是在输入时打印和重复:
(parse-primes []
(filter #(is-prime? %) (iterate inc 2)))
然后添加一个特定函数以获得第n个素数:
(nth-prime [n]
(nth (parse-primes) n))
然后,您可以用map nth prime line替换work函数parse primes line的主要部分,这使得该函数返回一个序列,而不是作为副作用打印并返回nil
作为清理工作,您可以删除工作的输入解析,以匹配现在返回的序列:
(defn work [rank-of-primes]
(letfn [...]
(map nth-prime rank-of-primes)))
(let [ranks-of-primes (map read-string (str/split-lines input))]
(work ranks-of-primes))
现在,为了提高性能,您只能测试奇数,而中的数字2是素数?并使用not any?进行简化
此时,在不修改您选择的算法的情况下,它应该更干净一些:
(defn work [rank-of-primes]
(letfn [(is-prime? [n]
(not-any? #(= 0 (mod n %))
(cons 2 (range 3 (inc (Math/sqrt n)) 2))))
(parse-primes []
(cons 2 (filter #(is-prime? %)
(cons 2 (iterate (partial + 2) 3)))))
(nth-prime [n]
(nth (parse-primes) n))]
(map nth-prime rank-of-primes)))
(let [input "2\n3\n6\n10000"
ranks-of-primes (map read-string (str/split-lines input))]
(work ranks-of-primes))
在素数问题上有很多东西需要探索。如果您对Clojure中的primes algos感兴趣,那么C.Grand的这篇文章会涉及更多内容。在我的环境中效果很好。无论如何,您在函数工作、解析字符串、打印结果等方面尝试了太多。您最好从函数中分离出副作用和非核心逻辑。例如,可以将参数作为字符串以外的序列传递,这会导致不必要的字符串解析。而不是打印结果,而是在parse primes嵌套函数中返回值。应用这些后,代码将更加清晰,您可以看到问题所在。感谢您的详细回复。检查答案的程序检查STDOUT,这就是我这样做的原因。答案是否有帮助?它确实有助于清理代码,但我从未足够快地完成问题,我在博客上写了这段经历
(defn work [rank-of-primes]
(letfn [(is-prime? [n]
(not-any? #(= 0 (mod n %))
(cons 2 (range 3 (inc (Math/sqrt n)) 2))))
(parse-primes []
(cons 2 (filter #(is-prime? %)
(cons 2 (iterate (partial + 2) 3)))))
(nth-prime [n]
(nth (parse-primes) n))]
(map nth-prime rank-of-primes)))
(let [input "2\n3\n6\n10000"
ranks-of-primes (map read-string (str/split-lines input))]
(work ranks-of-primes))