Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add karatsuba algorithm #225

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
add karatsuba multiplication algorithm
appleJax committed Oct 18, 2018
commit 42b5a462b7681d1f61c94972fd01dfb610d7c94a
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import karatsuba from '../karatsuba';

describe('karatsuba multiplication', () => {
xit('should multiply numbers correctly', () => {
expect(karatsuba(1234, 5678)).toEqual(7006652);
});
});
66 changes: 66 additions & 0 deletions src/algorithms/math/karatsuba-multiplication/karatsuba.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/**
*
* @param {number} x
* @param {number} y
* @return {number}
*/
export default function karatsuba(x, y) {
// BASE CASE:
// if numbers are sufficiently small,
// multiply them together in the traditional way
if (x < 10 || y < 10) {
return x * y;
}

const minDigits = Math.min(
String(x).length,
String(y).length,
);

// scaleFactor is used to split the numbers
// into smaller numbers for recursion.
// when combining the subcomputations back
// together, the scaleFactor is used to
// recreate the components of the original number
const scaleFactor = 10 ** Math.floor(minDigits / 2);

// a b are the two components of x
// c d are the two components of y
//
// e.g.
// x = 1234 -> a = 12, b = 34
// y = 5678 -> c = 56, d = 78
//
// example of component computations:
// x = 1234, y = 5678
// scaleFactor = 100
// a = floor(1234 / 100) = floor(12.34) = 12
const a = Math.floor(x / scaleFactor);

// b = 1234 - (12 * 100) = 1234 - 1200 = 34
const b = x - (a * scaleFactor);

// c = floor(5678 / 100) = floor(56.78) = 56
const c = Math.floor(y / scaleFactor);

// d = 5678 - (56 * 100) = 5678 - 5600 = 78
const d = y - (c * scaleFactor);

// compute sub-expressions:
// since a + b is less than x, and c + d is less than y
// the recursion is guaranteed to reach the base case
const ac = karatsuba(a, c);
const bd = karatsuba(b, d);
const abcd = karatsuba(a + b, c + d);

// combine sub-expressions:
// since the scaleFactor was used to
// artificially reduce the size of the components,
// the scaleFactor must be applied in reverse
// to reconstruct the original components
const A = ac * (scaleFactor ** 2);
const B = (abcd - ac - bd) * scaleFactor;
const C = bd;

return A + B + C;
}