【发布时间】:2017-02-02 22:28:44
【问题描述】:
我想我已经在 Haskell 中正确计算了 Luhn algorithm:
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
例如,
luhn 49927398716 ==> True
luhn 49927398717 ==> False
现在我必须创建一个新函数sigLuhn,这样,给定一个整数n,和luhn n == True,然后sigLuhn n 给出一个(或多个)数字,这样如果我们将数字添加到最后到n,那么新号码也验证了Luhn算法;如果luhn n == False 函数给出错误。例如,
sigLuhn 49927398716 ==> [8]
因为如果我们调用n = 49927398716 那么
luhn (10*n + 8) ==> True
是8 是0 中的最小整数。我的想法是下一个:
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"
代码没有给出错误,但 sigLuhn 与此代码不正确。简而言之,如果我们假设函数luhn很好,你能帮我正确写sigLuhn吗?非常感谢。
【问题讨论】:
-
1.如果你给你的函数提供更具描述性的名称,那将会有所帮助。很难说这里发生了什么。 2. 在假设第一部分基于几个测试工作之前,我会在继续之前做进一步的测试。我浪费了很多时间来排除检查一段代码的错误,因为我认为我已经彻底测试了它......但没有。
-
抱歉,函数名称。我不得不把很多单词翻译成英文,我也忘了翻译函数的名称。
-
好吧,老实说,我不知道 Luhn 算法是什么或者如何实现它,但是对于任何可以帮助你的人,你应该尽量让它尽可能简单为他们。
-
我想在这里再说一遍,我几乎可以肯定
luhn是正确的。只有我要写得更好sigLuhn。 -
好吧,不幸的是,我帮不上那个忙。我会说通过检查每个辅助函数来开始调试,以确保它们返回您所期望的。