Haskell中的Luhn算法 [英] Luhn algorithm in Haskell

查看:1059
本文介绍了Haskell中的Luhn算法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想我已经在Haskell中正确计算了 Luhn算法

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

现在我必须创建一个新函数 sigLuhn n ,并且 luhn n == True ,那么 sigLuhn n 给出数字(或数字),如果我们将数字添加到最终的 n 中,则新数字验证Luhn算法太;如果 luhn n == 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]

因为如果我们调用 n = 49927398716 然后

because if we call n = 49927398716 then

luhn (10*n + 8) ==> True

存在 8 code> 0 。我的想法是下一个:

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"

代码不会给出错误,但 c $ c> sigLuhn 对此代码不正确。总之,如果我们假设函数 luhn 是好的,你能帮我正确写出 sigLuhn 吗?非常感谢。

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.

推荐答案

去年秋天,我在课堂上分配了它。这是最好的解决方案之一。

I assigned it in a class last fall. Here's one of the best solutions.

doubleAndSum :: [Int] -> Int
doubleAndSum = fst . foldr (\i (acc, even) -> (acc + nextStep even i, not even)) (0,False)
  where 
    nextStep even i
        | even      = (uncurry (+) . (`divMod` 10) . (*2)) i
        | otherwise = i 

myLuhn :: Int -> Bool
myLuhn = (0 ==) . (`mod` 10) . doubleAndSum . (map (read . (: ""))) . show

testCC :: [Bool]
testCC = map myLuhn [49927398716, 49927398717, 1234567812345678, 1234567812345670]
-- => [True,False,False,True]

这篇关于Haskell中的Luhn算法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