我试图计算将自然数写为两个方格之和的方法数。我来自definition:
所以,这是我的代码。在我测试的地方下面,我发现我认为结果中的错误。
sumOfSquares :: Integer -> Int
sumOfSquares k = 4 * (d1 - d3)
where
divs = divisors k
d1 = congruents d1_test divs
d3 = congruents d3_test divs
d1_test n = (n - 1) `mod` 4 == 0
d3_test n = (n - 3) `mod` 4 == 0
congruents :: (Integer -> Bool) -> [Integer] -> Int
congruents f divs = length $ filter f divs
divisors :: Integer -> [Integer]
divisors k = divisors' 2 k
where
divisors' n k' | n*n > k' = [k']
| n*n == k' = [n, k']
| k' `mod` n == 0 = (n:(k' `div` n):result)
| otherwise = result
where result = divisors' (n+1) k'
当我运行它时,它会生成:
*Main Numbers.SumOfSquares> sumOfSquares 10
4
我计算出只有一种方法可以将10表示为两个方格的总和
1 ^ 2 + 3 ^ 2。请注意,中间结果(d1 - d3)
等于1。
我错过了一些重要但又不知道的东西。
答案 0 :(得分:3)
我认为你误读了公式的语义。 Wikipedia article表示以下等式:
这里有两个重要的评论:
现在10有以下除数: 1 ,2,5, 10 (你的程序忘记了1和10)。两个是一致的,1模4:1和5.此外,没有除数与3模4相同。所以d1 = 2
和d3 = 0
。因此有八种(4×(2-0)= 8)可能性:
现在我们只需解决您的程序问题。您只需从1
而不是2
开始计算:
divisors :: Integer -> [Integer]
divisors k = divisors' 1
where
divisors' i | i2 > k = []
| i2 == k = [i]
| k `mod` i == 0 = (i:(k `div` i):result)
| otherwise = result
where i2 = i*i
result = divisors' (i+1)
我还简化了程序并解决了一些其他语义错误。现在它至少应该是 r k (n)的声音。