我正在尝试制作一个算法来解决Project Euler 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
计算功能都会出错。
我做错了什么,这甚至会给我一个正确的解决方案,还是只会陷入困境?
答案 0 :(得分:5)
answer = average [map roundedSq [10E13..10E14]]
您已将映射列表放入此处的一个元素列表中。我想也许你的意思是:
answer = average (map roundedSq [10E13..10E14])
答案 1 :(得分:2)
您的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)
请注意,这使用的foldl'
来自Data.List
,而不是foldl
。 foldl
有自己的空间问题(比我更有知识的人可能希望评论)。
正如TobiasWärre指出的那样,
roundedSq n | (roundedSq n) == roundedSq (n-1) = n : roundedSq (n+1)
将导致无限循环:
roundedSq n
(roundedSq n) == roundedSq (n-1)
为真,我们将返回n : roundedSq (n+1)
作为答案(roundedSq n) == roundedSq (n-1)
roundedSq n
答案 2 :(得分:1)
如果您希望平均值返回Fractional
个数字,则需要使用此定义:
average a = (sum a) / (fromIntegral $ length a)
(/)
是Fractional
除法运算符,而div
是Integral
除法运算符。请注意,您还需要使用fromIntegral
,因为length
会返回Int
,而Fractional
不是{{1}}类型类的一部分。
答案 3 :(得分:0)
由于
,你会陷入无限循环roundedSq n | (roundedSq n) ...
编辑:有时似乎我脑子里有个洞。当然平均值还可以。
但是,由于您没有递减或递增所有对舍入的递归调用,您将永远不会触及“底部”并终止。