Luhn算法实现

时间:2015-07-01 20:59:14

标签: haskell luhn

我期待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会反转数字,但我认为它应该可行。

1 个答案:

答案 0 :(得分:1)

代码段x `div` 10 == 0无法正确检查x可被10整除;你应该使用`mod`代替。此外,这个等式是不正确的:

sumDigits (x : [])    = x

(请尝试,例如sumDigits [10]。)可以修复,但删除它更简单且仍然正确。