tags:

views:

318

answers:

3

I have some big numbers (again) and i need to find if the sum of the digits is an even number. I tried this: finding the sum of the digits with a while loop and then checking if that sum % 2 equals 0 and it's working but it's too slow for big numbers, because i am given intervals of numbers and if the input is 1999999 19999999999 then my program fails, i cannot complete within the time limit which is 0,1 sec.

What to do ? Is there any other faster way to do this ?

EDIT: The input 1999999 19999999999 means it will start with 1999999 and check all the numbers like i wrote above until 19999999999, and because we are talking about big numbers (< 2^30) my program is not worthy.

+2  A: 

Hint: if you find that the sum of the digits of a given number n is odd, will the sum of the digits of the number n + 1 be odd or even?

Update: as @Mark pointed out, it is not so simple... but the anomalies appear only when n + 1 is a multiple of 10, i.e. (n + 1) % 10 == 0. Then the oddity does not change. However, out of these cases, every 10th is an exception when the oddity does change still (e.g. 199 -> 200). And so on... basically, depending on where the highest value 9 of n is, one can decide whether or not the oddity changes between n and n + 1. I admit it is a bit tedious to calculate, but still I am sure it is faster than just adding up all these digits...

Péter Török
7: Odd, 8: Even, 9: Odd, 10: Odd
Mark Byers
not every ten -- look at my and swestrup's answers, only every 10 if an odd number of digits are changing. (eg 99->100 even -> odd)
Hogan
@Hogan That's what I tried to express (I admit that you and @swestrup explained the same clearer).
Péter Török
+5  A: 

You don't need to sum the digits. Think about it. The sum starts with zero, which is generally regarded as even (although you can special case this if you want).

Each even digit changes nothing. If the sum was odd, it stays odd, if it was even it stays even.

Each odd digit changes the sum from even to odd, or odd to even.

So, just count the number of odd digits. If the number is even, then the sum of all the digits is even. If the number is odd, then the sum of all the digits is odd.

Now, you only need to do this for the FIRST number in your range. What you need to do next is figure out how the evenness or oddness of the numbers change as you keep adding one.

I leave this as an exercise for the reader. Homework has to involve some work!

swestrup
Funny, we both wrote the same "hints" at the same time.
Hogan
You don't even have to sum the number of odd digits (pseudocode): sum_is_odd = false; foreach(digit) { sum_is_odd ^= (digit }
Mark B
True, and for even faster work, don't bother to extract the last bit until the end:sum_is_odd = 0;foreach(digit) { sum_is_odd ^= digit; }sum_is_odd
swestrup
+1  A: 

Here is a hint, it may work -- you don't need to sum the digits you just need to know if the result will be odd or even -- if you start with the assumption your total is even, even numbers have no effect, odd number toggle (ie an odd number of odd digits make it odd).

Depending on the language there may be a faster way to perform the calculation without adding.

Also remember -- a number is odd or even based on its last binary digit.

Example:

In ASM you could XOR the low order bit to get the correct result

In FORTH this would not work so well...

Hogan
it's a good hint, but the original questioner only needs to do THAT part once, on the smallest number... and then use the suggestion above.
Brian Postow
It needs to do it at every change that is a power of 10 at least -- not so easy to figure out a power of ten -- takes some IF statements which are slow. XORs are fast. (esp if you lay out the data in memory well.)
Hogan