views:

534

answers:

7

I have to check, if given number is divisible by 7, which is usualy done just by doing something like n % 7 == 0, but the problem is, that given number can have up to 100000000, which doesn't fit even in long long.

Another constrain is, that I have only few kilobytes of memory available, so I can't use an array.

I'm expecting the number to be on stdin and output to be 1/0.

This is an example

34123461273648125348912534981264376128345812354821354127346821354982135418235489162345891724592183459321864592158
0

It should be possible to do using only about 7 integer variables and cin.get(). It should be also done using only standard libraries.

+11  A: 

Think about how you do division on paper. You look at the first digit or two, and write down the nearest multiple of seven, carry down the remainder, and so on. You can do that on any abritrary length number because you don't have to load the whole number into memory.

Paul Tomblin
wow, very nice, thanks
Darth
+1: start with the concept that a number is just a list of digits and you perform division on each digit independently.
D.Shawley
+10  A: 

Most of the divisibility by seven rules work on a digit level, so you should have no problem applying them on your string.

Zed
+1 for the link
sean e
+1  A: 

I'd start by subtracting some big number which is divisible by 7.

Examples of numbers which are divisible by 7 include 700, 7000, 70000, 140000000, 42000000000, etc.

In the particular example you gave, try subtracting 280000000000(some number of zeros)0000.

Even easier to implement, repeatedly subtract the largest possible number like 70000000000(some number of zeros)0000.

ChrisW
+21  A: 

you can use a known rule about division by 7 that says: group each 3 digits together starting from the right and start subtracting and adding them alternativly, the divisibility of the result by 7 is the same as the original number:

ex.:

testing 341234612736481253489125349812643761283458123548213541273468213
        549821354182354891623458917245921834593218645921580

   (580-921+645-218+593-834+921-245+917-458+623-891+354-182
    +354-821+549-213+468-273+541-213+548-123+458-283+761-643
    +812-349+125-489+253-481+736-612+234-341 
    = 1882 )
    % 7 != 0 --> NOK!

there are other alternatives to this rule, all easy to implement.

najmeddine
This works because 1001 is divisible by 7.
starblue
First time I see this rule, any references available?
elcuco
@elcuco, it's a nice trick from modular mathematics, using the Chinese Remainder Theorem. It actually works on 11 and 13 too since 1001 = 7*11*13.
rlbond
see http://en.wikipedia.org/wiki/Divisibility_rule
najmeddine
@rlbond For 11 you don't need groups of three digits. Instead add/subtract every other digit. This works because 11 is divisible by 11. :-)
starblue
This is a good rule for humans, but for computers it is unnecessarily complicated.
starblue
Nice solution, but how can I implement it when I have to read input from begining to end, so I can't determine when the first group starts/ends? The only option I can think of is trying all three combinations at a time and then at the end determine which one was correct, but that doesn't seem like a very clean solution. I guess there is no way to read input backwards?
Darth
A: 

Because I recently did work dealing with breaking up numbers, I will hint that to get specific numbers - which is what you will need with some of the other answers - think about integer division and using the modulus to get digits out of it.

If you had a smaller number, say 123, how would you get the 1, the 2, and the 3 out of it? Especially since you're working in base 10...

Austin Hyde
+2  A: 

You can compute the value of the number modulo 7.

That is, for each digit d and value n so far compute n = (10 * n + d) % 7.

This has the advantage of working independently of the divisor 7 or the base 10.

starblue
A: 

You can compute the value of the number modulo 7.

That is, for each digit d and value n so far compute n = (10 * n + d) % 7.

This has the advantage of working independently of the divisor 7 or the base 10.

I solved this problem exactly the same way on one of programming contests. Here is the fragment of code you need:

int sum = 0;
while (true) {
  char ch;
  cin>>ch;
  if (ch<'0' || ch>'9') break; // Reached the end of stdin
  sum = sum*10; // The previous sum we had must be multiplied
  sum += (int) ch;
  sum -= (int) '0'; // Remove the code to get the value of the digit
  sum %= 7; 
}

if (sum==0) cout<<"1";
else cout<<"0";

This code is working thanks to simple rules of modular arithmetics. It also works not just for 7, but for any divisor actually.

SPIRiT_1984