Luhn算法实现
Luhn algorithm implementation
我期待 luhn 5594589764218858 = True
但它总是 False
-- Get the last digit from a number
lastDigit :: Integer -> Integer
lastDigit 0 = 0
lastDigit n = mod n 10
-- Drop the last digit from a number
dropLastDigit :: Integer -> Integer
dropLastDigit n = div n 10
toRevDigits :: Integer -> [Integer]
toRevDigits n
| n <= 0 = []
| otherwise = lastDigit n : toRevDigits (dropLastDigit n)
-- Double every second number in a list starting on the left.
doubleEveryOther :: [Integer] -> [Integer]
doubleEveryOther [] = []
doubleEveryOther (x : []) = [x]
doubleEveryOther (x : y : z) = x : (y * 2) : doubleEveryOther z
-- Calculate the sum of all the digits in every Integer.
sumDigits :: [Integer] -> Integer
sumDigits [] = 0
sumDigits (x : []) = x
sumDigits (x : y) = (lastDigit x) + (dropLastDigit x) + sumDigits y
-- Validate a credit card number using the above functions.
luhn :: Integer -> Bool
luhn n
| sumDigits (doubleEveryOther (toRevDigits n)) `div` 10 == 0 = True
| otherwise = False
我知道可以更轻松地完成,但我正在关注 Haskell introductory。我认为我唯一的问题是 luhn
函数。该课程提到可能会出现问题,因为 toRevDigits
颠倒了数字,但我认为它应该可以正常工作。
代码段 x `div` 10 == 0
没有正确检查 x
是否可以被 10 整除;您应该改用 `mod`
。另外,这个等式是不正确的:
sumDigits (x : []) = x
(试试,例如sumDigits [10]
。)可以修复,但删除更简单,仍然正确。
我期待 luhn 5594589764218858 = True
但它总是 False
-- Get the last digit from a number
lastDigit :: Integer -> Integer
lastDigit 0 = 0
lastDigit n = mod n 10
-- Drop the last digit from a number
dropLastDigit :: Integer -> Integer
dropLastDigit n = div n 10
toRevDigits :: Integer -> [Integer]
toRevDigits n
| n <= 0 = []
| otherwise = lastDigit n : toRevDigits (dropLastDigit n)
-- Double every second number in a list starting on the left.
doubleEveryOther :: [Integer] -> [Integer]
doubleEveryOther [] = []
doubleEveryOther (x : []) = [x]
doubleEveryOther (x : y : z) = x : (y * 2) : doubleEveryOther z
-- Calculate the sum of all the digits in every Integer.
sumDigits :: [Integer] -> Integer
sumDigits [] = 0
sumDigits (x : []) = x
sumDigits (x : y) = (lastDigit x) + (dropLastDigit x) + sumDigits y
-- Validate a credit card number using the above functions.
luhn :: Integer -> Bool
luhn n
| sumDigits (doubleEveryOther (toRevDigits n)) `div` 10 == 0 = True
| otherwise = False
我知道可以更轻松地完成,但我正在关注 Haskell introductory。我认为我唯一的问题是 luhn
函数。该课程提到可能会出现问题,因为 toRevDigits
颠倒了数字,但我认为它应该可以正常工作。
代码段 x `div` 10 == 0
没有正确检查 x
是否可以被 10 整除;您应该改用 `mod`
。另外,这个等式是不正确的:
sumDigits (x : []) = x
(试试,例如sumDigits [10]
。)可以修复,但删除更简单,仍然正确。