Recreate Number.toString(nn) in pure javascript - javascript

I'm trying convert a number into string using nn base. Basically, trying re-create Number.toString(nn)
Here is the code I have so far which produces incorrect result:
const baseData = "0123456789abcdef";
for(let i = 0; i < 257; i += 8)
{
console.log(i, "expected:", i.toString(16), "| actual:", toBase(i, 16));
}
function toBase(n, radix)
{
let result = "";
const count = ~~(n / radix);
for(let i = 0; i < count; i++)
{
result += baseData[~~(i % radix)];
}
result += baseData[~~(n % radix)];
return result;
}
.as-console-wrapper{top:0;max-height:unset!important;overflow:auto!important;}
There must be some kind of formula for this...
Any suggestions?

const baseData = "0123456789abcdef";
for(let i = 0; i < 257; i += 8)
{
console.log(i, "expected:", i.toString(16), "| actual:", toBase(i, 16));
}
function toBase(n, radix)
{
let result = "";
while(n>0){
result = baseData[n % radix]+result;
n=(n - n % radix)/radix;
}
return result;
}

const baseData = "0123456789abcdef";
for (let i = 0; i < 257; i += 8) {
console.log(i, "expected:", i.toString(16), "| actual:", toBase(i, 16));
}
function toBase(n, radix) {
if (n === 0) return 0
const chars = '0123456789abcdef'
const result = []
while (n > 0) {
const mod = n % radix
result.unshift(chars[mod])
n = Math.floor(n / radix)
}
return result.join('')
}
.as-console-wrapper {
top: 0;
max-height: unset!important;
overflow: auto!important;
}

Just in case someone is looking for the encoding/decoding solution:
const numBase = (() =>
{
//base65
let baseData = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY=+/-";
return {
get base() {return baseData;},
set base(data) {baseData = data;},
to: (num, radix = baseData.length) =>
{
let result = "";
for(; num > 0; num = ~~(num / radix))
result = baseData[num % radix] + result;
return result || "0";
},
from: (text, redix = baseData.length) =>
{
let result = 0;
for(let i = text.length, x = 1; --i >= 0; x *= redix)
result += baseData.indexOf(text[i]) * x;
return result;
}
};
})();
const redix = 65;
for(let i = 0; i < 4097; i += 82)
{
console.log(i, "⟶", numBase.to(i, redix), "⟶", numBase.from(numBase.to(i, redix), redix));
}
.as-console-wrapper{top:0;max-height:unset!important;overflow:auto!important;}

Related

unary operator prefix execution in recursion is not working as expected

I am trying to count number of combinations in given range and length of combinations. Here is following code.
function generateCombination() {
const perm = [];
const permLength = 2;
const numberRange = 8;
let total = 0;
const getCombinations = (result, permLength, numberRange) => {
if (result.length === permLength) {
//console.log('result: ', result);
return 1;
}
for (var i = 0; i < numberRange; i++) {
if (result.indexOf(i) === -1) {
result.push(i);
total = total + getCombinations(result, permLength, numberRange);
result.pop();
}
}
return 0;
}
getCombinations(perm, permLength, numberRange);
console.log("total: ", total); // expected value "total: 56"
}
generateCombination();
the console log for total variable always print 0. but following code works as expected with little change in for loop code. I couldn't understand how the prefix is works here (somex = somex + fn()). Can someone please help here?
// working solution
function generateCombination() {
const perm = [];
const permLength = 2;
const numberRange = 8;
let total = 0;
const getCombinations = (result, permLength, numberRange) => {
if (result.length === permLength) {
//console.log('result: ', result);
return 1;
}
for (var i = 0; i < numberRange; i++) {
if (result.indexOf(i) === -1) {
result.push(i);
if (getCombinations(result, permLength, numberRange)) {
total += 1;
}
result.pop();
}
}
return 0;
}
getCombinations(perm, permLength, numberRange);
console.log("total: ", total); // expected value is "total: 56" and working here
}
generateCombination();
My question is, I don't understand, why solution 1 (top one) is not working as expected (printing total as 0 rather than 56 )?
Thanks
You could move total into getCombinations and return this value on exit.
function generateCombination() {
const perm = [];
const permLength = 2;
const numberRange = 8;
const getCombinations = (result, permLength, numberRange) => {
if (result.length === permLength) return 1;
let total = 0;
for (let i = 0; i < numberRange; i++) {
if (result.indexOf(i) === -1) {
result.push(i);
total += getCombinations(result, permLength, numberRange);
result.pop();
}
}
return total;
}
console.log("total: ", getCombinations(perm, permLength, numberRange)); // expected value "total: 56"
}
generateCombination();

