Skip to content

Instantly share code, notes, and snippets.

@m-mujica
Created March 3, 2015 13:27
Show Gist options
  • Save m-mujica/3215005fe41a950143ba to your computer and use it in GitHub Desktop.
Save m-mujica/3215005fe41a950143ba to your computer and use it in GitHub Desktop.
-- Exercise 1
-- We need to first find the digits of a number.
-- Define the functions
-- toDigits :: Integer -> [Integer]
-- toDigitsRev :: Integer -> [Integer]
-- toDigits should convert positive Integers to a list of digits. (For 0 or
-- negative inputs, toDigits should return the empty list.) toDigitsRev
-- should do the same, but with the digits reversed.
-- Example: toDigits 1234 == [1,2,3,4]
-- Example: toDigitsRev 1234 == [4,3,2,1]
-- Example: toDigits 0 == []
-- Example: toDigits (-17) == []
toDigits :: Integer -> [Integer]
toDigits 0 = []
toDigits n = toDigits (div n 10) ++ [mod n 10]
toDigitsRev :: Integer -> [Integer]
toDigitsRev n = reverse (toDigits n)
-- Exercise 2
-- Once we have the digits in the proper order, we need to
-- double every other one.
-- Define a function
-- doubleEveryOther :: [Integer] -> [Integer]
-- Remember that doubleEveryOther should double every other number
-- beginning from the right, that is, the second-to-last, fourth-to-last,
-- numbers are doubled.
-- Example: doubleEveryOther [8,7,6,5] == [16,7,12,5]
-- Example: doubleEveryOther [1,2,3] == [1,4,3]
double :: Integer -> Integer
double n = n + n
doubleEveryOther :: [Integer] -> [Integer]
doubleEveryOther xs = reverse (doubleEveryOtherFromLeft (reverse xs))
doubleEveryOtherFromLeft :: [Integer] -> [Integer]
doubleEveryOtherFromLeft [] = []
doubleEveryOtherFromLeft [x] = [x]
doubleEveryOtherFromLeft (x:y:zs) = x : double y : doubleEveryOtherFromLeft zs
-- Exercise 3
-- The output of doubleEveryOther has a mix of one-digit
-- and two-digit numbers. Define the function
-- sumDigits :: [Integer] -> Integer
-- to calculate the sum of all digits.
-- Example: sumDigits [16,7,12,5] = 1 + 6 + 7 + 1 + 2 + 5 = 22
sumDigits :: [Integer] -> Integer
sumDigits [] = 0
sumDigits xs = sum (concatMap (toDigits) xs)
-- Exercise 4 Define the function
-- validate :: Integer -> Bool
-- that indicates whether an Integer could be a valid credit card number.
-- This will use all functions defined in the previous exercises.
-- Example: validate 4012888888881881 = True
-- Example: validate 4012888888881882 = False
validate :: Integer -> Bool
validate n = mod (sumDigits (doubleEveryOther (toDigits n))) 10 == 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment