haskell-homework/lib/Homework/Ch01/CreditCards.hs

45 lines
1.2 KiB
Haskell

module Homework.Ch01.CreditCards where
toDigits :: Integer -> [Integer]
toDigits = go []
where
go acc 0 = acc
go acc n = go (n `mod` 10 : acc) (n `div` 10)
revDigits :: [Integer] -> [Integer]
revDigits = go []
where
go acc (x : xs) = go (x : acc) xs
go acc [] = acc
toDigitsRev :: Integer -> [Integer]
toDigitsRev = revDigits . toDigits
doubleEveryOther :: [Integer] -> [Integer]
doubleEveryOther = revDigits . go []
where
go acc (first : second : rest) = go ((second * 2) : first : acc) rest
go acc [last'] = last' : acc
go acc [] = acc
sumDigits :: [Integer] -> Integer
sumDigits digits = foldDigits 0 (+) [y | x <- digits, y <- toDigits x]
where
foldDigits acc f (x : xs) = foldDigits (f x acc) f xs
foldDigits acc _ [] = acc
validateWithParens :: Integer -> Bool
validateWithParens n = f n `mod` 10 == 0
where
f n' = sumDigits (doubleEveryOther (toDigitsRev n'))
validateWithDollars :: Integer -> Bool
validateWithDollars n = f n `mod` 10 == 0
where
f n' = sumDigits $ doubleEveryOther $ toDigitsRev n'
validateWithCompose :: Integer -> Bool
validateWithCompose n = f n `mod` 10 == 0
where
f = sumDigits . doubleEveryOther . toDigitsRev