From: Ramakrishnan Muthukrishnan Date: Mon, 15 Dec 2014 14:52:05 +0000 (+0530) Subject: homework #1 solution. X-Git-Url: https://git.rkrishnan.org/specifications/components/index.php?a=commitdiff_plain;h=fea228fd81c6ccc72ee172a10c9e8a517c2c457d;p=yorgey.git homework #1 solution. --- diff --git a/hw1/01-intro.pdf b/hw1/01-intro.pdf new file mode 100644 index 0000000..e791a68 Binary files /dev/null and b/hw1/01-intro.pdf differ diff --git a/hw1/credit-card.hs b/hw1/credit-card.hs new file mode 100644 index 0000000..9663af5 --- /dev/null +++ b/hw1/credit-card.hs @@ -0,0 +1,90 @@ +{-# OPTIONS_GHC -Wall #-} +module CreditCard where + +{-| reverse list of the digits in a given number n. +>>> toDigitsRev 1234 +[4,3,2,1] +>>> toDigitsRev 0 +[] +>>> toDigitsRev (-20) +[] +-} + +toDigitsRev :: Integer -> [Integer] +toDigitsRev n | n <= 0 = [] + | n < 10 = [n] + | otherwise = let (d, m) = n `divMod` 10 in + m : toDigitsRev d +{-| list of the digits in a given number n. +>>> toDigits 1234 +[1,2,3,4] +>>> toDigits 0 +[] +>>> toDigits (-10) +[] +-} + +toDigits :: Integer -> [Integer] +toDigits = reverse . toDigitsRev + +{-| double every other digit in a list (from the right). +>>> doubleEveryOther [8, 7, 6, 5] +[16,7,12,5] +>>> doubleEveryOther [1, 2, 3] +[1,4,3] + -} +doubleEveryOther :: [Integer] -> [Integer] +doubleEveryOther = reverse . doubleEveryOther' . reverse + where + doubleEveryOther' :: [Integer] -> [Integer] + doubleEveryOther' [] = [] + doubleEveryOther' [x] = [x] + doubleEveryOther' (x:y:ys) = x : 2 * y : doubleEveryOther' ys + +doubleEveryOther'' :: [Integer] -> [Integer] +doubleEveryOther'' xs | even (length xs) = doubleEven xs + | otherwise = doubleOdd xs + where doubleEven [] = [] + doubleEven [x] = [2*x] + doubleEven (x:y:ys) = (2*x):y:doubleEven ys + doubleOdd [] = [] + doubleOdd (y:ys) = y:doubleEven ys +{-| sum all the 'digits' in a list. +>>> sumDigits [16,7,12,5] +22 +-} +sumDigits :: [Integer] -> Integer +sumDigits xs = let pairs = map (`divMod` 10) xs in + sum $ map (\(x,y) -> (x + y)) pairs +{-| sum all the 'digits' in a list. +>>> sumDigits' [16,7,12,5] +22 +-} + +sumDigits' :: [Integer] -> Integer +sumDigits' xs = foldr (\x acc -> let (q,r) = x `divMod` 10 in acc + q + r) 0 xs + +{-| validate +>>> validate 4012888888881881 +True +>>> validate 4012888888881882 +False +-} +validate :: Integer -> Bool +validate n = (== 0) ((`rem` 10) (sumDigits (doubleEveryOther (toDigits n)))) + +{-| validate' +>>> validate' 4012888888881881 +True +>>> validate' 4012888888881882 +False +-} +validate' :: Integer -> Bool +validate' = (== 0) . (`rem` 10) . sumDigits . doubleEveryOther . toDigits + +-- tower of hanoi +type Peg = String +type Move = (Peg, Peg) +hanoi :: Integer -> Peg -> Peg -> Peg -> [Move] +hanoi 0 _ _ _ = [] +hanoi n a b c = hanoi (n - 1) a c b ++ [(a, c)] ++ hanoi (n - 1) b a c