两个方块的总和:我的错误在哪里?

时间:2017-03-23 18:13:22

标签: algorithm haskell number-theory

我试图计算将自然数写为两个方格之和的方法数。我来自definition

specifically

所以,这是我的代码。在我测试的地方下面,我发现我认为结果中的错误。

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。

我错过了一些重要但又不知道的东西。

1 个答案:

答案 0 :(得分:3)

我认为你误读了公式的语义。 Wikipedia article表示以下等式:

cardinality of sum of powers

这里有两个重要的评论:

  • Z ,而不是 N ,因此(-1),( - 3),0等也是正方形的有效元素;和
  • 我们计算元组的数量,而不是,因此订单很重要(并且(1,2,2)不相等至(1,2)):如果(1,3)是一个解,那么(3,1)我们将它们视为两个独立的解。

现在10有以下除数: 1 ,2,5, 10 (你的程序忘记了1和10)。两个是一致的,1模4:1和5.此外,没有除数与3模4相同。所以d1 = 2d3 = 0。因此有八种(4×(2-0)= 8)可能性:

  1. (1,3):1 2 +3 2 = 10
  2. (3,1):3 2 +1 2 = 10
  3. (1,-3):1 2 +( - 3) 2 = 10
  4. (3,-1):3 2 +( - 1) 2 = 10
  5. ( - 1,3):( - 1) 2 +3 2 = 10
  6. ( - 3,1):( - 3) 2 +1 2 = 10
  7. ( - 1,-3):( - 1) 2 +( - 3) 2 = 10
  8. ( - 3,-1):( - 3) 2 +( - 1) 2 = 10
  9. 现在我们只需解决您的程序问题。您只需从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)的声音。