Mihai's page

Ramblings on a trivial math pattern

A week or so after publishing the previous article I observed an unexpected traffic pattern on my blog. I thought it was some new AI crawler and didn’t give it much thought. Until a few hours later when I actually looked from the logs and realized that the article somehow made its way to Hacker News.

After looking through the comments there, I realized that some are really useful. As discussed in the comments article, I extracted four of those comments and updated the \(\pi^2 \approx 10\) article. One of these four comments is the subject of today’s article.

987654321 / 123456789 = 8 (to the 7th decimal place)

No, I’m not going to say that it is 8. Instead, this comment reminded me of a different math meme that was going on the internet a few years ago:

A simple math pattern that has been used in various memes

Here, I will discuss the math pattern, excluding the Galileo quote that usually accompanies it.

We can quickly check that all the identities in the meme are true. But, there is nothing magic about it. We can try the same pattern in base 16, as the below Haskell example shows:

main = print $ and
  [               0x1 * 0xe + 0x1 == 0xf
  ,              0x12 * 0xe + 0x2 == 0xfe
  ,             0x123 * 0xe + 0x3 == 0xfed
  ,            0x1234 * 0xe + 0x4 == 0xfedc
  ,           0x12345 * 0xe + 0x5 == 0xfedcb
  ,          0x123456 * 0xe + 0x6 == 0xfedcba
  ,         0x1234567 * 0xe + 0x7 == 0xfedcba9
  ,        0x12345678 * 0xe + 0x8 == 0xfedcba98
  ,       0x123456789 * 0xe + 0x9 == 0xfedcba987
  ,      0x123456789a * 0xe + 0xa == 0xfedcba9876
  ,     0x123456789ab * 0xe + 0xb == 0xfedcba98765
  ,    0x123456789abc * 0xe + 0xc == 0xfedcba987654
  ,   0x123456789abcd * 0xe + 0xd == 0xfedcba9876543
  ,  0x123456789abcde * 0xe + 0xe == 0xfedcba98765432
  , 0x123456789abcdef * 0xe + 0xf == 0xfedcba987654321
  ]

Compiling and running it we see:

[...]$ ghc --make test.hs && ./test
[1 of 2] Compiling Main             ( test.hs, test.o )
[2 of 2] Linking test
True

So, there is nothing special about base 10 here. In fact, this pattern is valid in all bases.

Let’s assume base \(b\) and look at line \(k\) of the pattern. Looking at the pattern on each line, the right hand side is:

\[ S_R = \sum_{i=1}^{k}{(b-i)b^{k-i}} \]

while the left hand side is:

\[ S_L = \left(\sum_{i=1}^{k}{ib^{k-i}}\right)\left(b-2\right) + k \]

We see that we need to first compute \(S_1 = \sum_{i=1}^{k}{b^{k-i}}\) and \(S_2 = \sum_{i=1}^{k}{ib^{k-i}}\) because \(S_R = bS_1 - S_2\) and \(S_L = (b-2)S_2 + k\)

With a change of variables, the first intermediary sum is

\[ S_1 = \sum_{i=1}^{k}{b^{k-i}} = \sum_{j=0}^{k-1}{b^j} = \frac{b^k - 1}{b - 1} \]

If we differentiate with respect to \(b\) we get:

\[ S_1' = \sum_{j=1}^{k-1}{jb^{j-1}} = \frac{(k-1)b^k - kb^{k-1} + 1}{(b-1)^2} \]

We dropped the \(j=0\) term in the sum, as that does not contribute anything.

We now have a sum where we have the exponent in front of the term, but it does not yet follow the pattern needed for \(S_2\). Let’s do the same change of variables:

\[ S_2 = \sum_{i=1}^{k}{ib^{k-i}} = \sum_{j=0}^{k-1}{(k-j)b^j} = kS_1 - bS_1' = \frac{b^{k+1}-(k+1)b+k}{(b-1)^2} \]

With a little more algebra we get

\[ S_L = S_R = \frac{b^{k+2}-2b^{k+1}-b^2 + (k+2)b - k}{(b-1)^2} \]

Which proves that the identity is true, regardless of what base we pick.

As an exercise, try to prove the patterns captured by the following two Haskell expressions:

pattern_2 = and
  [               0x1 * 0xf + 0x2 == 0x11
  ,              0x12 * 0xf + 0x3 == 0x111
  ,             0x123 * 0xf + 0x4 == 0x1111
  ,            0x1234 * 0xf + 0x5 == 0x11111
  ,           0x12345 * 0xf + 0x6 == 0x111111
  ,          0x123456 * 0xf + 0x7 == 0x1111111
  ,         0x1234567 * 0xf + 0x8 == 0x11111111
  ,        0x12345678 * 0xf + 0x9 == 0x111111111
  ,       0x123456789 * 0xf + 0xa == 0x1111111111
  ,      0x123456789a * 0xf + 0xb == 0x11111111111
  ,     0x123456789ab * 0xf + 0xc == 0x111111111111
  ,    0x123456789abc * 0xf + 0xd == 0x1111111111111
  ,   0x123456789abcd * 0xf + 0xe == 0x11111111111111
  ,  0x123456789abcde * 0xf + 0xf == 0x111111111111111
  ]

pattern3 = and
  [               0xf * 0xf + 0xd == 0xee
  ,              0xfe * 0xf + 0xc == 0xeee
  ,             0xfed * 0xf + 0xb == 0xeeee
  ,            0xfedc * 0xf + 0xa == 0xeeeee
  ,           0xfedcb * 0xf + 0x9 == 0xeeeeee
  ,          0xfedcba * 0xf + 0x8 == 0xeeeeeee
  ,         0xfedcba9 * 0xf + 0x7 == 0xeeeeeeee
  ,        0xfedcba98 * 0xf + 0x6 == 0xeeeeeeeee
  ,       0xfedcba987 * 0xf + 0x5 == 0xeeeeeeeeee
  ,      0xfedcba9876 * 0xf + 0x4 == 0xeeeeeeeeeee
  ,     0xfedcba98765 * 0xf + 0x3 == 0xeeeeeeeeeeee
  ,    0xfedcba987654 * 0xf + 0x2 == 0xeeeeeeeeeeeee
  ,   0xfedcba9876543 * 0xf + 0x1 == 0xeeeeeeeeeeeeee
  ,  0xfedcba98765432 * 0xf + 0x0 == 0xeeeeeeeeeeeeeee
  ]

You won’t need more sums than the ones we already computed!


Comments:

There are 0 comments (add more):