Live data from Hacker News

Divisibility by 7 is a Walk on a Graph - how does it work?

blog.tanyakhovanova.com

11–19 of 19 posts

Re: Divisibility by 7 is a Walk on a Graph - how does it work?

#11
post #4

This graph is just deterministic finite automaton[1] with some fancy rules to make it easier to remember and to draw less arrows. What this proves is that that when you look at natural numbers as a words over {0, 1, ..., 9} alphabet, numbers divisible by 7 form a regular language[2]. This method generalizes to divisiblity by any number, not just 7, though it requires some cunning to come up with a nice way of represe…

http://codegolf.stackexchange.com/questions/3503/hard-code-g...

Re: Divisibility by 7 is a Walk on a Graph - how does it work?

#12
post #7
post #4

This graph is just deterministic finite automaton[1] with some fancy rules to make it easier to remember and to draw less arrows. What this proves is that that when you look at natural numbers as a words over {0, 1, ..., 9} alphabet, numbers divisible by 7 form a regular language[2]. This method generalizes to divisiblity by any number, not just 7, though it requires some cunning to come up with a nice way of represe…

Great comment. Am I the only person waiting for someone to provide the regular expression intimated at above?

If you want regular expressions for divisibility, here’s the little toy I made last time this came up on HN: http://s3.boskent.com/divisibility-regex/divisibility-regex....

You can do any number in any base up to 36 (subject to limitations of patience and available RAM, naturally).

The resulting regular expressions are not terribly friendly. You have to remember that converting a DFA to a regex can lead to exponential blow-up in size.

Re: Divisibility by 7 is a Walk on a Graph - how does it work?

#13
post #7
post #4

This graph is just deterministic finite automaton[1] with some fancy rules to make it easier to remember and to draw less arrows. What this proves is that that when you look at natural numbers as a words over {0, 1, ..., 9} alphabet, numbers divisible by 7 form a regular language[2]. This method generalizes to divisiblity by any number, not just 7, though it requires some cunning to come up with a nice way of represe…

Great comment. Am I the only person waiting for someone to provide the regular expression intimated at above?

I wouldn't want to actually compute it, but here's one way you can do it:

Let R_i be an unknown regexp that matches base 10 expansion of numbers with residue i mod 7 (for simplicity, include the empty string --representing 0-- in the strings matched for R_0). We want R_0 and will get it from a system of equations for R_0, ..., R_6.

The key is that any string matched by, say (R_j)k is a number congruent to 10j+k mod 7, so we get the equation R_i = sum( R_j k ) + delta_i0 where

* the sum means union, i.e., operator | for regexes, and is taken over all 0* delta_i0 is a term which is not there unless i=0 in which case it is equal to epsilon, (the language consisting solely of) the empty string.

You solve such a system by solving for one unknown at a time and substituting. An equation of the form R = RD | A, where R is one of the unknowns, and does not appear in either D or A, has solution R = AD*. You take that solution and plug it into all other equations, and repeat until you just get an equation for R_0. It's solution is the regex you want (except maybe you didn't want it to also match the empty string). Obviously this should not be done by hand.

Re: Divisibility by 7 is a Walk on a Graph - how does it work?

#14
post #7
post #4

This graph is just deterministic finite automaton[1] with some fancy rules to make it easier to remember and to draw less arrows. What this proves is that that when you look at natural numbers as a words over {0, 1, ..., 9} alphabet, numbers divisible by 7 form a regular language[2]. This method generalizes to divisiblity by any number, not just 7, though it requires some cunning to come up with a nice way of represe…

Great comment. Am I the only person waiting for someone to provide the regular expression intimated at above?

[deleted]

Re: Divisibility by 7 is a Walk on a Graph - how does it work?

#16
post #3

Divisibility by any n is a walk on a graph with n nodes, each one representing one of the modulus equivalence classes 0 .. n-1.

And there are graphs going either way, either starting from most or least significant digit. (Take previous modulus, *10 mod N, + next digit mod N), or (Take previous modulus, + 10^(next digit) mod N)

In the case of least significant to most significant, that means you need more nodes, because the position of the current digit is another piece of state you also have to keep track of.

Re: Divisibility by 7 is a Walk on a Graph - how does it work?

#17
post #5

jowair already said this [1], but here's a less concise explanation: The black arrows implement the operation of adding one mod 7, the white arrows implement the operation of multiplying by ten mod 7. The decimal expansion of a number tells you how to build it out of the operations of adding 1 and multiplying by 10, for example, to get 321, start at 0 and then do the operations +1, +1, +1, x10, +1, +1, x10, +1. Of co…

A quicker mnemonic for me is that the white arrows are multiplying by 3 mod 7, which is an equivalent operation to multiplying by 10 mod 7.

Re: Divisibility by 7 is a Walk on a Graph - how does it work?

#18
I've been waiting decades for anyone to be interested in a divisible-by-7 test that works right-to-left. Only 7 states required:

  #include 

  int x[7][10] = {
    /* 0 */ {0, 2, 4, 6, 1, 3, 5, 0, 2, 4},
    /* 1 */ {5, 0, 2, 4, 6, 1, 3, 5, 0, 2},
    /* 2 */ {3, 5, 0, 2, 4, 6, 1, 3, 5, 0},
    /* 3 */ {1, 3, 5, 0, 2, 4, 6, 1, 3, 5},
    /* 4 */ {6, 1, 3, 5, 0, 2, 4, 6, 1, 3},
    /* 5 */ {4, 6, 1, 3, 5, 0, 2, 4, 6, 1},
    /* 6 */ {2, 4, 6, 1, 3, 5, 0, 2, 4, 6}
  };

  int divisible_by_7(char *b)
  {
    char *p = b; while (*p) p++; // skip to NUL
    int state = 0;
    while (--p >= b)
      state = x[state][*p-'0'];
    return !state;
  }

  int main(int argc, char *argv[])
  {
    int i;
    for (i = 1; i

Re: Divisibility by 7 is a Walk on a Graph - how does it work?

#19
post #3

Earlier quoted context omitted.

And there are graphs going either way, either starting from most or least significant digit. (Take previous modulus, *10 mod N, + next digit mod N), or (Take previous modulus, + 10^(next digit) mod N)

In the case of least significant to most significant, that means you need more nodes, because the position of the current digit is another piece of state you also have to keep track of.

Yes - you need to work powers of 10 modulo the divisor as well.
Post reply on HN