summaryrefslogtreecommitdiff
path: root/lec01/hw.hs
blob: 8f4197dbcb45e3c92d06cd34a835506f8a46c842 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
-- homework for lecture 1

-- exercise 1

toDigits :: Integer -> [Integer]
toDigits n
    | n > 0     = toDigits (n `div` 10) ++ [n `mod` 10]
    | otherwise = []

revList :: [Integer] -> [Integer]
revList [] = []
revList (x:xs) = revList xs ++ [x]

toDigitsRev :: Integer -> [Integer]
toDigitsRev n = revList (toDigits n)

-- exercise 2

-- [SIDE NOTE] The exercise specifies that the function below "should double
-- every other number *beginning from the right*". However, it's unclear
-- whether this is a requirement (i.e. the function must double digits in
-- reverse order) or a mere clarification to better understand which numbers
-- should be doubled and which not. Since the order doesn't matter (and doing
-- the operation in reverse order would also complicate the solution), I
-- decided to do it from left to right, the usual order.
doubleEveryOther :: [Integer] -> [Integer]
doubleEveryOther [] = []
doubleEveryOther (x:y:ys) = x*2 : (y : doubleEveryOther ys)

-- exercise 3

-- This function assumes that the list only contains numbers between 0 and 19
sumDigits :: [Integer] -> Integer
sumDigits [] = 0
sumDigits (x:xs)
    | x >= 10 = (1 + x `mod` 10) + sumDigits xs
    | otherwise = x + sumDigits xs

-- exercise 4

validate :: Integer -> Bool
validate n = sumDigits (doubleEveryOther (toDigits n)) `mod` 10 == 0