Search code examples
javascriptstringnumbersbijection

Return a unique and sorted string from number


I have an input which is a number of base 10: 1, 2, 3, 52, 53 ...

I would like to convert the number to a string built with the letters a to z. For each number there should be only one letter combination and they should be sorted alphabetically.

0 => A
1 => B
2 => C
26 => AA
27 => AB
52 => BA
53 => BB
...

At the moment I build this snippet:

var possibleIndexes = "abcdefghijklmnopqrstuvwxyz".split("");
var result = '';
var index10 = 52;
var index26 = (index10).toString(26);

for (var i = 0; i < index26.length ; i++) {
    result += possibleIndexes[(parseInt(index26[i], 26)) % 26];
}

console.log(result);

It's not so far from the correct answer but it's still wrong.

What would be the correct form of the function?


Solution

  • I generalized the solution and I provided some data for test:

    function f(xx) {
        var v = "abcdefghijklmnopqrstuvwxyz".split("");
        var result = '';
        var nr = Math.floor(xx/26);
        var mod = xx%26;
    
        for ( var j = 1, jj = 1 ; j <= nr ; j=Math.pow(26,jj)+1, jj++ ) {
            result += v[(nr-1)%26];
        }
    
        result += v[mod];
    
        return result;
    }
    
    /* USEFUL FOR TESTS */
    var arr = [0, 1, 25, 26, 52, 53, 701, 702, 17601, 17602, 457001, 457002];
    var expected = ['a','b','z','aa', 'ba', 'bb', 'zz', 'aaa', 'zzz', 'aaaa', 'zzzz', 'aaaaa'];
    for ( var k = 0 ; k < arr.length ; k++ ) {
        console.log(arr[k] + " --> " + f(arr[k]) + "-->" + expected[k]);
    }
    

    Idea:

    Take into account that the number of possible solutions grow exponentially related to the length of the output string:

     - A-Z            +26^1            1-26
     - AA-ZZ          +26^2            27-702
     - AAA-ZZZ        +26^3            703-17602
     - AAAA-ZZZZ      +26^4            17603-457002
     ...
    

    Details:

    mod keeps the latest character for the output string

    j grows exponentially ( 26^0, 26^1, 26^2 ... ) and it assures that result will have the suitable number of characters:

    26^1+1 - 26^2   -> add one letter
    26^2+1 - 26^3   -> add another letter
    ...
    

    jj is used only as an exponent ( 1 - 26^1, 2 - 26^2, 3 - 26^3, ... )