mirror of
https://github.moeyy.xyz/https://github.com/trekhleb/javascript-algorithms.git
synced 2024-11-10 11:09:43 +08:00
Add lcm.
This commit is contained in:
parent
34522c8087
commit
91457191b1
@ -33,10 +33,9 @@
|
|||||||
* [Power Set](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/math/power-set)
|
* [Power Set](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/math/power-set)
|
||||||
* [Primality Test](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/math/primality-test) (trial division)
|
* [Primality Test](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/math/primality-test) (trial division)
|
||||||
* [Euclidean Algorithm](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/math/euclidean-algorithm) - calculate the greatest common divisor (GCD)
|
* [Euclidean Algorithm](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/math/euclidean-algorithm) - calculate the greatest common divisor (GCD)
|
||||||
|
* [Least Common Multiple (LCM)](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/math/least-common-multiple)
|
||||||
* [Fisher–Yates Shuffle](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/math/fisher-yates) - random permutation of a finite sequence
|
* [Fisher–Yates Shuffle](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/math/fisher-yates) - random permutation of a finite sequence
|
||||||
* Collatz Conjecture algorithm
|
* Collatz Conjecture algorithm
|
||||||
* Greatest Difference
|
|
||||||
* Least Common Multiple
|
|
||||||
* Newton's square
|
* Newton's square
|
||||||
* Shannon Entropy
|
* Shannon Entropy
|
||||||
* **String**
|
* **String**
|
||||||
|
@ -20,5 +20,7 @@ describe('euclideanAlgorithm', () => {
|
|||||||
expect(euclideanAlgorithm(105, 252)).toBe(21);
|
expect(euclideanAlgorithm(105, 252)).toBe(21);
|
||||||
expect(euclideanAlgorithm(1071, 462)).toBe(21);
|
expect(euclideanAlgorithm(1071, 462)).toBe(21);
|
||||||
expect(euclideanAlgorithm(462, 1071)).toBe(21);
|
expect(euclideanAlgorithm(462, 1071)).toBe(21);
|
||||||
|
expect(euclideanAlgorithm(462, -1071)).toBe(21);
|
||||||
|
expect(euclideanAlgorithm(-462, -1071)).toBe(21);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
/**
|
/**
|
||||||
* @param {number} a
|
* @param {number} originalA
|
||||||
* @param {number} b
|
* @param {number} originalB
|
||||||
* @return {number|null}
|
* @return {number|null}
|
||||||
*/
|
*/
|
||||||
export default function euclideanAlgorithm(a, b) {
|
export default function euclideanAlgorithm(originalA, originalB) {
|
||||||
|
const a = Math.abs(originalA);
|
||||||
|
const b = Math.abs(originalB);
|
||||||
|
|
||||||
if (a === 0 && b === 0) {
|
if (a === 0 && b === 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -16,9 +19,14 @@ export default function euclideanAlgorithm(a, b) {
|
|||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Normally we need to do subtraction (a - b) but to prevent
|
||||||
|
// recursion occurs to often we may shorten subtraction to (a % b).
|
||||||
|
// Since (a % b) is normally means that we've subtracted b from a
|
||||||
|
// many times until the difference became less then a.
|
||||||
|
|
||||||
if (a > b) {
|
if (a > b) {
|
||||||
return euclideanAlgorithm(a - b, b);
|
return euclideanAlgorithm(a % b, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
return euclideanAlgorithm(b - a, a);
|
return euclideanAlgorithm(b % a, a);
|
||||||
}
|
}
|
||||||
|
62
src/algorithms/math/least-common-multiple/README.md
Normal file
62
src/algorithms/math/least-common-multiple/README.md
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
# Least common multiple
|
||||||
|
|
||||||
|
In arithmetic and number theory, the least common multiple,
|
||||||
|
lowest common multiple, or smallest common multiple of
|
||||||
|
two integers `a` and `b`, usually denoted by `LCM(a, b)`, is
|
||||||
|
the smallest positive integer that is divisible by
|
||||||
|
both `a` and `b`. Since division of integers by zero is
|
||||||
|
undefined, this definition has meaning only if `a` and `b` are
|
||||||
|
both different from zero. However, some authors define `lcm(a,0)`
|
||||||
|
as `0` for all `a`, which is the result of taking the `lcm`
|
||||||
|
to be the least upper bound in the lattice of divisibility.
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
What is the LCM of 4 and 6?
|
||||||
|
|
||||||
|
Multiples of `4` are:
|
||||||
|
|
||||||
|
```
|
||||||
|
4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, ...
|
||||||
|
```
|
||||||
|
|
||||||
|
and the multiples of `6` are:
|
||||||
|
|
||||||
|
```
|
||||||
|
6, 12, 18, 24, 30, 36, 42, 48, 54, 60, 66, 72, ...
|
||||||
|
```
|
||||||
|
|
||||||
|
Common multiples of `4` and `6` are simply the numbers
|
||||||
|
that are in both lists:
|
||||||
|
|
||||||
|
```
|
||||||
|
12, 24, 36, 48, 60, 72, ....
|
||||||
|
```
|
||||||
|
|
||||||
|
So, from this list of the first few common multiples of
|
||||||
|
the numbers `4` and `6`, their least common multiple is `12`.
|
||||||
|
|
||||||
|
## Computing the least common multiple
|
||||||
|
|
||||||
|
The following formula reduces the problem of computing the
|
||||||
|
least common multiple to the problem of computing the greatest
|
||||||
|
common divisor (GCD), also known as the greatest common factor:
|
||||||
|
|
||||||
|
```
|
||||||
|
lcm(a, b) = |a * b| / gcd(a, b)
|
||||||
|
```
|
||||||
|
|
||||||
|
![LCM](https://upload.wikimedia.org/wikipedia/commons/c/c9/Symmetrical_5-set_Venn_diagram_LCM_2_3_4_5_7.svg)
|
||||||
|
|
||||||
|
A Venn diagram showing the least common multiples of
|
||||||
|
combinations of `2`, `3`, `4`, `5` and `7` (`6` is skipped as
|
||||||
|
it is `2 × 3`, both of which are already represented).
|
||||||
|
|
||||||
|
For example, a card game which requires its cards to be
|
||||||
|
divided equally among up to `5` players requires at least `60`
|
||||||
|
cards, the number at the intersection of the `2`, `3`, `4`
|
||||||
|
and `5` sets, but not the `7` set.
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
[Wikipedia](https://en.wikipedia.org/wiki/Least_common_multiple)
|
@ -0,0 +1,18 @@
|
|||||||
|
import leastCommonMultiple from '../leastCommonMultiple';
|
||||||
|
|
||||||
|
describe('leastCommonMultiple', () => {
|
||||||
|
it('should find least common multiple', () => {
|
||||||
|
expect(leastCommonMultiple(0, 0)).toBe(0);
|
||||||
|
expect(leastCommonMultiple(1, 0)).toBe(0);
|
||||||
|
expect(leastCommonMultiple(0, 1)).toBe(0);
|
||||||
|
expect(leastCommonMultiple(4, 6)).toBe(12);
|
||||||
|
expect(leastCommonMultiple(6, 21)).toBe(42);
|
||||||
|
expect(leastCommonMultiple(7, 2)).toBe(14);
|
||||||
|
expect(leastCommonMultiple(3, 5)).toBe(15);
|
||||||
|
expect(leastCommonMultiple(7, 3)).toBe(21);
|
||||||
|
expect(leastCommonMultiple(1000000, 2)).toBe(1000000);
|
||||||
|
expect(leastCommonMultiple(-9, -18)).toBe(18);
|
||||||
|
expect(leastCommonMultiple(-7, -9)).toBe(63);
|
||||||
|
expect(leastCommonMultiple(-7, 9)).toBe(63);
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,15 @@
|
|||||||
|
import euclideanAlgorithm from '../euclidean-algorithm/euclideanAlgorithm';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {number} a
|
||||||
|
* @param {number} b
|
||||||
|
* @return {number}
|
||||||
|
*/
|
||||||
|
|
||||||
|
export default function leastCommonMultiple(a, b) {
|
||||||
|
if (a === 0 && b === 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Math.abs(a * b) / euclideanAlgorithm(a, b);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user