45 lines
1.2 KiB
Haskell
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
|