I'm working on a system to replace numbers with letters for listings. I use 12 letters, such as ABCEHKMOPTXY
. So such a replacement needs to use duodecimal number format.
Here is the table for convertion results, that are needed:
1 – A
2 - B
3 - C
...
11 - X
12 - Y
13 - AA
14 - AB
...
48 - CY
49 - EA
...
156 - YY
157 - AAA
158 - AAB
I try to use the .toString(12)
to convert the number to a doudecimal and then replace each character in result with letters using switch - case
, but there are difficulties with round doudecimal numbers, such as results for 1884.
1883 - YYX
1884 - AYY **- WRONG! Has to be YYY**
1885 - AAAA
Here is my function, that works good for numbers till 1884, but I need more universal one. Please, help!
function numToString (num) {
var duodecimal = (+num).toString(12);
var numArray=duodecimal.split('');
var lttrs='';
for (var i=0; i<numArray.length; i++) {
switch (numArray[i]) {
case '1':
lttrs+='A'
break
case '2':
lttrs+='B'
break
case '3':
lttrs+='C'
break
case '4':
lttrs+='E'
break
case '5':
lttrs+='H'
break
case '6':
lttrs+='K'
break
case '7':
lttrs+='M'
break
case '8':
lttrs+='O'
break
case '9':
lttrs+='P'
break
case 'a':
lttrs+='T'
break
case 'b':
lttrs+='X'
break
case '0':
lttrs=lttrs.slice(0,-1);
switch (numArray[i-1]) {
case '1':
if (numArray[i-2]) {lttrs=lttrs.slice(0,-1); lttrs+='Y'}
break
case '2':
lttrs+='A'
break
case '3':
lttrs+='B'
break
case '4':
lttrs+='C'
break
case '5':
lttrs+='E'
break
case '6':
lttrs+='H'
break
case '7':
lttrs+='K'
break
case '8':
lttrs+='M'
break
case '9':
lttrs+='O'
break
case 'a':
lttrs+='P'
break
case 'b':
lttrs+='T'
break
case '0':
lttrs=lttrs.slice(0,-1);
lttrs+='X'
break
}
lttrs+='Y'
break
}
}
return lttrs;
}
I think I got it:
function n2s(n, digits) {
var s = '';
var l = digits.length;
while (n > 0) {
s = digits.charAt((n - 1) % l) + s;
n = Math.ceil(n / l) - 1;
}
return s;
}
A check in Chrome's console:
var i, letters = 'ABCEHKMOPTXY';
for (i = 1; i <= 25; i++) console.log(i, n2s(i, letters));
console.log(1884, n2s(1884, letters)); // 1884 "YYY"
console.log(1885, n2s(1885, letters)); // 1885 "AAAA"
Related stuffs: https://stackoverflow.com/a/30687539/1636522.
I'm a bit late though :-|
Reverse function
I have to admit that there is still a bit of magic for me as well, then I'm not sure to be able to give you a full explaination of what's happenning here :-D Anyway, as you requested, here is the reverse function:
function s2n(s, digits) {
var pow, n = 0, i = 0;
while (i++ < s.length) {
pow = Math.pow(digits.length, s.length - i);
n += (digits.indexOf(s.charAt(i - 1)) + 1) * pow;
}
return n;
}
Here is a use case by the way:
var letters = 'ABCEHKMOPTXY';
var from = s2n('YYT', letters);
var to = s2n('AAAC', letters);
for (var n = from; n <= to; n++) {
console.log(n, n2s(n, letters));
}
Under Chrome or Firefox:
You should see the following lines:
1882 "YYT"
1883 "YYX"
1884 "YYY"
1885 "AAAA"
1886 "AAAB"
1887 "AAAC"
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments