测试整数能否被 11 整除

发布于 2024-09-28 15:36:13 字数 177 浏览 2 评论 0原文

我现在正在努力处理这段代码。我想判断一个整数是否能被11整除。据我所知,当一个整数的各位数字之和(一次+,一次-)能被11整除时,该整数就能被11整除。

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

我如何在 Haskell 中写下这个?提前致谢。

I'm struggling with this code right now. I want to determine whether an integer is divsible by 11. From what I have read, an integer is divisible to 11 when the sum (one time +, one time -) of its digits is divisible by 11.

For example: 56518 is divisible by 11, because 8-1+5-6+5 = 11, and 11 is divisible by 11.

How can i write this down in Haskell? Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

手心的温暖 2024-10-05 15:36:13

一个数字x可以被y整除,如果它除以y的余数是0。所以你可以这样做

divisibleBy11 x = x `rem` 11 == 0

A number x is divisible by y if it's remainder when divided by y is 0. So you can just do

divisibleBy11 x = x `rem` 11 == 0
可可 2024-10-05 15:36:13

ifan 我确信您知道在现实生活中您会使用 modrem 来完成这个简单的示例,但您所询问的算法很有趣。这是一种有趣的方法,强调 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'

ifan I'm sure you know that in real life you would use mod or rem for this simple example, but the algorithm you are asking about is interesting. Here's a fun way to do it that emphasizes the functional nature of 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'
高速公鹿 2024-10-05 15:36:13

当然,divmod 更快,但为什么不呢?我假设问题是将数字转换为数字列表:

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

56518 被转换为字符串 "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)

Surely, div and mod are faster, but why not? I assume the problem is converting a number to a list of digits:

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

56518 is converted to a String "56518", and each symbol in the string (every digit) is converted to a string itself with map (:[]), at this point we have ["5","6","5","1","8"], and we read every single-digit string as an integer value: [5,6,5,1,8]. Done.

Now we can calculate the sum of digits this way:

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

cycle [1,-1] makes an infinite list [1, -1, 1, -1, ...], which we pair with the reversed list of digits (toDigit x), and multiply elements of every pair. So we have [8, -1, 5, -6, 5] and its sum.

Now we can do it recursively:

isDivisible x
  | x == 11 || x == 0 = True
  | x < 11            = False
  | x > 11            = isDivisible (sumDigits x)
仅此而已 2024-10-05 15:36:13

怎么样...

mod11 n | n < 0 = 11 - mod11 (-n) 
        | n < 11 = n
        | otherwise = mod11 $ (n `mod` 10) - (n `div` 10) 

How about...

mod11 n | n < 0 = 11 - mod11 (-n) 
        | n < 11 = n
        | otherwise = mod11 $ (n `mod` 10) - (n `div` 10) 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文