blog-static/content/blog/modulo_patterns/index.md

16 KiB

title date tags draft
Digit Sum Patterns and Modular Arithmetic 2021-12-30T15:42:40-08:00
Ruby
Mathematics
true

When I was in elementary school, our class was briefly visited by our school's headmaster. He was there for a demonstration, probably intended to get us to practice our multiplication tables. "Pick a number", he said, "And I'll teach you how to draw a pattern from it."

The procedure was rather simple:

  1. Pick a number between 2 and 8 (inclusive).
  2. Start generating multiples of this number. If you picked 8, your multiples would be 8, 16, 24, and so on.
  3. If a multiple is more than one digit long, sum its digits. For instance, for 16, write 1+6=7. If the digits add up to a number that's still more than 1 digit long, add up the digits of that number (and so on).
  4. Start drawing on a grid. For each resulting number, draw that many squares in one direction, and then "turn". Using 8 as our example, we could draw 8 up, 7 to the right, 6 down, 5 to the left, and so on.
  5. As soon as you come back to where you started ("And that will always happen", said my headmaster), you're done. You should have drawn a pretty pattern!

Sticking with our example of 8, the pattern you'd end up with would be something like this:

{{< figure src="pattern_8.svg" caption="Pattern generated by the number 8." class="tiny" alt="Pattern generated by the number 8." >}}

Before we go any further, let's observe that it's not too hard to write code to do this. For instance, the "add digits" algorithm can be naively written by turning the number into a string (17 becomes "17"), splitting that string into characters ("17" becomes ["1", "7"]), turning each of these character back into numbers (the array becomes [1, 7]) and then computing the sum of the array, leaving 8.

{{< codelines "Ruby" "patterns/patterns.rb" 3 8 >}}

We may now encode the "drawing" logic. At any point, there's a "direction" we're going - which I'll denote by the Ruby symbols :top, :bottom, :left, and :right. Each step, we take the current x/y coordinates (our position on the grid), and shift them by n in a particular direction dir. We also return the new direction alongside the new coordinates.

{{< codelines "Ruby" "patterns/patterns.rb" 10 21 >}}

The top-level algorithm is captured by the following code, which produces a list of coordinates in the order that you'd visit them.

{{< codelines "Ruby" "patterns/patterns.rb" 23 35 >}}

I will omit the code for generating SVGs from the body of the article -- you can always find the complete source code in this blog's Git repo (or by clicking the link in the code block above). Let's run the code on a few other numbers. Here's one for 4, for instance:

{{< figure src="pattern_4.svg" caption="Pattern generated by the number 4." class="tiny" alt="Pattern generated by the number 4." >}}

And one more for 2, which I don't find as pretty.

{{< figure src="pattern_2.svg" caption="Pattern generated by the number 2." class="tiny" alt="Pattern generated by the number 2." >}}

It really does always work out! Young me was amazed, though I would often run out of space on my grid paper to complete the pattern, or miscount the length of my lines partway in. It was only recently that I started thinking about why it works, and I think I figured it out. Let's take a look!

Is a number divisible by 3?

You might find the whole "add up the digits of a number" thing familiar, and for good reason: it's one way to check if a number is divisible by 3. The quick summary of this result is,

If the sum of the digits of a number is divisible by 3, then so is the whole number.

For example, the sum of the digits of 72 is 9, which is divisible by 3; 72 itself is correspondingly also divisible by 3, since 24*3=72. On the other hand, the sum of the digits of 82 is 10, which is not divisible by 3; 82 isn't divisible by 3 either (it's one more than 81, which is divisible by 3).

Why does this work? Let's talk remainders.

If a number doesn't cleanly divide another (we're sticking to integers here), what's left behind is the remainder. For instance, dividing 7 by 3 leaves us with a remainder 1. On the other hand, if the remainder is zero, then that means that our dividend is divisible by the divisor (what a mouthful). In mathematics, we typically use \(a|b\) to say \(a\) divides \(b\), or, as we have seen above, that the remainder of dividing \(b\) by \(a\) is zero.

Working with remainders actually comes up pretty commonly in discrete math. A well-known example I'm aware of is the RSA algorithm, which works with remainders resulting from dividing by a product of two large prime numbers. But what's a good way to write, in numbers and symbols, the claim that "\(a\) divides \(b\) with remainder \(r\)"? Well, we know that dividing yields a quotient (possibly zero) and a remainder (also possibly zero). Let's call the quotient \(k\). {{< sidenote "right" "r-less-note" "Then, we know that when dividing b by a we have:" >}} It's important to point out that for the equation in question to represent division with quotient k and remainder r, it must be that r is less than a. Otherwise, you could write r = s + a for some s, and end up with {{< latex >}} \begin{aligned} & b = ka + r \ \Rightarrow\ & b = ka + (s + a) \ \Rightarrow\ & b = (k+1)a + s \end{aligned} {{< /latex >}}

