我现在正在努力处理这段代码。我想确定一个整数是否可以被 11 整除。根据我的阅读,当整数的数字之和(一次 +,一次 -)可以被 11 整除时,一个整数可以被 11 整除。
例如:56518 可以被 11 整除,因为 8-1+5-6+5 = 11,而 11 可以被 11 整除。
我怎样才能在 Haskell 中写下来?提前致谢。
一个数字可以被除以0的余数x
被整除。所以你可以这样做y
y
divisibleBy11 x = x `rem` 11 == 0
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'
当然,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)
怎么样...
mod11 n | n < 0 = 11 - mod11 (-n)
| n < 11 = n
| otherwise = mod11 $ (n `mod` 10) - (n `div` 10)