1

Consider Microsoft Excel's column-numbering system. Columns are "numbered" A, B, C, ... , Y, Z, AA, AB, AC, ... where A is 1.

The column system is similar to the base-10 numbering system that we're familiar with in that when any digit has its maximum value and is incremented, its value is set to the lowest possible digit value and the digit to its left is incremented, or a new digit is added at the minimum value. The difference is that there isn't a digit that represents zero in the letter numbering system. So if the "digit alphabet" contained ABC or 123, we could count like this:

(base 3 with zeros added for comparison)

base 3 no 0    base 3 with 0    base 10 with 0
-----------    -------------    --------------
  -      -            0               0
  A      1            1               1
  B      2            2               2
  C      3           10               3
 AA     11           11               4
 AB     12           12               5
 AC     13           20               6
 BA     21           21               7
 BB     22           22               8
 BC     23          100               9
 CA     31          101              10
 CB     32          102              11
 CC     33          110              12
AAA    111          111              13

Converting from the zeroless system to our base 10 system is fairly simple; it's still a matter of multiplying the power of that space by the value in that space and adding it to the total. So in the case of AAA with the alphabet ABC, it's equivalent to (1*3^2) + (1*3^1) + (1*3^0) = 9 + 3 + 1 = 13.

I'm having trouble converting inversely, though. With a zero-based system, you can use a greedy algorithm moving from largest to smallest digit and grabbing whatever fits. This will not work for a zeroless system, however. For example, converting the base-10 number 10 to the base-3 zeroless system: Though 9 (the third digit slot: 3^2) would fit into 10, this would leave no possible configuration of the final two digits since their minimum values are 1*3^1 = 3 and 1*3^0 = 1 respectively.

Realistically, my digit alphabet will contain A-Z, so I'm looking for a quick, generalized conversion method that can do this without trial and error or counting up from zero.

Edit

The accepted answer by n.m. is primarily a string-manipulation-based solution. For a purely mathematical solution see kennytm's links:

Community
  • 1
  • 1
Taylor Lopez
  • 813
  • 1
  • 8
  • 28
  • I'm having trouble following all of your explanations, but isn't this just equivalent to a base-3 system, plus 1? To go from base-10-with-0 to base-3-without-0, would it not work to add 1, convert first to base-3-with-zero, and subtract 1? Or something like that. I've got a nasty head cold right now and my thoughts are not so clear. xP – B. Eckles Oct 31 '16 at 15:44
  • Maybe one thing I'm missing-- are you saying that you're excluding numbers with zero in them from being representable? – B. Eckles Oct 31 '16 at 15:45
  • @B.Eckles No, The system simply has no zero digit. so instead of 0, 1, 2, it has 1, 2, 3 in each digit position. – Taylor Lopez Oct 31 '16 at 15:46
  • 2
    Excel to number: http://stackoverflow.com/questions/667802/what-is-the-algorithm-to-convert-an-excel-column-letter-into-its-number?noredirect=1&lq=1; Number to Excel: http://stackoverflow.com/questions/181596/how-to-convert-a-column-number-eg-127-into-an-excel-column-eg-aa – kennytm Oct 31 '16 at 15:47
  • could you add a clause along the lines of `if (number.ToString()[number.ToString().length-1] == '0'){number++;}` to totally skip anything ending in 0? It's not elegant, but I don't see why it wouldn't work – ScottishTapWater Oct 31 '16 at 15:47
  • @kennytm This example shows from the column name to the number representation, which I get. I want to go in the reverse: converting to the number to the "column name" – Taylor Lopez Oct 31 '16 at 15:51
  • 2
    @TaylorLopez: That's the second link in the comment... – kennytm Oct 31 '16 at 15:51
  • @kennytm Ah! So it is #embarass – Taylor Lopez Oct 31 '16 at 15:57

1 Answers1

4

Convert to base-3-with-zeroes first (digits 0AB), and from there, convert to base-3-without-zeroes (ABC), using these string substitutions:

   A0  =>  0C
   B0  =>  AC
   C0  =>  BC

Each substitution either removes a zero, or pushes one to the left. In the end, discard leading zeroes.

It is also possible, as an optimisation, to process longer strings of zeros at once:

A000...000 = 0BBB...BBC
B000...000 = ABBB...BBC
C000...000 = BBBB...BBC

Generalizable to any base.

n. m. could be an AI
  • 112,515
  • 14
  • 128
  • 243
  • I really like this solution because it's clever, and it's strictly based on the string patters. It's probably still a _little_ less efficient than the Excel link above since this would require you to make several passes, and gets more complicated the larger your alphabet is (if it's a true string replacement), but I like it nonetheless. – Taylor Lopez Oct 31 '16 at 16:23
  • No, one pass is enough. It's basically "replace 0 wirh C and subtract 1 from the digit on the left". If that digit is 0 again, you reolace it with B and subtract 1 from the next one on the left, etc. So you make one right to left pass. – n. m. could be an AI Oct 31 '16 at 16:27
  • Ah I see. I misunderstood. – Taylor Lopez Oct 31 '16 at 16:28