Why does this function return " '\'1\'' " according to codewars?

So I'm trying to solve this codewars problem (https://www.codewars.com/kata/5518a860a73e708c0a000027/train/javascript), but instead of my function returning a regular string like "1", it apparently returns something like " '\'1\'' ", according to codewars. Why is this? My code is below:
function lastDigit(as){
var product = "1";
for(var i = as.length - 1; i >= 0; i--){
var num = as[i]
//console.log(num)
//console.log(bigPower(num.toString(), product))
product = bigPower(as[i].toString(), product);
}
var prodArr = product.split("");
console.log(prodArr[prodArr.length - 1].toString());
return prodArr[prodArr.length - 1].toString();
}
function bigPower(base, exponent){
var product = base;
for(var i = 1; i < parseInt(exponent); i++){
product = multiply(product.toString(), base.toString());
}
return product;
}
function multiply(a, b) {
const product = Array(a.length+b.length).fill(0);
for (let i = a.length; i--; null) {
let carry = 0;
for (let j = b.length; j--; null) {
product[1+i+j] += carry + a[i]*b[j];
carry = Math.floor(product[1+i+j] / 10);
product[1+i+j] = product[1+i+j] % 10;
}
product[i] += carry;
}
return product.join("").replace(/^0*(\d)/, "$1");
}
Use parseInt function in the return statement to parse the string and return as an integer.
return parseInt(prodArr[prodArr.length - 1].toString());
function lastDigit(as){
var product = "1";
for(var i = as.length - 1; i >= 0; i--){
var num = as[i]
product = bigPower(as[i].toString(), product);
}
var prodArr = product.split("");
return parseInt(prodArr[prodArr.length - 1].toString());
}
function bigPower(base, exponent){
var product = base;
for(var i = 1; i < parseInt(exponent); i++){
product = multiply(product.toString(), base.toString());
}
return product;
}
function multiply(a, b) {
const product = Array(a.length+b.length).fill(0);
for (let i = a.length; i--; null) {
let carry = 0;
for (let j = b.length; j--; null) {
product[1+i+j] += carry + a[i]*b[j];
carry = Math.floor(product[1+i+j] / 10);
product[1+i+j] = product[1+i+j] % 10;
}
product[i] += carry;
}
return product.join("").replace(/^0*(\d)/, "$1");
}
console.log(lastDigit([3, 4, 2]))

count 9's from 1 to n - 5kyu Kata