In plain English, if r is bigger than a after you've divided, you haven't taken out "as much a from your dividend as you could", and the actual quotient is larger than k. {{< /sidenote >}}

{{< latex >}} \begin{aligned} & b = ka + r \ \Rightarrow\ & b-r = ka \ \end{aligned} {{< /latex >}}

We only really care about the remainder here, not the quotient, since it's the remainder that determines if something is divisible or not. From the form of the second equation, we can deduce that \(b-r\) is divisible by \(a\) (it's literally equal to \(a\) times \(k\), so it must be divisible). Thus, we can write:

{{< latex >}} (b-r)|a {{< /latex >}}

There's another notation for this type of statement, though. To say that the difference between two numbers is divisible by a third number, we write:

{{< latex >}} b \equiv r\ (\text{mod}\ a) {{< /latex >}}

Some things that seem like they would work from this "equation-like" notation do, indeed, work. For instance, we can "add two equations":

{{< latex >}} \textbf{if}\ a \equiv b\ (\text{mod}\ k)\ \textbf{and}\ c \equiv d, (\text{mod}\ k),\ \textbf{then}\ a+c \equiv b+d\ (\text{mod}\ k). {{< /latex >}} Multiplying both sides by the same number (call it \(n\)) also works:

{{< latex >}} \textbf{if}\ a \equiv b\ (\text{mod}\ k),\ \textbf{then}\ na \equiv nb\ (\text{mod}\ k). {{< /latex >}}

Ok, that's a lot of notation and other stuff. Let's talk specifics. Of particular interest is the number 10, since our number system is base ten (the value of a digit is multiplied by 10 for every place it moves to the left). The remainder of 10 when dividing by 3 is 1. Thus, we have:

{{< latex >}} 10 \equiv 1\ (\text{mod}\ 3) {{< /latex >}}

From this, we can deduce that multiplying by 10, when it comes to remainders from dividing by 3, is the same as multiplying by 1. We can clearly see this by multiplying both sides by \(n\). In our notation:

{{< latex >}} 10n \equiv n\ (\text{mod}\ 3) {{< /latex >}}

But wait, there's more. Take any power of ten, be it a hundred, a thousand, or a million. Multiplying by that number is also equivalent to multiplying by 1!

{{< latex >}} 10^kn = 10\times10\times...\times 10n \equiv n\ (\text{mod}\ 3) {{< /latex >}}

We can put this to good use. Let's take a large number that's divisible by 3. This number will be made of multiple digits, like \(d_2d_1d_0\). Note that I do not mean multiplication here, but specifically that each \(d_i\) is a number between 0 and 9 in a particular place in the number -- it's a digit. Now, we can write:

{{< latex >}} \begin{aligned} 0 &\equiv d_2d_1d_0 \ & = 100d_2 + 10d_1 + d_0 \ & \equiv d_2 + d_1 + d_0 \end{aligned} {{< /latex >}}

We have just found that \(d_2+d_1+d_0 \equiv 0\ (\text{mod}\ 3)\), or that the sum of the digits is also divisible by 3. The logic we use works in the other direction, too: if the sum of the digits is divisible, then so is the actual number.

There's only one property of the number 3 we used for this reasoning: that \(10 \equiv 1\ (\text{mod}\ 3)\). But it so happens that there's another number that has this property: 9. This means that to check if a number is divisible by nine, we can also check if the sum of the digits is divisible by 9. Try it on 18, 27, 81, and 198.

Here's the main takeaway: summing the digits in the way described by my headmaster is the same as figuring out the remainder of the number from dividing by 9. Well, almost. The difference is the case of 9 itself: the remainder here is 0, but we actually use 9 to draw our line. We can actually try just using 0. Here's the updated sum_digits code:

def sum_digits(n)
    n % 9
end

The results are similarly cool:

{{< figure src="pattern_8_mod.svg" caption="Pattern generated by the number 8." class="tiny" alt="Pattern generated by the number 8 by just using remainders." >}} {{< figure src="pattern_4_mod.svg" caption="Pattern generated by the number 4." class="tiny" alt="Pattern generated by the number 4 by just using remainders." >}} {{< figure src="pattern_2_mod.svg" caption="Pattern generated by the number 2." class="tiny" alt="Pattern generated by the number 2 by just using remainders." >}}

Sequences of Remainders

So now we know what the digit-summing algorithm is really doing. But that algorithm isn't all there is to it! We're repeatedly applying this algorithm over and over to multiples of another number. How does this work, and why does it always loop around? Why don't we ever spiral further and further from the center?

First, let's take a closer look at our sequence of multiples. Suppose we're working with multiples of some number \(n\). Let's write \(a_i\) for the \(i\)th multiple. Then, we end up with:

{{< latex >}} \begin{aligned} a_1 &= n \ a_2 &= 2n \ a_3 &= 3n \ a_4 &= 4n \ ... \ a_i &= in \end{aligned} {{< /latex >}}

