以下是我对4clojure Problem 108
的回答我能够通过前三次测试,但最后一次测试时间结束了。在最后一次测试中,代码运行得非常非常缓慢。究竟是什么造成了这个?
((fn [& coll] (loop [coll coll m {}]
(do
(let [ct (count coll)
ns (mapv first coll)
m' (reduce #(update-in %1 [%2] (fnil inc 0)) m ns)]
(println m')
(if (some #(<= ct %) (mapv m' ns))
(apply min (map first (filter #(>= (val %) ct) m')))
(recur (mapv rest coll) m'))))))
(map #(* % % %) (range)) ;; perfect cubes
(filter #(zero? (bit-and % (dec %))) (range)) ;; powers of 2
(iterate inc 20))
答案 0 :(得分:2)
您正在从每次迭代(recur (mapv rest coll) m')
您的一个输入非常缓慢地生成值,并且非常快速地加速到非常高的值:(filter #(zero? (bit-and % (dec %))) (range))
。
您的代码花费大部分时间通过递增1并测试位来发现2的幂。
您不需要具有发生次数的所有输入的地图。您不需要为目前为止找不到的项找到下一个值。我不会发布解决方案,因为它是一个练习,但是在每次迭代中消除最低的非匹配值应该是一个开始。
答案 1 :(得分:2)
除了这里的其他好答案之外,你还做了一堆数学,但是所有的数字都被装箱作为对象,而不是用作原语。有很多提示可以做得更好here。
答案 2 :(得分:1)
这是计算2的幂的非常低效的方法:
(filter #(zero? (bit-and % (dec %))) (range))
这基本上是从0到无穷大,从头开始测试每个数字,看看它是否是2的幂。进入序列越远,每次调用rest
的费用就越高。
鉴于它是测试输入,你不能改变它,我认为你需要重新思考你的方法。您可能只想在具有最小第一个值的序列上调用(mapv rest coll)
,而不是调用rest
。