4

我现在正在努力处理这段代码。我想确定一个整数是否可以被 11 整除。根据我的阅读,当整数的数字之和(一次 +,一次 -)可以被 11 整除时,一个整数可以被 11 整除。

例如:56518 可以被 11 整除,因为 8-1+5-6+5 = 11,而 11 可以被 11 整除。

我怎样才能在 Haskell 中写下来?提前致谢。

4

4 回答 4

16

一个数字可以被除以0的余数x被整除。所以你可以这样做yy

divisibleBy11 x = x `rem` 11 == 0
于 2010-10-21T17:17:28.130 回答
9

ifan 我相信你知道在现实生活中你会使用mod这个rem简单的例子,但是你问的算法很有趣。这是一种有趣的方法,它强调了 Haskell 的功能性:

digits = map (`mod` 10) . takeWhile (> 0) . iterate (`div` 10)

divisible11 = (== 0) . head . dropWhile (>= 11) . iterate (reduce11 . digits)
  where
    reduce11 []     = 0
    reduce11 (d:ds) = foldl combine d $ zip (cycle [(-), (+)]) ds
    combine d (op, d') = d `op` d'
于 2010-10-21T17:29:54.933 回答
2

当然,div而且mod更快,但为什么不呢?我认为问题是将数字转换为数字列表:

toDigits = map (read . (:[])) . show

56518转换为 String "56518",并且字符串中的每个符号(每个数字)都转换为字符串本身map (:[]),此时我们有["5","6","5","1","8"],并且我们将每个单个数字字符串读取为整数值:[5,6,5,1,8]。完毕。

现在我们可以这样计算数字的总和:

sumDigits x = sum (zipWith (*) (cycle [1,-1]) (reverse (toDigits x)))

cycle [1,-1]生成一个无限列表[1, -1, 1, -1, ...],我们将其与反转的数字列表 ( toDigit x) 配对,并将每对的元素相乘。所以我们有[8, -1, 5, -6, 5]它的总和。

现在我们可以递归地做到这一点:

isDivisible x
  | x == 11 || x == 0 = True
  | x < 11            = False
  | x > 11            = isDivisible (sumDigits x)
于 2010-10-22T14:26:26.183 回答
0

怎么样...

mod11 n | n < 0 = 11 - mod11 (-n) 
        | n < 11 = n
        | otherwise = mod11 $ (n `mod` 10) - (n `div` 10) 
于 2010-10-22T07:14:26.437 回答