我正在尝试制作一个算法来解决欧拉项目的Problem 255
我想出了这个解决方案:
roundedSq n | (roundedSq n) == roundedSq (n-1) = n : roundedSq (n+1)
| rem n 2 == 1 = n : floor ( ((2*10^((d-1) `div` 2)) + ceiling (n `div` (2*10^((d-1) `div` 2)) )) `div` 2 )
| otherwise = n : floor ( ((7*10^((d-2) `div` 2)) + ceiling (n `div` (7*10^((d-2) `div` 2)) )) `div` 2 )
where
d = length (map (digitToInt) (show (n)))
average a = (sum a) `div` (length a)
answer = average [map roundedSq [10E13..10E14]]
main = do
print answer但每次我尝试加载时,answer计算函数都会出现错误。我做错了什么?这会给我一个正确的解决方案吗?还是会陷入循环??
发布于 2009-09-17 11:17:01
answer = average [map roundedSq [10E13..10E14]]在这里,您将映射列表放入一个包含一个元素的列表中。我想你的意思可能是:
answer = average (map roundedSq [10E13..10E14])发布于 2009-09-17 11:11:53
您的average有问题。
average a = (sum a) `div` (length a)sum使用整个列表。length也使用整个列表。这意味着当其中一个函数遍历它时,整个列表将被生成并保存在内存中,并且直到另一个函数遍历它时才会被垃圾回收。
您向average传递了一个非常大的列表,因此您将耗尽内存。
解决方案:将average重写为一个仅遍历列表一次的函数,以便可以在生成列表时对其进行垃圾收集。
示例(未测试):
average a = sum `div` length
where (sum, length) = foldl' f (0, 0) a
f (sum, length) i = (sum + i, length + 1)请注意,这里使用的是来自Data.List的foldl',而不是foldl。foldl有它自己的空间问题(比我更有见识的人可能希望评论一下)。
正如Tobias Wärre所指出的,
roundedSq n | (roundedSq n) == roundedSq (n-1) = n : roundedSq (n+1)将导致无限循环:
如果我们要评估的答案为真,我们将返回n : roundedSq (n+1)作为我们评估所需的答案
roundedSq n
发布于 2009-09-17 10:59:08
如果你想让average返回一个Fractional数,你需要使用这个定义:
average a = (sum a) / (fromIntegral $ length a)(/)是Fractional除法运算符,而div是Integral除法运算符。注您还需要使用fromIntegral,因为length返回的Int不是Fractional类型类的一部分。
https://stackoverflow.com/questions/1437924
复制相似问题