I think I have computed Luhn algorithm correctly in Haskell:
f1 :: Integer -> [Integer]
f1 x = if x < 10 then [x] else (f1 (div x 10))++[mod x 10]
f2 :: [Integer] -> [Integer]
f2 xs = [(!!) xs (x - 1) | x <- [1..(length xs)] , even x]
f3 :: [Integer] -> [Integer]
f3 xs = if mod (length xs) 2 /= 0 then (f2 xs) else (f2 (0:xs))
f4 :: [Integer] -> [Integer]
f4 xs = map (*2) (f3 xs)
f5 :: [Integer] -> [[Integer]]
f5 xs = map f1 xs
f6 :: [[Integer]] -> [Integer]
f6 [] = []
f6 (xs : xss) = xs++(f6 xss)
f7 :: [Integer] -> [Integer]
f7 xs = [(!!) xs (x - 1) | x <- [1..(length xs)] , odd x]
f8 :: [Integer] -> [Integer]
f8 xs = if mod (length xs) 2 /= 0 then (f7 xs) else (f7 (0:xs))
f9 :: [Integer] -> [Integer]
f9 xs = (f8 xs) ++ (f4 xs)
f :: Integer -> Integer
f x = sum (f6 (f5 (f9 xs)))
where xs = f1 x
luhn :: Integer -> Bool
luhn x = if mod (f x) 10 == 0 then True else False
For example,
luhn 49927398716 ==> True
luhn 49927398717 ==> False
Now I have to make a new function sigLuhn
such that, given an integer n
, with luhn n == True
, then sigLuhn n
gives the digit (or digits) such that if we add the digit to the final to n
, then the new number verifies the Luhn algorithm too; if luhn n == False
the function gives an error. For example,
sigLuhn 49927398716 ==> [8]
because if we call n = 49927398716
then
luhn (10*n + 8) ==> True
being 8
the lowest integer from 0
. My thought is the next:
g1 :: Integer -> Integer
g1 x = div 10 x + 1
g2 :: Integer -> Integer -> Integer
g2 x y = x*(floor (10)^(g1 y)) + y
g3 :: Integer -> [Bool]
g3 x = [luhn (g2 x y) | y <- [1..]]
g4 :: [Bool] -> Int
g4 xs = minimum (elemIndices True xs)
g :: Integer -> Int
g x = g4 (g3 x)
sigLuhn :: Integer -> [Int]
sigLuhn x = if (luhn x) then [g x] else error "The conditions of Luhn's algorithm are not valid"
The code doesn't give error but sigLuhn
is not correct with this code. In short, if we assume that the function luhn
is good, can you help me to write sigLuhn
correctly? Thank you very much.