Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create a function that converts a Number to a Bijective Hexavigesimal?

Maybe i am just not that good enough in math, but I am having a problem in converting a number into pure alphabetical Bijective Hexavigesimal just like how Microsoft Excel/OpenOffice Calc do it.

Here is a version of my code but did not give me the output i needed:


    var toHexvg = function(a){
     var x='';
     var let="_abcdefghijklmnopqrstuvwxyz";
     var len=let.length;
     var b=a;
     var cnt=0;
     var y = Array();
     do{
      a=(a-(a%len))/len;
      cnt++;
     }while(a!=0)
     a=b;
     var vnt=0;
     do{
      b+=Math.pow((len),vnt)*Math.floor(a/Math.pow((len),vnt+1));
      vnt++;
     }while(vnt!=cnt)
     var c=b;
     do{
      y.unshift( c%len );
      c=(c-(c%len))/len;
     }while(c!=0)
     for(var i in y)x+=let[y[i]];
     return x;
    }

The best output of my efforts can get is: a b c d ... y z ba bb bc - though not the actual code above. The intended output is suppose to be a b c ... y z aa ab ac ... zz aaa aab aac ... zzzzz aaaaaa aaaaab, you get the picture.

Basically, my problem is more on doing the ''math'' rather than the function. Ultimately my question is: How to do the Math in Hexavigesimal conversion, till a [supposed] infinity, just like Microsoft Excel.

And if possible, a source code, thank you in advance.

like image 304
A. K. Tolentino Avatar asked Dec 22 '11 11:12

A. K. Tolentino


3 Answers

Okay, here's my attempt, assuming you want the sequence to be start with "a" (representing 0) and going:

a, b, c, ..., y, z, aa, ab, ac, ..., zy, zz, aaa, aab, ...

This works and hopefully makes some sense. The funky line is there because it mathematically makes more sense for 0 to be represented by the empty string and then "a" would be 1, etc.

alpha = "abcdefghijklmnopqrstuvwxyz";

function hex(a) {
  // First figure out how many digits there are.
  a += 1; // This line is funky
  c = 0;
  var x = 1;      
  while (a >= x) {
    c++;
    a -= x;
    x *= 26;
  }

  // Now you can do normal base conversion.
  var s = "";
  for (var i = 0; i < c; i++) {
    s = alpha.charAt(a % 26) + s;
    a = Math.floor(a/26);
  }

  return s;
}

However, if you're planning to simply print them out in order, there are far more efficient methods. For example, using recursion and/or prefixes and stuff.

like image 58
karnok Avatar answered Oct 01 '22 18:10

karnok


Although @user826788 has already posted a working code (which is even a third quicker), I'll post my own work, that I did before finding the posts here (as i didnt know the word "hexavigesimal"). However it also includes the function for the other way round. Note that I use a = 1 as I use it to convert the starting list element from

aa) first
ab) second

to

<ol type="a" start="27">
<li>first</li>
<li>second</li>
</ol>

:

function linum2int(input) {
    input = input.replace(/[^A-Za-z]/, '');
    output = 0;
    for (i = 0; i < input.length; i++) {
        output = output * 26 + parseInt(input.substr(i, 1), 26 + 10) - 9;
    }
    console.log('linum', output);
    return output;
}

function int2linum(input) {

    var zeros = 0;
    var next = input;
    var generation = 0;
    while (next >= 27) {
        next = (next - 1) / 26 - (next - 1) % 26 / 26;
        zeros += next * Math.pow(27, generation);
        generation++;
    }
    output = (input + zeros).toString(27).replace(/./g, function ($0) {
        return '_abcdefghijklmnopqrstuvwxyz'.charAt(parseInt($0, 27));
    });
    return output;
}

linum2int("aa"); // 27
int2linum(27); // "aa"
like image 38
jakov Avatar answered Oct 01 '22 17:10

jakov


You could accomplish this with recursion, like this:

const toBijective = n => (n > 26 ? toBijective(Math.floor((n - 1) / 26)) : "") + ((n % 26 || 26) + 9).toString(36);
// Parsing is not recursive
const parseBijective = str => str.split("").reverse().reduce((acc, x, i) => acc + ((parseInt(x, 36) - 9) * (26 ** i)), 0);

toBijective(1) // "a"
toBijective(27) // "aa"
toBijective(703) // "aaa"
toBijective(18279) // "aaaa"
toBijective(127341046141) // "overflow"

parseBijective("Overflow") // 127341046141
like image 21
A1rPun Avatar answered Oct 01 '22 17:10

A1rPun