I want to create a function as mentioned in the title. The specific is that it adds the digits in reversed order, you can see that in the test cases: 12 -> 1; 852369 -> 628; 1714 -> 11; 12345 -> 42; 891 -> 9; 448575 -> 784; 4214 -> 14
The main idea is that when the number is bigger than 99 it enters the helper function which has i - indicator if the the digit is on an even position, and res which stores the result. Helper begins to cycle n as it checks whether or not the current digit is on even position and adds it to the result.
So far I've tried the following code:
everyOther :: Int -> Int
everyOther n
| n < 10 = error "n must be bigger than 10 or equal"
| n < 100 = div n 10
| otherwise = helper n 0 0
where
helper :: Int -> Int -> Int -> Int
helper n i res
| n < 100 = res
| i == 1 = helper (div n 10) (i - 1) (res (mod n 10)*10)
| otherwise = helper (div n 10) i res
Any help would be appreciated!
CodePudding user response:
You can obtain the one but last digit of x
with mod (div x 10) 10
. You can use this with an accumulator that accumulates the value by each time multiplying with 10, so:
everyOther :: Int -> Int
everyOther = go 0
where go a v
| v < 10 = a
| otherwise = go (10*a mod (div v 10) 10) (div v 100)
If v
is thus less than 10, we can return the accumulator, since there is no "other digit" anymore. If that is not the case, we multiply a
with 10
, and add mod (div v 10) 10
to add the other digit to it, and recurse with the value divided by 100 to move it two places to the right.
We can improve this, as @Daniel Wagner says, by making use of quotRem :: Integral a => a -> a -> (a, a)
:
everyOther :: Int -> Int
everyOther = go 0
where go a v
| v < 10 = a
| otherwise = let (q, r) = v `quotRem` 100 in go (10*a r `quot` 10) q
here we thus work with the remainder of a division by 100, and this thus avoids an extra modulo.