Skip to content

Instantly share code, notes, and snippets.

@wsams
Last active March 16, 2019 04:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wsams/c0f035edbb7f275775395854e986c872 to your computer and use it in GitHub Desktop.
Save wsams/c0f035edbb7f275775395854e986c872 to your computer and use it in GitHub Desktop.
Multiply or Add big numbers quickly with this node script. 5000 digit numbers squared in < 1 minute, doubled in < 0.1 seconds.
/**
* This node script accepts two arguments, both integers, and returns their sum.
*
* The integers are string inputs split into an array of digits and operated on so
* they can be really big numbers. A 5000 digit number doubled takes less than 0.1 seconds
* to compute on a mid-2014 MacBook Pro. (Node v11.11.0)
*
* Usage: node add.js <int> <int>
*/
function p(...o) {
console.log(o);
}
/**
* @param Array a
* @param Array b
*/
function add(arrs) {
const sortedRows = arrs.sort(function(a, b) {
return b.length - a.length;
});
const maxCol = sortedRows[0].length;
remainder = 0;
const sum = [];
for (let col = (maxCol - 1); col >= 0; col--) {
let tmp = 0;
for (let row = 0; row < sortedRows.length; row++) {
const rowForVal = sortedRows[row];
const rowLen = rowForVal.length;
for (let t = rowLen; t < maxCol; t++) {
rowForVal.unshift(0);
}
tmp += rowForVal[col];
}
tmp += remainder;
const tmps = tmp.toString().split('');
const tmpsl = tmps.length;
sum.unshift(tmps.pop());
if (tmpsl > 1) {
remainder = parseInt(tmps.join(''));
} else {
remainder = 0;
}
}
if (remainder > 0) {
sum.unshift(remainder.toString());
}
return sum.map(n => parseInt(n));
}
const inputs = [];
if (process.argv.length > 1) {
for (let i = 2; i < process.argv.length; i++) {
inputs.push(process.argv[i].split('').map(n => parseInt(n)));
}
}
p(add(inputs).map(n => n.toString()).join(''));
/**
* This node script accepts two arguments, both integers, and returns the product.
*
* The integers are string inputs split into an array of digits and operated on so
* they can be really big numbers. A 5000 digit number squared takes less than 1 minute
* to compute on a mid-2014 MacBook Pro. (Node v11.11.0)
*
* Usage: node multiply.js <int> <int>
*/
function p(...o) {
console.log(o);
}
/**
* Multiply two integers of any length.
* @param Array a
* @param Array b
*/
function mult(aArr, bArr) {
const as = aArr.reverse().join('');
const bs = bArr.reverse().join('');
let rowa = [];
let remainder = 0;
let rows = [];
for (let bx = 0; bx < bs.length; bx++) {
const bval = bs[bx];
rowa = bx > 0 ? Array(bx).fill(0) : [];
for (let ax = 0; ax < as.length; ax++) {
const aval = as[ax];
const c = bval * aval;
const cs = c.toString();
const cl = cs.length;
if (cl === 2) {
const save = parseInt(cs[1]);
rowa.unshift(save + remainder);
let msg = '';
remainder = parseInt(cs[0]);
} else if (cl === 1) {
const save = parseInt(cs[0]);
rowa.unshift(save + remainder);
remainder = 0;
}
if (ax === (as.length - 1)) {
if (remainder > 0) {
rowa.unshift(remainder);
remainder = 0;
}
}
}
rows.push(rowa);
}
const sortedRows = rows.sort(function(a, b) {
return b.length - a.length;
});
const maxCol = sortedRows[0].length;
remainder = 0;
const sum = [];
for (let col = (maxCol - 1); col >= 0; col--) {
let tmp = 0;
for (let row = 0; row < sortedRows.length; row++) {
const rowForVal = sortedRows[row];
const rowLen = rowForVal.length;
for (let t = rowLen; t < maxCol; t++) {
rowForVal.unshift(0);
}
tmp += rowForVal[col];
}
tmp += remainder;
const tmps = tmp.toString().split('');
const tmpsl = tmps.length;
sum.unshift(tmps.pop());
if (tmpsl > 1) {
remainder = parseInt(tmps.join(''));
} else {
remainder = 0;
}
}
if (remainder > 0) {
sum.unshift(remainder.toString());
}
return sum.map(n => parseInt(n));
}
const a = process.argv[2];
const b = process.argv[3];
p(mult(a.split(''), b.split('')).map(n => n.toString()).join(''));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment