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
Prev Previous commit
Next Next commit
add partial README
appleJax committed Oct 18, 2018
commit 4b67f1e158e33f53d0d729bc3bbd3e551ed0c92f
7 changes: 7 additions & 0 deletions src/algorithms/math/karatsuba-multiplication/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Karatsuba Multiplication

Karatsuba is a fast multiplication algorithm discovered by Anatoly Karatsuba in 1960. Given two n-digit numbers, the "grade-school" method of long multiplication has a time complexity of O(n<sup>2</sup>), whereas the karatsuba algorithm has a time complexity of O(n<sup>1.59</sup>).

## References
[Stanford Algorithms (YouTube)](https://www.youtube.com/watch?v=JCbZayFr9RE)
[Wikipedia](https://en.wikipedia.org/wiki/Karatsuba_algorithm)
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
import karatsuba from '../karatsuba';

describe('karatsuba multiplication', () => {
xit('should multiply numbers correctly', () => {
it('should multiply simple numbers correctly', () => {
expect(karatsuba(0, 37)).toEqual(0);
expect(karatsuba(1, 8)).toEqual(8);
expect(karatsuba(5, 6)).toEqual(30);
});

it('should multiply larger numbers correctly', () => {
expect(karatsuba(1234, 5678)).toEqual(7006652);
expect(karatsuba(9182734, 726354172)).toEqual(6669917151266248);
});
});
24 changes: 13 additions & 11 deletions src/algorithms/math/karatsuba-multiplication/karatsuba.js
Original file line number Diff line number Diff line change
@@ -12,28 +12,30 @@ export default function karatsuba(x, y) {
return x * y;
}

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

// SCALE FACTOR:
// 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
// recreate the magnitude of the original numbers
const minDigits = Math.min(
String(x).length,
String(y).length,
);
const scaleFactor = 10 ** Math.floor(minDigits / 2);

// PARAMETER COMPONENTS:
// 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);

@@ -46,18 +48,18 @@ export default function karatsuba(x, y) {
// d = 5678 - (56 * 100) = 5678 - 5600 = 78
const d = y - (c * scaleFactor);

// compute sub-expressions:
// 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:
// COMBINE SUB-EXPRESSIONS:
// since the scaleFactor was used to
// artificially reduce the size of the components,
// reduce the size of the components,
// the scaleFactor must be applied in reverse
// to reconstruct the original components
// to reconstruct the magnitude of the original components
const A = ac * (scaleFactor ** 2);
const B = (abcd - ac - bd) * scaleFactor;
const C = bd;