using System;
class Program
{
static void Main(string[] args)
{
var rnd = new Random();
for (int i = 0; i < 10; i++)
{
int x = rnd.Next(10000);
string encoded = AbcNotation.Encode(x);
int decoded = AbcNotation.Decode(encoded);
Console.WriteLine("{0} -> {1} -> {2}", x, encoded, decoded);
}
}
}
public static class AbcNotation
{
public const int AlphabetsCount = 26;
// A -> 1, AA -> 27, AAA -> 703, .....
private static int DecodeRepeatedA(int digits)
{
return digits == 1 ? 1 : (int)Math.Pow(26, digits - 1) + DecodeRepeatedA(digits - 1);
}
// decode "ABC" as simple 26-adic encoded.
private static int DecodeAs26Adic(string se)
{
int msd = AtoI(se[0]);
int power = (int)Math.Pow(AlphabetsCount, se.Length - 1);
return se.Length == 1 ? msd : msd * power + DecodeAs26Adic(se.Substring(1));
}
public static int Decode(string abc)
{
return DecodeRepeatedA(abc.Length) + DecodeAs26Adic(abc);
}
// Encode to Simple 26-adic notaion using A to Z.
private static string EncodeAs26Adic(int x, int digits)
{
int power = (int)Math.Pow(AlphabetsCount, digits - 1);
int msd = x / power;
int remainder = x - power * msd;
return digits == 1 ? ItoA(x).ToString() : ItoA(msd) + EncodeAs26Adic(remainder, digits - 1);
}
public static string Encode(int x)
{
int digits = GetEncodedLength(x);
return EncodeAs26Adic(x - DecodeRepeatedA(digits), digits);
}
// Return length of ABC encoded string.
private static int GetEncodedLength(int x)
{
for (int i = 2; ; i++) if (x < DecodeRepeatedA(i)) return i - 1;
}
private static int AtoI(char c)
{
return c - 'A';
}
private static char ItoA(int figure)
{
return (char)('A' + figure);
}
}