Convert base 10 and base 255 integer strings in JavaScript? - javascript
Does anyone know a way to convert base 10 and base 255 strings in JavaScript exceeding the Number.MAX_SAFE_INTEGER value without using a big number library?
For something like:
var base10 = '23456786543234567876543234567876543267';
var base255 = base10ToBase255(base10);
To base-255 or from base-255 as:
var base255 = new Uint8Array(20);
for (var i = 0; i < 20; i++) base255[i] = 254 - i;
var base10 = base255ToBase10(base255);
EDITED: changed to allow for other bases (<=256)
It always boils down to using a big integer, sorry. But you do not need much, it's just about 100 lines of code for what you want (string to base 256 and back).
"use strict";
var COMMON_BASE = 255; // must be 256 at most!
function copyA(a){
var ret = new Uint8Array(a.length);
for(var i = 0;i<a.length;i++){
ret[i] = a[i];
}
return ret;
}
function isZero(a){
for(var i = 0;i<a.length;i++){
if(a[i] !== 0)
return false;
}
return true;
}
function clampA(a){
var alen = a.length;
var i=0;
while(a[alen - 1] === 0)alen--;
var ret = new Uint8Array(alen);
for(var i = 0;i<alen;i++){
ret[i] = a[i];
}
return ret;
}
function addD(a,d) {
var tlen = a.length;
var carry = 0;
var ret = new Uint8Array(tlen +1);
if(d === 0)
return copyA(a);
var i = 0;
var temp = carry;
temp += a[i] + d;
carry = Math.floor(temp / COMMON_BASE);
ret[i] = temp % COMMON_BASE;
for (i = 1; i < tlen; i++) {
temp = carry;
temp += a[i];
carry = Math.floor(temp / COMMON_BASE);
ret[i] = temp % COMMON_BASE;
}
if (carry) {
ret[i] = carry;
}
ret = clampA(ret);
return ret;
};
function mulD(a,d){
var tlen = a.length;
var carry = 0;
var ret = new Uint8Array(tlen + 1);
var k = 0;
var tmp;
if(isZero(a))
return copyA(a);
if(d === 0)
return new Uint8Array(tlen);
for (; k < tlen; k++) {
tmp = a[k] * d + carry;
ret[k] = tmp % COMMON_BASE;
carry = Math.floor(tmp / COMMON_BASE);
}
if (carry) {
ret[k] = carry;
}
ret = clampA(ret);
return ret;
}
function divRem(a,d){
var divrem = function(u, m, v, q, B) {
var k = 0,
t;
for (var j = m - 1; j >= 0; j--) {
k = (k * COMMON_BASE) ;
k += u[j];
if (k >= v) {
t = Math.floor(k / v);
k -= t * v;
} else {
t = 0;
}
q[j] = t;
}
return k;
};
var Q = new Uint8Array(a.length);
var R = divrem(a,a.length, d, Q, 8);
Q = clampA(Q);
return [Q,R];
}
// Assuming 's' being a string with decimal digits
function base10ToBase256(s){
var blen = 0;
// checks&balances omitted
var out = new Uint8Array(1);
for(var i=0;i<s.length;i++){
out = mulD(out,10);
out = addD(out,parseInt(s[i],10) );
}
return out;
}
// Assuming b being a Uint8Array
function base256ToBase10(a){
var s = "";
var t = copyA(a);
var qr = [];
var i = a.length;
while(!isZero(t)){
qr = divRem(t,10);
s = s + qr[1].toString(10);
t = qr[0];
}
return s.split("").reverse().join("");
}
var str = "8716418673416734167345634096788356249857";
//base10ToBase256(str).join(",");
base256ToBase10(base10ToBase256(str));
var str = "8716418673416734167345634096788356249857";
console.log(base10ToBase256(str).join(","));
console.log(base256ToBase10(base10ToBase256(str)));
Here the LSB is at position zero.
It's a rough hack (way too much copies etc.) but it'll do it.
Related
Pascal's Triangle gone wrong
I am trying to make Pascal's Triangle in JavaScript but there are lots of errors. I have know idea why errors are happening but there are some. Code: function triangle() { this.rows = [[1]]; this.genRow = function() { this.rows.push([]); this.rows[this.rows.length-1].push(1); for (var i = 0; i < this.rows[this.rows.length-1].length; i++){ var u = [this.rows[this.rows.length-1][i-1], this.rows[this.rows.length-1][i], this.rows[this.rows.length-1][i+1]]; var f = function(e) { return e != undefined; }; function s() { var sum=0; for (var index = 0; i < this.legnth; i++){ sum =+ this[i]; } return sum; } u = u.filter(f).s(); this.rows[this.rows.length-1].push(u); } this.rows[this.rows.length-1].push(1); } } var t = new triangle(); t.genRow(); console.log(t.rows); Thanks.
Please try this code,To Pasqual's triangle gone wrong #include <stdio.h> int binomialCoeff(int n, int k); void printPascal(int n) { for (int line = 0; line < n; line++) { for (int i = 0; i <= line; i++) printf("%d ", binomialCoeff(line, i)); printf("\n"); } } int binomialCoeff(int n, int k) { int res = 1; if (k > n - k) k = n - k; for (int i = 0; i < k; ++i) { res *= (n - i); res /= (i + 1); } return res; } int main() { int n = 7; printPascal(n); return 0; } I hope this code will be useful. Thank you.
const pascalsTriangle = (rows = 1) => { let res = []; for (let i = 1; i <= rows; i++) { if (i == 1) { res.push([1]); } else if (i == 2) { res.push([1, 1]); } else { let arr = [1]; let lastArr = res[i - 2]; for (let index=0; index<lastArr.length-1; index++) { arr.push(lastArr[index] + lastArr[index + 1]); } arr.push(1); res.push(arr); } } return res; }; This will work perfectly. You can refer it here. https://github.com/omkarsk98/Exercism/blob/master/javascript/pascals-triangle/pascals-triangle.js
Here is an approach in JS. function getNextLevel(previous) { const current = [1]; for (let i = 1; i < previous.length; i++) { current.push(previous[i] + previous[i - 1]); } current.push(1); return current; } function pascalTriangle(levels = 1) { let currentRow = [1]; while (levels--) { console.log(currentRow.join(" ")); currentRow = getNextLevel(currentRow); } } pascalTriangle(10);
How to get index/position of excel column in javascript
I am developing a program where I need to find out index/position of given excel column's index. if I passed A it should return 1 if I passed AA it should return 27 if I passed AB it should return 28 if I passed AAA it should return 26*26*26 (not sure but want to get actual position) what I did so far var str = "AB"; var d = 0; for (var i = 1, m = 26; i < string.length ; i++) { if(string.length === 1) { var d = parseInt(string.charCodeAt(i) - index); } else if (string.length === 2){ var d = parseInt(((string.charCodeAt(i) - index) * m ) + (i)); } else { var d = parseInt(((string.charCodeAt(i) - index) * m ) + (i)); } }
var str = "MM19"; var number_regex = /[+-]?\d+(\.\d+)?/g; var matches = []; str.replace(number_regex, function (match) { matches.push(match); }); str = str.replace(/[0-9]/g, ''); matches.push(str); console.log(matches[1]); var index = 64; var string = matches[1]; var columnIndex = 0; var counter = 0; var baseValue; var m = 26; console.log("length is:", string.length); for (var i = string.length-1; i >= 0; i--) { columnIndex = columnIndex + (string.charCodeAt(i) - index) * Math.pow(m, counter); counter++; } console.log("index value", columnIndex);
The return is not working (javascript)
The function is returning undefined why it's not returning the array length.even at the start of the code it's printing in the console but return is not working. var resArr = []; var p; function persistence(num) { resArr.push(num); console.log(resArr); console.log(resArr.length); if (num > 10) { var v = 1; var x = num.toString(); var arr = []; for (i = 0; i < x.length; i++) { arr.push(x.charAt(i)); } console.log(arr); for (j = 0; j < arr.length; j++) { var v = v * arr[j]; } persistence(v); } else { return resArr.length - 1; } }
You're not returning in all cases. Change persistence(v); to return persistence(v);
String reverse in javascript using prototype
String.prototype.reverseStr = function () { var len = this.length - 1; var j = 0; for (i = len; i >= Math.floor(len / 2); i--) { var tmp = this[i]; this[i] = this[j]; this[j] = tmp; j++; } return this; } alert("abcde".reverseStr()); Why doesn't this work ? It outputs "abcde" and not reversed string .
Overkill. "abcde".split('').reverse().join('');
The same code but with some edits String.prototype.reverseStr = function () { var len = this.length - 1; var tmp = ''; for (var i = len; i >= 0; i--) { tmp += this[i]; } return tmp; } alert("abcde".reverseStr()); See a fiddle here
Interleave array elements
What is a fast and simple implementation of interleave: console.log( interleave([1,2,3,4,5,6] ,2) ); // [1,4,2,5,3,6] console.log( interleave([1,2,3,4,5,6,7,8] ,2) ); // [1,5,2,6,3,7,4,8] console.log( interleave([1,2,3,4,5,6] ,3) ); // [1,3,5,2,4,6] console.log( interleave([1,2,3,4,5,6,7,8,9],3) ); // [1,4,7,2,5,8,3,6,9] This mimics taking the array and splitting it into n equal parts, and then shifting items off the front of each partial array in sequence. (n=2 simulates a perfect halving and single shuffle of a deck of cards.) I don't much care exactly what happens when the number of items in the array is not evenly divisible by n. Reasonable answers might either interleave the leftovers, or even "punt" and throw them all onto the end.
function interleave( deck, step ) { var copyDeck = deck.slice(), stop = Math.floor(copyDeck.length/step), newDeck = []; for (var i=0; i<step; i++) { for (var j=0; j<stop; j++) { newDeck[i + (j*step)] = copyDeck.shift(); } } if(copyDeck.length>0) { newDeck = newDeck.concat(copyDeck); } return newDeck; } It could be done with a counter instead of shift() function interleave( deck, step ) { var len = deck.length, stop = Math.floor(len/step), newDeck = [], cnt=0; for (var i=0; i<step; i++) { for (var j=0; j<stop; j++) { newDeck[i + (j*step)] = deck[cnt++]; } } if(cnt<len) { newDeck = newDeck.concat(deck.slice(cnt,len)); } return newDeck; } And instead of appending the extras to the end, we can use ceil and exit when we run out function interleave( deck, step ) { var copyDeck = deck.slice(), stop = Math.ceil(copyDeck.length/step), newDeck = []; for (var i=0; i<step; i++) { for (var j=0; j<stop && copyDeck.length>0; j++) { newDeck[i + (j*step)] = copyDeck.shift(); } } return newDeck; }
can i has prize? :-D function interleave(a, n) { var i, d = a.length + 1, r = []; for (i = 0; i < a.length; i++) { r[i] = a[Math.floor(i * d / n % a.length)]; } return r; } according to my tests r.push(... is faster than r[i] = ... so do with that as you like.. note this only works consistently with sets perfectly divisible by n, here is the most optimized version i can come up with: function interleave(a, n) { var i, d = (a.length + 1) / n, r = [a[0]]; for (i = 1; i < a.length; i++) { r.push(a[Math.floor(i * d) % a.length]); } return r; } O(n-1), can anyone come up with a log version? to the mathmobile! [spinning mathman logo]
Without for loops (I've added some checkup for the equal blocks): function interleave(arr, blocks) { var len = arr.length / blocks, ret = [], i = 0; if (len % 1 != 0) return false; while(arr.length>0) { ret.push(arr.splice(i, 1)[0]); i += (len-1); if (i>arr.length-1) {i = 0; len--;} } return ret; } alert(interleave([1,2,3,4,5,6,7,8], 2)); And playground :) http://jsfiddle.net/7tC9F/
how about functional with recursion: function interleave(a, n) { function f(a1, d) { var next = a1.length && f(a1.slice(d), d); a1.length = Math.min(a1.length, d); return function(a2) { if (!a1.length) { return false; } a2.push(a1.shift()); if (next) { next(a2); } return true; }; } var r = [], x = f(a, Math.ceil(a.length / n)); while (x(r)) {} return r; }
Phrogz was pretty close, but it didn't interleave properly. This is based on that effort: function interleave(items, parts) { var len = items.length; var step = len/parts | 0; var result = []; for (var i=0, j; i<step; ++i) { j = i while (j < len) { result.push(items[j]); j += step; } } return result; } interleave([0,1,2,3], 2); // 0,2,1,3 interleave([0,1,2,3,4,5,6,7,8,9,10,11], 2) // 0,6,1,7,2,8,3,9,4,10,5,11 interleave([0,1,2,3,4,5,6,7,8,9,10,11], 3) // 0,4,8,1,5,9,2,6,10,3,7,11 interleave([0,1,2,3,4,5,6,7,8,9,10,11], 4) // 0,3,6,9,1,4,7,10,2,5,8,11 interleave([0,1,2,3,4,5,6,7,8,9,10,11], 5) // 0,2,4,6,8,10,1,3,5,7,9,11
Since I've been pushed to add my own answer early (edited to fix bugs noted by RobG): function interleave(items,parts){ var stride = Math.ceil( items.length / parts ) || 1; var result = [], len=items.length; for (var i=0;i<stride;++i){ for (var j=i;j<len;j+=stride){ result.push(items[j]); } } return result; }
try this one: function interleave(deck, base){ var subdecks = []; for(count = 0; count < base; count++){ subdecks[count] = []; } for(var count = 0, subdeck = 0; count < deck.length; count++){ subdecks[subdeck].push(deck[count]); subdeck = subdeck == base - 1? 0 : subdeck + 1; } var newDeck = []; for(count = 0; count < base; count++){ newDeck = newDeck.concat(subdecks[count]); } return newDeck; }