Credit card problem from Chapter 01
This commit is contained in:
parent
82667ad5f8
commit
a71926c399
10
hie.yaml
Normal file
10
hie.yaml
Normal file
@ -0,0 +1,10 @@
|
||||
cradle:
|
||||
stack:
|
||||
- path: "lib"
|
||||
component: "homework:lib"
|
||||
|
||||
- path: "app"
|
||||
component: "homework:exe"
|
||||
|
||||
- path: "test"
|
||||
component: "homework:test"
|
@ -23,6 +23,7 @@ source-repository head
|
||||
library
|
||||
exposed-modules:
|
||||
Homework
|
||||
Homework.Ch01
|
||||
other-modules:
|
||||
Paths_homework
|
||||
hs-source-dirs:
|
||||
@ -48,6 +49,7 @@ test-suite test
|
||||
type: exitcode-stdio-1.0
|
||||
main-is: Spec.hs
|
||||
other-modules:
|
||||
Homework.Ch01Spec
|
||||
Paths_homework
|
||||
hs-source-dirs:
|
||||
test
|
||||
|
39
lib/Homework/Ch01.hs
Normal file
39
lib/Homework/Ch01.hs
Normal file
@ -0,0 +1,39 @@
|
||||
module Homework.Ch01 where
|
||||
|
||||
-- This calls reverse on toDigitsRev because I somehow did this backwards by default.
|
||||
toDigits :: Integer -> [Integer]
|
||||
toDigits = rev [] . toDigitsRev
|
||||
where
|
||||
rev acc (x : xs) = rev (x : acc) xs
|
||||
rev acc [] = acc
|
||||
|
||||
-- I don't know how I managed it, but turning the number into an array already reversed it?
|
||||
toDigitsRev :: Integer -> [Integer]
|
||||
toDigitsRev n
|
||||
| n < 1 = []
|
||||
| otherwise =
|
||||
let leftDigit = n `mod` 10
|
||||
shiftedDigits = n `div` 10
|
||||
in leftDigit : toDigitsRev shiftedDigits
|
||||
|
||||
doubleEveryOther :: [Integer] -> [Integer]
|
||||
doubleEveryOther (odd' : even' : rest) = odd' : (even' * 2) : doubleEveryOther rest
|
||||
doubleEveryOther rest = rest
|
||||
|
||||
sumDigits :: [Integer] -> Integer
|
||||
sumDigits = sumDigits' 0 . flattenDigits [] . eachToDigits []
|
||||
where
|
||||
eachToDigits acc (x : xs) = eachToDigits (toDigits x : acc) xs
|
||||
eachToDigits acc [] = acc
|
||||
|
||||
flattenDigits acc ((x : xs) : rest) = flattenDigits (x : acc) (xs : rest)
|
||||
flattenDigits acc ([] : rest) = flattenDigits acc rest
|
||||
flattenDigits acc [] = acc
|
||||
|
||||
sumDigits' acc (x : xs) = sumDigits' (acc + x) xs
|
||||
sumDigits' acc [] = acc
|
||||
|
||||
validate :: Integer -> Bool
|
||||
validate n = f n `mod` 10 == 0
|
||||
where
|
||||
f = sumDigits . doubleEveryOther . toDigitsRev
|
53
test/Homework/Ch01Spec.hs
Normal file
53
test/Homework/Ch01Spec.hs
Normal file
@ -0,0 +1,53 @@
|
||||
module Homework.Ch01Spec where
|
||||
|
||||
import Homework.Ch01
|
||||
import Test.Hspec
|
||||
|
||||
spec :: Spec
|
||||
spec = describe "Credit Card Validation" $ do
|
||||
describe "toDigits" $ do
|
||||
context "n is less than 1" $ do
|
||||
it "returns an empty list" $ do
|
||||
toDigits 0 `shouldBe` []
|
||||
|
||||
context "n contains a single digit" $ do
|
||||
it "creates a list with one digit" $ do
|
||||
toDigits 9 `shouldBe` [9]
|
||||
|
||||
context "n contains more than one digit" $ do
|
||||
it "creates a list of digits" $ do
|
||||
toDigits 12345 `shouldBe` [1, 2, 3, 4, 5]
|
||||
|
||||
describe "toDigitsRev" $ do
|
||||
context "n is less than 1" $ do
|
||||
it "returns an empty list" $ do
|
||||
toDigitsRev 0 `shouldBe` []
|
||||
|
||||
context "n contains a single digit" $ do
|
||||
it "creates a list with one digit" $ do
|
||||
toDigitsRev 9 `shouldBe` [9]
|
||||
|
||||
context "n contains more than one digit" $ do
|
||||
it "creates a list of the digits in reverse order" $ do
|
||||
toDigitsRev 12345 `shouldBe` [5, 4, 3, 2, 1]
|
||||
|
||||
describe "doubleEveryOther" $ do
|
||||
context "list length is odd" $ do
|
||||
it "does not double the last digit" $ do
|
||||
doubleEveryOther [1, 2, 3, 4, 5] `shouldBe` [1, 4, 3, 8, 5]
|
||||
|
||||
context "list length is even" $ do
|
||||
it "doubles every other digit" $ do
|
||||
doubleEveryOther [1, 2, 3, 4, 5, 6] `shouldBe` [1, 4, 3, 8, 5, 12]
|
||||
|
||||
describe "sumDigits" $ do
|
||||
it "splits doubled digits into single digits and sums all single digits together" $ do
|
||||
sumDigits [16, 7, 12, 5] `shouldBe` 22
|
||||
|
||||
describe "validate" $ do
|
||||
it "returns True for a valid credit card number" $ do
|
||||
validate 5105105105105100 `shouldBe` True
|
||||
validate 2223577120017656 `shouldBe` True
|
||||
it "returns False for invalid credit card number" $ do
|
||||
validate 5105105105105101 `shouldBe` False
|
||||
validate 2223573420017656 `shouldBe` False
|
Loading…
Reference in New Issue
Block a user