Skip to content

Commit 9145719

Browse files
committedApr 17, 2018
Add lcm.
1 parent 34522c8 commit 9145719

File tree

6 files changed

+111
-7
lines changed

6 files changed

+111
-7
lines changed
 

‎README.md

+1-2
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,9 @@
3333
* [Power Set](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/math/power-set)
3434
* [Primality Test](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/math/primality-test) (trial division)
3535
* [Euclidean Algorithm](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/math/euclidean-algorithm) - calculate the greatest common divisor (GCD)
36+
* [Least Common Multiple (LCM)](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/math/least-common-multiple)
3637
* [Fisher–Yates Shuffle](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/math/fisher-yates) - random permutation of a finite sequence
3738
* Collatz Conjecture algorithm
38-
* Greatest Difference
39-
* Least Common Multiple
4039
* Newton's square
4140
* Shannon Entropy
4241
* **String**

‎src/algorithms/math/euclidean-algorithm/__test__/euclieanAlgorithm.test.js

+2
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,7 @@ describe('euclideanAlgorithm', () => {
2020
expect(euclideanAlgorithm(105, 252)).toBe(21);
2121
expect(euclideanAlgorithm(1071, 462)).toBe(21);
2222
expect(euclideanAlgorithm(462, 1071)).toBe(21);
23+
expect(euclideanAlgorithm(462, -1071)).toBe(21);
24+
expect(euclideanAlgorithm(-462, -1071)).toBe(21);
2325
});
2426
});
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
/**
2-
* @param {number} a
3-
* @param {number} b
2+
* @param {number} originalA
3+
* @param {number} originalB
44
* @return {number|null}
55
*/
6-
export default function euclideanAlgorithm(a, b) {
6+
export default function euclideanAlgorithm(originalA, originalB) {
7+
const a = Math.abs(originalA);
8+
const b = Math.abs(originalB);
9+
710
if (a === 0 && b === 0) {
811
return null;
912
}
@@ -16,9 +19,14 @@ export default function euclideanAlgorithm(a, b) {
1619
return a;
1720
}
1821

22+
// Normally we need to do subtraction (a - b) but to prevent
23+
// recursion occurs to often we may shorten subtraction to (a % b).
24+
// Since (a % b) is normally means that we've subtracted b from a
25+
// many times until the difference became less then a.
26+
1927
if (a > b) {
20-
return euclideanAlgorithm(a - b, b);
28+
return euclideanAlgorithm(a % b, b);
2129
}
2230

23-
return euclideanAlgorithm(b - a, a);
31+
return euclideanAlgorithm(b % a, a);
2432
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# Least common multiple
2+
3+
In arithmetic and number theory, the least common multiple,
4+
lowest common multiple, or smallest common multiple of
5+
two integers `a` and `b`, usually denoted by `LCM(a, b)`, is
6+
the smallest positive integer that is divisible by
7+
both `a` and `b`. Since division of integers by zero is
8+
undefined, this definition has meaning only if `a` and `b` are
9+
both different from zero. However, some authors define `lcm(a,0)`
10+
as `0` for all `a`, which is the result of taking the `lcm`
11+
to be the least upper bound in the lattice of divisibility.
12+
13+
## Example
14+
15+
What is the LCM of 4 and 6?
16+
17+
Multiples of `4` are:
18+
19+
```
20+
4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, ...
21+
```
22+
23+
and the multiples of `6` are:
24+
25+
```
26+
6, 12, 18, 24, 30, 36, 42, 48, 54, 60, 66, 72, ...
27+
```
28+
29+
Common multiples of `4` and `6` are simply the numbers
30+
that are in both lists:
31+
32+
```
33+
12, 24, 36, 48, 60, 72, ....
34+
```
35+
36+
So, from this list of the first few common multiples of
37+
the numbers `4` and `6`, their least common multiple is `12`.
38+
39+
## Computing the least common multiple
40+
41+
The following formula reduces the problem of computing the
42+
least common multiple to the problem of computing the greatest
43+
common divisor (GCD), also known as the greatest common factor:
44+
45+
```
46+
lcm(a, b) = |a * b| / gcd(a, b)
47+
```
48+
49+
![LCM](https://upload.wikimedia.org/wikipedia/commons/c/c9/Symmetrical_5-set_Venn_diagram_LCM_2_3_4_5_7.svg)
50+
51+
A Venn diagram showing the least common multiples of
52+
combinations of `2`, `3`, `4`, `5` and `7` (`6` is skipped as
53+
it is `2 × 3`, both of which are already represented).
54+
55+
For example, a card game which requires its cards to be
56+
divided equally among up to `5` players requires at least `60`
57+
cards, the number at the intersection of the `2`, `3`, `4`
58+
and `5` sets, but not the `7` set.
59+
60+
## References
61+
62+
[Wikipedia](https://en.wikipedia.org/wiki/Least_common_multiple)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import leastCommonMultiple from '../leastCommonMultiple';
2+
3+
describe('leastCommonMultiple', () => {
4+
it('should find least common multiple', () => {
5+
expect(leastCommonMultiple(0, 0)).toBe(0);
6+
expect(leastCommonMultiple(1, 0)).toBe(0);
7+
expect(leastCommonMultiple(0, 1)).toBe(0);
8+
expect(leastCommonMultiple(4, 6)).toBe(12);
9+
expect(leastCommonMultiple(6, 21)).toBe(42);
10+
expect(leastCommonMultiple(7, 2)).toBe(14);
11+
expect(leastCommonMultiple(3, 5)).toBe(15);
12+
expect(leastCommonMultiple(7, 3)).toBe(21);
13+
expect(leastCommonMultiple(1000000, 2)).toBe(1000000);
14+
expect(leastCommonMultiple(-9, -18)).toBe(18);
15+
expect(leastCommonMultiple(-7, -9)).toBe(63);
16+
expect(leastCommonMultiple(-7, 9)).toBe(63);
17+
});
18+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import euclideanAlgorithm from '../euclidean-algorithm/euclideanAlgorithm';
2+
3+
/**
4+
* @param {number} a
5+
* @param {number} b
6+
* @return {number}
7+
*/
8+
9+
export default function leastCommonMultiple(a, b) {
10+
if (a === 0 && b === 0) {
11+
return 0;
12+
}
13+
14+
return Math.abs(a * b) / euclideanAlgorithm(a, b);
15+
}

0 commit comments

Comments
 (0)
Please sign in to comment.