我正在尝试解决codeeval上的斐波那契问题。起初我以通常的递归方式编写它,虽然我得到了正确的输出,但我没有通过测试,因为它使用了~70MB的内存,使用限制为20MB。我找到了一个approximation formula并重新编写它以使用它认为是重堆栈使用导致我超过限制。但是,似乎没有任何减少。
(ns fibonacci.core
(:gen-class))
(use 'clojure.java.io)
(def phi (/ (+ 1 (Math/sqrt 5)) 2))
(defn parse-int
"Find the first integer in the string"
[int-str]
(Integer. (re-find #"\d+" int-str)))
(defn readfile
"Read in a file of integers separated by newlines and return them as a list"
[filename]
(with-open [rdr (reader filename)]
(reverse (map parse-int (into '() (line-seq rdr))))))
(defn fibonacci
"Calculate the Fibonacci number using an approximatation of Binet's Formula. From
http://www.maths.surrey.ac.uk/hosted-sites/R.Knott/Fibonacci/fibFormula.html"
[term]
(Math/round (/ (Math/pow phi term) (Math/sqrt 5))))
(defn -main
[& args]
(let [filename (first args)
terms (readfile filename)]
(loop [terms terms]
((comp println fibonacci) (first terms))
(if (not (empty? (rest terms)))
(recur (rest terms))))))
(-main (first *command-line-args*))
示例输入:
0
1
2
3
4
5
6
7
8
9
10
11
12
13
50
示例输出:
0
1
1
2
3
5
8
13
21
34
55
89
144
233
12586269025
他们的输入显然远大于此,我无法看到它。如何修改此代码以大大减少内存使用?
编辑:这是不可能的。 Codeeval知道这个问题并正在努力。请参阅here。
答案 0 :(得分:4)
Clojure的Codeeval已被破坏。没有公认的Clojure解决方案listed两个月前有一个message from the company说他们仍然在解决这个问题。
织补。
答案 1 :(得分:3)
据推测,问题是输入文件非常大,而readfile
函数正在内存中创建整个行列表。
避免这种情况的方法是一次处理一行,而不是保持整个序列,如:
(defn -main [& args]
(let [filename (first args)]
(with-open [rdr (reader filename)]
(doseq [line (line-seq rdr)]
(-> line parse-int fibonacci println)))))
答案 2 :(得分:-1)
您是否收到堆栈溢出错误?如果是这样,Clojure支持任意精度,因此尝试使用/'
代替/
可能会有所帮助。 +
,-
,*
和/
的撇号版本旨在将数字强制转换为BigInt
以防止堆栈溢出。
请参阅this question。