Hi I am new in Haskell and I came across an interesting problem but I was not really sure on how I would go about solving it. I am about to show you only two parts of the qu
The missing component is a way to break down an integer into its digits, and build it back up from there. That's easy:
digits:: Int -> [Int]
digits = map (`mod` 10) . takeWhile (/= 0) . iterate (`div` 10)
undigits :: [Int] -> Int
undigits = foldr f 0 where f i r = 10 * r + i
Then it looks like you need to post-process those digits in two different ways, but only if they match a predicate. Let's build a combinator for that:
when :: (a -> Bool) -> (a -> a) -> a -> a
when p f a = if p a then f a else a
The first case appears when you want to double digits in odd position (from left to right). Again trivial, with the minor inconvenience that digits breaks down a number by increasing power of ten. Let's prefix each number by its position:
prefix :: [Int] -> [(Int, Int)]
prefix is = let n = length is in zip [n, n-1..1] is
doubleOdd can now be expressed as
doubleodd :: [Int] -> [Int]
doubleodd = map (snd . when (odd . fst) (id *** double)) . prefix
You mentioned in a comment that when the double number overflows, its digits must be added together. This is the second case I was referring to and is again simplicity itself:
double :: Int -> Int
double = when (>= 10) (sum . digits) . (* 2)
Here is your final program:
program = undigits . doubleodd . tail . digits
... assuming the "between 13 and 15 digits" part is verified separately.