【发布时间】:2014-11-28 03:22:18
【问题描述】:
在今天早些时候将我的解决方案提交给 Project Euler 的problem 50 后,我正在浏览问题的论坛,查看其他人的解决方案/执行时间。
一段时间后,我开始为自己的代码感到非常自豪,该代码在大约 3 秒内解决了问题(我的代码使用了 Primes 库并使用 O2 编译)...
...然后我遇到了下面的代码,它在大约 0.05 秒内解决了它...在解释模式下(即ghci)。
有人能解释一下下面的代码如何/为什么解决这个特定问题吗?
令人费解的部分是将tails 函数应用于列表理解中的无限素数列表(primes)。我很难理解我们如何保证查看所有可能的连续素数子列表,而不仅仅是tails 生成的子列表。
(我通常在ghci 中尝试代码片段的策略在这种情况下不起作用,因为primes 是无限的......)
问题:我们被要求找到 1,000,000 以下的最大素数,这是连续素数相加的结果。例如,连续素数之和 100 以下的最大素数是 41(2 + 3 + 5 + 7 + 11 + 13)。
import Data.List (tails)
import Data.Numbers.Primes
under n xs = takeWhile (< n) xs
takeUntil p xs = foldr (\x r-> if p x then [x] else x:r) [] xs
res :: [((Int, Int), (Int, Int))]
-- ((top_length, sums_to), (total_length, starting_prime))
res = [(r,(length s,x)) | (x:xs) <- tails primes
, let s = zip [1..]
$ under 100
$ scanl (+) x xs
, let r = ...]
main = mapM_ print $ takeUntil ...
【问题讨论】:
-
“用
O2编译的obv”是什么意思? OBV 是某种特殊的编译工具吗? -
obv = 显然 :P(把它拿出来),只是想强调我自己的代码相对于上面发布的代码执行得有多糟糕。
-
也许你应该发布你的代码,我们可以告诉你为什么它运行这么慢。
-
该条目确实指出“通过试除法检测素数”和“通过 Eratosthenes 的筛子找到素数”是“都从编译模块加载的”。
-
btw the problem 要求 “最连续素数的总和?” 即最长的,而不是最大的。
标签: haskell list-comprehension primes infinite