Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
clojure-project euler primes超时_Clojure - Fatal编程技术网

clojure-project euler primes超时

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? [

我正在尝试解决欧拉项目的问题,该问题要求您提供第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? [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))