I am working on this kata https://www.codewars.com/kata/count-9-s-from-1-to-n/train/javascript
and i have written this code for it, but its not working. This question is similar to this one Count the number of occurrences of 0's in integers from 1 to N
but it is different because searching for 9's is practically very different to searching for 0's.
think part of the problem with this code is that it takes too long to run...
any advice appreciated!
function has9(n) {
var nine = [];
var ninearr = n.toString().split('');
for (var j = 0; j < ninearr.length; j++) {
if (ninearr[j] == '9') {
nine.push(ninearr[j]);
}
}
return nine.length;
}
function number9(n) {
var arr = [];
var arrnew = [];
for (var i = 0; i <= n; i++) {
arr.push(i);
}
for (var l = 0; l < arr.length; l++) {
arrnew.push(has9(l));
}
var sum = arrnew.reduce((a, b) => a + b, 0);
return sum;
}
Why not a regex based solution? (Too slow as well?)
const count9s = num => num.toString().match(/9/g).length
console.log(count9s(19716541879)) // 2
console.log(count9s(919191919191919)) // 8
console.log(count9s(999)) // 3
console.log(count9s(999999)) // 6
I have taken the above hint and completely re written the code, which I now feel should work, and it does for most inputs, but codewars is saying it fails on some of them. any ideas why?
function nines(n){
if(n>=100){
var q= Math.floor(n/100);
var nq= q * 20;
var r = (n%100);
var s = Math.floor(r/9);
if (r<=90){
return s + nq;
}
if (r == 99){
return 20 + nq;
}
if (90 < r < 100 && r!= 99){
var t = (r-90);
return nq + s + t;
}
}
if (n<100){
if (n<=90){
var a = Math.floor(n/9);
return a ;
}
if (n == 99){
return 20
}
if (90 < n < 100 && n!= 99){
var c = (n-90);
return 10 + c;
}
}
}
=== UPDATE ===
I just solved your kata using
function number9Helper(num) {
var pow = Math.floor(Math.log10(num));
var round = Math.pow(10, pow);
var times = Math.floor(num / round);
var rest = Math.abs(num - (round * times));
var res = pow * (round==10 ? 1 : round / 10) * times;
if (num.toString()[0] == '9') res += rest;
if (rest < 9) return res;
else return res + number9Helper(rest);
}
function number9(num) {
var res = number9Helper(num);
res = res + (num.toString().split('9').length-1);
return res;
}
== Function below works but is slow ===
So, could something like this work for you:
for (var nines=0, i=1; i<=n; i++) nines += i.toString().split('9').length-1;
Basically, there are many way to achieve what you need, in the end it all depends how do you want to approach it.
You can test it with
function nines(n) {
for (var nines=0, i=1; i<=n; i++) nines += i.toString().split('9').length-1;
return nines;
}
function number9(n) {
if (n < 8) {
return 0
};
if (n === 9) {
return 1
};
if (n > 10) {
let str = ''
for (let i = 9; i <= n; i++) {
str += String(i)
}
return str.match(/[9]/g).length
}
}

Longest palindrome in a string

