Home > other >  How to code a function in Haskell which takes every other digit from an Int and adds it to a result
How to code a function in Haskell which takes every other digit from an Int and adds it to a result

Time:03-12

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.

  • Related