This is actually called an arithmetic sequence; for each multiple, the number increases by \(n\).

Here's a first seemingly trivial point: at some time, the remainder of \(a_i\) will repeat. There are only so many remainders when dividing by nine: specifically, the only possible remainders are the numbers 0 through 8. We can invoke the pigeonhole principle and say that after 9 multiples, we will have to have looped. Another way of seeing this is as follows:

{{< latex >}} \begin{aligned} & 9 \equiv 0\ (\text{mod}\ 9) \ \Rightarrow\ & 9n \equiv 0\ (\text{mod}\ 9) \ \Rightarrow\ & 10n \equiv n\ (\text{mod}\ 9) \ \end{aligned} {{< /latex >}}

The 10th multiple is equivalent to n, and will thus have the same remainder. The looping may happen earlier: the simplest case is if we pick 9 as our \(n\), in which case the remainder will always be 0.

Repeating remainders alone do not guarantee that we will return to the center. The repeating sequence 1,2,3,4 will certainly cause a spiral. The reason is that, if we start facing "up", we will always move up 1 and down 3 after four steps, leaving us 2 steps below where we started. Next, the cycle will repeat, and since turning four times leaves us facing "up" again, we'll end up getting further down.

From this, we can devise a simple condition to prevent spiraling -- the length of the sequence before it repeats cannot be a multiple of 4. This way, whenever the cycle restarts, it will do so in a different direction: backwards, turned once to the left, or turned once to the right. Clearly repeating the sequence backwards is guaranteed to take us back to the start. The same is true for the left and right-turn sequences, since after two iterations they will also leave us facing backwards.

Okay, so we want to avoid cycles with lengths divisible by four. What does it mean for a cycle to be of length k? It effectively means the following:

{{< latex >}} \begin{aligned} & a_{k+1} \equiv a_1\ (\text{mod}\ 9) \ \Rightarrow\ & (k+1)n \equiv n\ (\text{mod}\ 9) \ \Rightarrow\ & kn \equiv 0\ (\text{mod}\ 9) \ \end{aligned} {{< /latex >}}

If we could divide both sides by \(k\), we could go one more step:

{{< latex >}} n \equiv 0\ (\text{mod}\ 9) \ {{< /latex >}}

That is, \(n\) would be divisible by 9! This would contradict our choice of \(n\) to be between 2 and 8. What went wrong? Turns out, it's that last step: we can't always divide by \(k\). Some values of \(k\) are special, and it's only those values that can serve as cycle lengths without causing a contradiction. So, what are they?

They're values that have a common factor with 9. There are many numbers that have a common factor with 9; 3, 6, 9, 12, and so on. However, those can't all serve as cycle lengths: as we said, cycles can't get longer than 9. This leaves us with 3, 6, and 9 as possible cycle lengths, none of which are divisible by 4. We've eliminated the possibility of spirals!

{{< todo >}} This doesn't get to the bottom of it all. {{< /todo >}}

Generalizing to Arbitrary Divisors

The trick was easily executable on paper because there's an easy way to compute the remainder of a number when dividing by 9 (adding up the digits). However, we have a computer, and we don't need to fall back on such cool-but-complicated techniques. To replicate our original behavior, we can just write:

def sum_digits(n)
  x = n % 9
  x == 0 ? 9 : x
end

But now, we can change the 9 to something else. Any number we pick, so long as it isn't {{< sidenote "right" "div-4-note" "divisible by 4," >}} "Wait", you might be thinking, "I thought you said that 4 can't have a common factor with the divisor, and that means any even numbers are out, too."

Good observation. Although the path-not-divisible-by-four condition is certainly sufficient, it is not necessary. There seems to be another, less restrictive, condition at play here: even numbers work fine. I haven't figured out what it is, but we might as well make use of it. {{< /sidenote >}} will work. I'll pick primes for good measure. Here are a few good ones from using 13 (which corresponds to summing digits of base-14 numbers):

{{< figure src="pattern_8_13.svg" caption="Pattern generated by the number 8 in base 14." class="tiny" alt="Pattern generated by the number 8 by summing digits." >}} {{< figure src="pattern_4_13.svg" caption="Pattern generated by the number 4 in base 14." class="tiny" alt="Pattern generated by the number 4 by summing digits." >}}

Here are a few from dividing by 17 (base-18 numbers).

{{< figure src="pattern_5_17.svg" caption="Pattern generated by the number 5 in base 18." class="tiny" alt="Pattern generated by the number 5 by summing digits." >}}

Finally, base-30:

{{< figure src="pattern_2_29.svg" caption="Pattern generated by the number 2 in base 30." class="tiny" alt="Pattern generated by the number 2 by summing digits." >}}

{{< figure src="pattern_6_29.svg" caption="Pattern generated by the number 6 in base 30." class="tiny" alt="Pattern generated by the number 6 by summing digits." >}}