I took this picture while driving, much to the panicked screams of my passengers. What they couldn’t see, and I had very little time to capture, was that the odometer was displaying a very curious number, namely “122551”. It may not be obvious in the font being used here, but on my dashboard, rendered in seven-segment LED numbers, it exhibited perfect mirror symmetry. These kinds of numbers are related to palindromic numbers (which I explored earlier this year), but are just a little bit more odd because they rely on how the numbers are represented visually.

The question I began to think about was something like: “How many times will the odometer of my car display a number that contains it’s own reflection?” In this strange kind of numerical analysis, some numbers will never show up (3, 4, 6, 7, and 9), some exhibit self mirror-symmetry by the nature of being symmetrical about the vertical axis (0, 1, 8) and then 2 and 5 are a reflective pair. What that means is that any time a 2 or a 5 shows up, there must a corresponding opposite 5 or 2. For the record, 9 and 6 don’t count because they are rotations not reflections. So how is this essentially arbitrary property distributed along the number line?

To examine a few million integers efficiently, I would have to create an efficient way to check a number for mirror symmetry (in python). I decided to treat all mirror-able numbers as if they have a mirror pair the way 5 and 2 do — this simplifies the comparison step. For odd length numbers, I check for self-symmetry on the central digit.

SymPairs = {'0':'0', '1':'1', '2':'5', '5':'2', '8':'8'} SymMonads = ['0', '1', '8'] def sym_check(v): l = len(v) match_count = 0 for i in range(l/2): target = v[i] if not target in SymPairs: continue match = SymPairs[target] if v[l-1-i] == match: match_count += 2 if l & 0x1: # odd length # check center digit if v[l/2] in SymMonads: match_count += 1 rval = 0.0 if match_count > 0: rval = match_count / float(l) if rval == 1.0: print v return rval

Armed with a function that returns 1.0 for fully mirror-palindrome numbers, I checked to see how many there were between 0 and 100,000:

0 15821 1 18081 8 18181 11 18881 25 20005 52 20105 88 20805 101 21015 111 21115 181 21815 205 22055 215 22155 285 22855 502 25025 512 25125 582 25825 808 28085 818 28185 888 28885 1001 50002 1111 50102 1251 50802 1521 51012 1881 51112 2005 51812 2115 52052 2255 52152 2525 52852 2885 55022 5002 55122 5112 55822 5252 58082 5522 58182 5882 58882 8008 80008 8118 80108 8258 80808 8528 81018 8888 81118 10001 81818 10101 82058 10801 82158 11011 82858 11111 85028 11811 85128 12051 85828 12151 88088 12851 88188 15021 88888 15121

The great thing about this function is that it returns 1.0 for a perfect mirror-symmetry number, and something less than that for something that exhibits some symmetry. So we can visualize that as grey scale in an image. Here’s the corner of an image that contains a rendering of all the numbers from 0 to 1,000,000. In the upper left corner is 0 with the pixels representing 0, 1, 2, 3, 4 and so on moving to the right. Pixels 0, 1, and 8, are bright green because they are self-mirroring. Checking the list above, we see pixels representing 11, 25, 52, and 88 lit up as well. In this rendering, grey pixels are kind of symmetrical, and black pixels exhibit no symmetry (according to how the code is testing for it).

That pattern of rectangles continues, with an evolving variation, from there on out. Viewed as a graph, you can see the gaps between fairly evenly distributed ranges more clearly.

Start looking for patterns in numbers, and you will find them. This is also true for all endeavors, mathematical or otherwise.