我是Haskell的初学者,并使用它解决了一些Project Euler的50个问题,但现在我卡在了问题66上。问题在于编译好的代码(ghc -O2 --make problem66.hs
)在10-20秒后占用了我机器所有的空闲内存。我的代码看起来像这样:
-- Project Euler, problem 66
diophantine x y d = x^2 - d*y^2 == 1
minimalsolution d = take 1 [(x, y, d) | y <- [2..],
let x = round $ sqrt $ fromIntegral (d*y^2+1),
diophantine x y d]
issquare x = (round $ sqrt $ fromIntegral x)^2 == x
main = do
print (map minimalsolution (filter (not . issquare) [1..1000]))
我有一种直觉,问题出在minimalsolution
列表理解中的无限列表上。
实际上,我以为由于Haskell的惰性求值,它只会评估列表,直到找到一个元素(因为使用了take 1
),并在此过程中舍弃所有diophantine
计算为False
的东西。我错了吗?
有趣的是,我在ghci中没有看到这种行为。这是因为ghci内部的处理速度太慢,以至于我必须等到看到内存消耗爆炸才能发现问题吗?还是其他原因?
请不要透露任何剧透。我只想知道极端内存消耗来自哪里以及如何解决它。
minimalsolution
函数中取出的列表是否始终包含元素? - Daniel Wagnerd
参数是非平方数,则应该在main
内的filter
中提供。但是我的算法完全可能是错误的。请注意,有时需要一段时间才能找到实际解决方案,因为数字很快变得非常大。 - Johannes P