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
|
library
|
||||||
exposed-modules:
|
exposed-modules:
|
||||||
Homework
|
Homework
|
||||||
|
Homework.Ch01
|
||||||
other-modules:
|
other-modules:
|
||||||
Paths_homework
|
Paths_homework
|
||||||
hs-source-dirs:
|
hs-source-dirs:
|
||||||
@ -48,6 +49,7 @@ test-suite test
|
|||||||
type: exitcode-stdio-1.0
|
type: exitcode-stdio-1.0
|
||||||
main-is: Spec.hs
|
main-is: Spec.hs
|
||||||
other-modules:
|
other-modules:
|
||||||
|
Homework.Ch01Spec
|
||||||
Paths_homework
|
Paths_homework
|
||||||
hs-source-dirs:
|
hs-source-dirs:
|
||||||
test
|
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