I wrote the following function to find the longest palindrome in a string. It works fine but it won't work for words like "noon" or "redder". I fiddled around and changed the first line in the for loop from:
var oddPal = centeredPalindrome(i, i);
to
var oddPal = centeredPalindrome(i-1, i);
and now it works, but I'm not clear on why. My intuition is that if you are checking an odd-length palindrome it will have one extra character in the beginning (I whiteboarded it out and that's the conclusion I came to). Am I on the right track with my reasoning?
var longestPalindrome = function(string) {
var length = string.length;
var result = "";
var centeredPalindrome = function(left, right) {
while (left >= 0 && right < length && string[left] === string[right]) {
//expand in each direction.
left--;
right++;
}
return string.slice(left + 1, right);
};
for (var i = 0; i < length - 1; i++) {
var oddPal = centeredPalindrome(i, i);
var evenPal = centeredPalindrome(i, i);
if (oddPal.length > result.length)
result = oddPal;
if (evenPal.length > result.length)
result = evenPal;
}
return "the palindrome is: " + result + " and its length is: " + result.length;
};
UPDATE:
After Paul's awesome answer, I think it makes sense to change both variables for clarity:
var oddPal = centeredPalindrome(i-1, i + 1);
var evenPal = centeredPalindrome(i, i+1);
You have it backwards - if you output the "odd" palindromes (with your fix) you'll find they're actually even-length.
Imagine "noon", starting at the first "o" (left and right). That matches, then you move them both - now you're comparing the first "n" to the second "o". No good. But with the fix, you start out comparing both "o"s, and then move to both "n"s.
Example (with the var oddPal = centeredPalindrome(i-1, i); fix):
var longestPalindrome = function(string) {
var length = string.length;
var result = "";
var centeredPalindrome = function(left, right) {
while (left >= 0 && right < length && string[left] === string[right]) {
//expand in each direction.
left--;
right++;
}
return string.slice(left + 1, right);
};
for (var i = 0; i < length - 1; i++) {
var oddPal = centeredPalindrome(i, i + 1);
var evenPal = centeredPalindrome(i, i);
if (oddPal.length > 1)
console.log("oddPal: " + oddPal);
if (evenPal.length > 1)
console.log("evenPal: " + evenPal);
if (oddPal.length > result.length)
result = oddPal;
if (evenPal.length > result.length)
result = evenPal;
}
return "the palindrome is: " + result + " and its length is: " + result.length;
};
console.log(
longestPalindrome("nan noon is redder")
);
This will be optimal if the largest palindrome is found earlier.
Once its found it will exit both loops.
function isPalindrome(s) {
//var rev = s.replace(/\s/g,"").split('').reverse().join(''); //to remove space
var rev = s.split('').reverse().join('');
return s == rev;
}
function longestPalind(s) {
var maxp_length = 0,
maxp = '';
for (var i = 0; i < s.length; i++) {
var subs = s.substr(i, s.length);
if (subs.length <= maxp_length) break; //Stop Loop for smaller strings
for (var j = subs.length; j >= 0; j--) {
var sub_subs = subs.substr(0, j);
if (sub_subs.length <= maxp_length) break; // Stop loop for smaller strings
if (isPalindrome(sub_subs)) {
maxp_length = sub_subs.length;
maxp = sub_subs;
}
}
}
return maxp;
}
Here is another take on the subject.
Checks to make sure the string provided is not a palindrome. If it is then we are done. ( Best Case )
Worst case 0(n^2)
link to
gist
Use of dynamic programming. Break each problem out into its own method, then take the solutions of each problem and add them together to get the answer.
class Palindrome {
constructor(chars){
this.palindrome = chars;
this.table = new Object();
this.longestPalindrome = null;
this.longestPalindromeLength = 0;
if(!this.isTheStringAPalindrome()){
this.initialSetupOfTableStructure();
}
}
isTheStringAPalindrome(){
const reverse = [...this.palindrome].reverse().join('');
if(this.palindrome === reverse){
this.longestPalindrome = this.palindrome;
this.longestPalindromeLength = this.palindrome.length;
console.log('pal is longest', );
return true;
}
}
initialSetupOfTableStructure(){
for(let i = 0; i < this.palindrome.length; i++){
for(let k = 0; k < this.palindrome.length; k++){
this.table[`${i},${k}`] = false;
}
}
this.setIndividualsAsPalindromes();
}
setIndividualsAsPalindromes(){
for(let i = 0; i < this.palindrome.length; i++){
this.table[`${i},${i}`] = true;
}
this.setDoubleLettersPlaindrome();
}
setDoubleLettersPlaindrome(){
for(let i = 0; i < this.palindrome.length; i++){
const firstSubstring = this.palindrome.substring(i, i + 1);
const secondSubstring = this.palindrome.substring(i+1, i + 2);
if(firstSubstring === secondSubstring){
this.table[`${i},${i + 1}`] = true;
if(this.longestPalindromeLength < 2){
this.longestPalindrome = firstSubstring + secondSubstring;
this.longestPalindromeLength = 2;
}
}
}
this.setAnyPalindromLengthGreaterThan2();
}
setAnyPalindromLengthGreaterThan2(){
for(let k = 3; k <= this.palindrome.length; k++){
for(let i = 0; i <= this.palindrome.length - k; i++){
const j = i + k - 1;
const tableAtIJ = this.table[`${i+1},${j-1}`];
const stringToCompare = this.palindrome.substring(i, j +1);
const firstLetterInstringToCompare = stringToCompare[0];
const lastLetterInstringToCompare = [...stringToCompare].reverse()[0];
if(tableAtIJ && firstLetterInstringToCompare === lastLetterInstringToCompare){
this.table[`${i},${j}`] = true;
if(this.longestPalindromeLength < stringToCompare.length){
this.longestPalindrome = stringToCompare;
this.longestPalindromeLength = stringToCompare.length;
}
}
}
}
}
printLongestPalindrome(){
console.log('Logest Palindrome', this.longestPalindrome);
console.log('from /n', this.palindrome );
}
toString(){
console.log('palindrome', this.palindrome);
console.log(this.table)
}
}
// const palindrome = new Palindrome('lollolkidding');
// const palindrome = new Palindrome('acbaabca');
const palindrome = new Palindrome('acbaabad');
palindrome.printLongestPalindrome();
//palindrome.toString();
function longestPalindrome(str){
var arr = str.split("");
var endArr = [];
for(var i = 0; i < arr.length; i++){
var temp = "";
temp = arr[i];
for(var j = i + 1; j < arr.length; j++){
temp += arr[j];
if(temp.length > 2 && temp === temp.split("").reverse().join("")){
endArr.push(temp);
}
}
}
var count = 0;
var longestPalindrome = "";
for(var i = 0; i < endArr.length; i++){
if(count >= endArr[i].length){
longestPalindrome = endArr[i-1];
}
else{
count = endArr[i].length;
}
}
console.log(endArr);
console.log(longestPalindrome);
return longestPalindrome;
}
longestPalindrome("abracadabra"));
let str = "HYTBCABADEFGHABCDEDCBAGHTFYW12345678987654321ZWETYGDE";
let rev = str.split("").reverse().join("").trim();
let len = str.length;
let a="";
let result = [];
for(let i = 0 ; i < len ; i++){
for(let j = len ; j > i ; j--){
a = rev.slice(i,j);
if(str.includes(a)){
result.push(a);
break;
}
}
}
result.sort((a,b) => { return b.length - a.length})
let logPol = result.find((value)=>{
return value === value.split('').reverse().join('') && value.length > 1
})
console.log(logPol);
function longest_palindrome(s) {
if (s === "") {
return "";
}
let arr = [];
let _s = s.split("");
for (let i = 0; i < _s.length; i++) {
for (let j = 0; j < _s.length; j++) {
let word = _s.slice(0, j + 1).join("");
let rev_word = _s
.slice(0, j + 1)
.reverse()
.join("");
if (word === rev_word) {
arr.push(word);
}
}
_s.splice(0, 1);
}
let _arr = arr.sort((a, b) => a.length - b.length);
for (let i = 0; i < _arr.length; i++) {
if (_arr[arr.length - 1].length === _arr[i].length) {
return _arr[i];
}
}
}
longest_palindrome('bbaaacc')
//This code will give you the first longest palindrome substring into the string
var longestPalindrome = function(string) {
var length = string.length;
var result = "";
var centeredPalindrome = function(left, right) {
while (left >= 0 && right < length && string[left] === string[right]) {
//expand in each direction.
left--;
right++;
}
return string.slice(left + 1, right);
};
for (var i = 0; i < length - 1; i++) {
var oddPal = centeredPalindrome(i, i + 1);
var evenPal = centeredPalindrome(i, i);
if (oddPal.length > 1)
console.log("oddPal: " + oddPal);
if (evenPal.length > 1)
console.log("evenPal: " + evenPal);
if (oddPal.length > result.length)
result = oddPal;
if (evenPal.length > result.length)
result = evenPal;
}
return "the palindrome is: " + result + " and its length is: " + result.length;
};
console.log(longestPalindrome("n"));
This will give wrong output so this condition need to be taken care where there is only one character.
public string LongestPalindrome(string s) {
return LongestPalindromeSol(s, 0, s.Length-1);
}
public static string LongestPalindromeSol(string s1, int start, int end)
{
if (start > end)
{
return string.Empty;
}
if (start == end)
{
char ch = s1[start];
string s = string.Empty;
var res = s.Insert(0, ch.ToString());
return res;
}
if (s1[start] == s1[end])
{
char ch = s1[start];
var res = LongestPalindromeSol(s1, start + 1, end - 1);
res = res.Insert(0, ch.ToString());
res = res.Insert(res.Length, ch.ToString());
return res;
}
else
{
var str1 = LongestPalindromeSol(s1, start, end - 1);
var str2 = LongestPalindromeSol(s1, start, end - 1);
if (str1.Length > str2.Length)
{
return str1;
}
else
{
return str2;
}
}
}
This is in JS ES6. much simpler and works for almost all words .. Ive tried radar, redder, noon etc.
const findPalindrome = (input) => {
let temp = input.split('')
let rev = temp.reverse().join('')
if(input == rev){
console.log('Palindrome', input.length)
}
}
//i/p : redder
// "Palindrome" 6

