2015-07-01 5 views
1

Я ожидаю 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

Я бы предложил написать несколько тестов для каждого из этих компонентов (хорошая возможность изучить quickcheck, если у вас мало времени). – jberryman

+1

@BradyDean Ваша функция 'sumDigits' неверна. Рассмотрим этот пример. 'lastDigit 123' возвращает' 3'. 'dropLastDigit 123' возвращает' 12'. Однако '3 + 12' не равно сумме цифр (' 1 + 2 + 3'). – Jubobs

+0

Цифры разделяются. 'sumDigits [10, 5, 18, 4] = 1 + 0 + 5 + 1 + 8 + 4 = 19' - это то, что я собираюсь сделать для –

ответ

1

Фрагмент x `div` 10 == 0 неверен, так как x делится на десять; вместо этого вы должны использовать `mod`. Кроме того, это уравнение неверно:

sumDigits (x : []) = x 

(Попробуйте, например, sumDigits [10].) Это может быть исправлено, но удалить его проще и по-прежнему верна.

+0

Ничего себе, я много раз читал код и никогда этого не замечал. Код теперь работает с этими изменениями. –

+1

@BradyDean По моему опыту, вы не можете обнаружить ошибки, прочитав код. И я тоже этого не делал; Я выполнил фрагменты кода на примере вашей ручной работы, чтобы увидеть, что он будет делать, и соответствует ли это ожидаемому, ища самую маленькую функцию, которая не соответствовала моим ожиданиям. Это мощный метод, который я призываю вас принять. –

+0

Да, я провел примеры, приведенные в курсе, но мне не с чем было работать. –

 Смежные вопросы

  • Нет связанных вопросов^_^