Convert excel column alphabet (e.g. AA) to number (e.g., 25)

In my grid the column headers are named A,B,C...,AA,AB,AC,...etc like an excel spreadsheet. How can I convert the string to number like: A => 1, B => 2, AA => 27
Try:
var foo = function(val) {
var base = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', i, j, result = 0;
for (i = 0, j = val.length - 1; i < val.length; i += 1, j -= 1) {
result += Math.pow(base.length, j) * (base.indexOf(val[i]) + 1);
}
return result;
};
console.log(['A', 'AA', 'AB', 'ZZ'].map(foo)); // [1, 27, 28, 702]
solution 1: best performance and browser compatibility
// convert A to 1, Z to 26, AA to 27
function lettersToNumber(letters){
var chrs = ' ABCDEFGHIJKLMNOPQRSTUVWXYZ', mode = chrs.length - 1, number = 0;
for(var p = 0; p < letters.length; p++){
number = number * mode + chrs.indexOf(letters[p]);
}
return number;
}
solution 2: best performance and compatibility and shorter code (Recommended)
// convert A to 1, Z to 26, AA to 27
function lettersToNumber(letters){
for(var p = 0, n = 0; p < letters.length; p++){
n = letters[p].charCodeAt() - 64 + n * 26;
}
return n;
}
solution 3: short code (es6 arrow function)
// convert A to 1, Z to 26, AA to 27
function lettersToNumber(letters){
return letters.split('').reduce((r, a) => r * 26 + parseInt(a, 36) - 9, 0);
}
test:
['A', 'Z', 'AA', 'AB', 'ZZ','BKTXHSOGHKKE'].map(lettersToNumber);
// [1, 26, 27, 28, 702, 9007199254740991]
lettersToNumber('AAA'); //703
Here's a quick example of the code you should implement.
This will work with any given number of letters.
function letterToNumbers(string) {
string = string.toUpperCase();
var letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', sum = 0, i;
for (i = 0; i < string.length; i++) {
sum += Math.pow(letters.length, i) * (letters.indexOf(string.substr(((i + 1) * -1), 1)) + 1);
}
return sum;
}
i just wrote a junk yard f##$ snippet... need to be optimized.. :)
charToNum = function(alpha) {
var index = 0
for(var i = 0, j = 1; i < j; i++, j++) {
if(alpha == numToChar(i)) {
index = i;
j = i;
}
}
console.log(index);
}
numToChar = function(number) {
var numeric = (number - 1) % 26;
var letter = chr(65 + numeric);
var number2 = parseInt((number - 1) / 26);
if (number2 > 0) {
return numToChar(number2) + letter;
} else {
return letter;
}
}
chr = function (codePt) {
if (codePt > 0xFFFF) {
codePt -= 0x10000;
return String.fromCharCode(0xD800 + (codePt >> 10), 0xDC00 + (codePt & 0x3FF));
}
return String.fromCharCode(codePt);
}
charToNum('A') => returns 1 and charToNum('AA') => returns 27;
// Given Column to Number
function colToNumber(str) {
let num = 0
let i = 0
while (i < str.length) {
num = str[i].charCodeAt(0) - 64 + num * 26;
i++;
}
return num;
}
//Given Number to Column name
function numberToCol(num) {
let str = '', q, r;
while (num > 0) {
q = (num-1) / 26;
r = (num-1) % 26
num = Math.floor(q)
str = String.fromCharCode(65 + r) + str;
}
return str;
}
I rewrote Yoshi's answer in a more verbose form that explains better how it works and is easier to port to other languages:
var foo = function(val) {
var base = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
var baseNumber = base.length;
var runningTotal = 0;
var characterIndex = 0;
var indexExponent = val.length - 1;
while( characterIndex < val.length ){
var digit = val[characterIndex];
var digitValue = base.indexOf(digit) + 1;
runningTotal += Math.pow(baseNumber, indexExponent) * digitValue;
characterIndex += 1
indexExponent -= 1
}
return runningTotal;
};
console.log(['A', 'AA', 'AB', 'ZZ'].map(foo)); // [1, 27, 28, 702]
Public Function ColLet2Num(Letras As String)
'RALONSO MAYO 2017
'A-> 1
'OQ ->407
'XFD->16384
Dim UnChar As String
Dim NAsc As Long
Dim F As Long
Dim Acum As Long
Dim Indice As Long
Letras = UCase(Letras)
Acum = 0
Indice = 0
For F = Len(Letras) - 1 To 0 Step -1
UnChar = Mid(Letras, F + 1, 1)
NAsc = Asc(UnChar) - 64
Acum = Acum + (NAsc * (26 ^ Indice))
Indice = Indice + 1
Next
If Acum > 16384 Then
MsgBox "La celda máxima es la XFD->16384", vbCritical
End If
ColLet2Num = Acum
End Function
const getColumnName = (columnNumber) => {
let columnName = "";
const alphabets = "abcdefghijklmnopqrstuvwxyz".toUpperCase();
while (columnNumber > 0) {
const rem = columnNumber % 26;
if (rem === 0) {
columnName += "Z";
columnNumber = columnNumber / 26 - 1;
} else {
columnName += alphabets[rem - 1];
columnNumber = Math.floor(columnNumber / 26);
}
}
return columnName.split("").reverse().join("");
};
console.log(getColumnName(27));
A good readability and performance example:
const letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
// create dict to O(1) access to letter number
const dict = Object.fromEntries(letters.split('').map((it, index) => [it, index + 1]));
function toNumber(col) {
return col
.toUpperCase()
.split('')
.reduce((acc, letter, index) => acc + Math.pow(letters.length, col.length - (index + 1)) * dict[letter], 0);
}
Highly inspired by the different solutions put forth on this page
//fixed the one taken from here
function colToNumber(str: string): number {
var num = 0
for (var i = 0; i < str.length; i++) {
const current_letter = str.charCodeAt(i) - 64
const current_char = str[i]
if (i == str.length - 1) {
num += current_letter
} else {
var current = current_letter * Math.pow(26, str.length - i - 1)
num += current
}
}
return num;
}
//Given Number to Column name (taken from here)
function numberToCol(num: number) {
var str = '', q: number, r: number;
while (num > 0) {
q = (num - 1) / 26;
r = (num - 1) % 26
num = Math.floor(q)
str = String.fromCharCode(65 + r) + str;
}
return str;
}
function test_both() {
const dic = new Map<number, string>()
dic.set(1,"A")
dic.set(10,"J")
dic.set(13,"M")
dic.set(33,"AG")
dic.set(63,"BK")
dic.set(66,"BN")
dic.set(206,"GX")
dic.set(502,"SH")
dic.set(1003,"ALO")
dic.set(100,"CV")
dic.set(10111,"NXW")
dic.set(10001,"NTQ")
dic.set(9002,"MHF")
dic.set(5002,"GJJ")
dic.set(3002,"DKL")
dic.set(16384,"XFD")
for (var key of dic.keys()) {
const expected_a1 = dic.get(key) || ""
//console.log(`${ key }, ${ expected_a1 } `)
var actual = numberToCol(key)
var actual_num = colToNumber(expected_a1)
if (actual.localeCompare(expected_a1) != 0) {
console.error(`key = ${key} == expected=${expected_a1} actual = ${actual} `)
}
if (actual_num != key) {
console.error(`expected = ${expected_a1} key = ${key} == actual = ${actual_num} `)
}
}
}

Categories