Smallest Common Multiple – Optimized Advanced Solution (#19572)
* Optimized advanced solution Made 2 minor improvement to the advanced solution: 1. The original advanced solution used `Math.max` and `Math.min` against the supplied array, this causes the values in the supplied array to be compared twice. If we use sort instead, the values are only compared once and we can target the max and min values using an index. This is more efficient. 2. The original solution caused `lcm(min, min + 1)` to be evaluated twice. By incrementing `min` the first time we run `lcm` we avoid this duplication and also by taking advantage of the prefix increment operator ++ in the while loop, we trim a line. * Fixed extra spaces in code block * Incorporated code feedback from #19572 Made the following changes to the advanced code solution: - Converted helper functions to arrow function constants - Simplified comments - Used destructuring and `sort` for `min` and `max` * Fixed spacing.
This commit is contained in:
committed by
Randell Dawson
parent
39fa46348e
commit
f0eb384b10
@ -153,45 +153,25 @@ Note: If the array only has two elements, then the `for` loop never gets used an
|
||||
|
||||
##  Advanced Code Solution:
|
||||
|
||||
function smallestCommons(arr) {
|
||||
function smallestCommons(arr) {
|
||||
// Euclidean algorithm for the greatest common divisor.
|
||||
// ref: https://en.wikipedia.org/wiki/Euclidean_algorithm
|
||||
const gcd = (a, b) => b === 0 ? a : gcd(b, a % b);
|
||||
|
||||
// range
|
||||
let min = Math.min.apply(null, arr);
|
||||
let max = Math.max.apply(null, arr);
|
||||
// Least Common Multiple for two numbers based on GCD
|
||||
const lcm = (a, b) => (a * b) / gcd(a, b);
|
||||
|
||||
let smallestCommon = lcm(min, min + 1);
|
||||
|
||||
while(min < max) {
|
||||
min++;
|
||||
smallestCommon = lcm(smallestCommon, min);
|
||||
}
|
||||
|
||||
return smallestCommon;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates Greatest Common Divisor
|
||||
* of two nubers using Euclidean algorithm
|
||||
* https://en.wikipedia.org/wiki/Euclidean_algorithm
|
||||
*/
|
||||
function gcd(a, b) {
|
||||
while (b > 0) {
|
||||
let tmp = a;
|
||||
a = b;
|
||||
b = tmp % b;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates Least Common Multiple
|
||||
* for two numbers utilising GCD
|
||||
*/
|
||||
function lcm(a, b) {
|
||||
return (a * b / gcd(a, b));
|
||||
}
|
||||
// range
|
||||
let [min, max] = arr.sort((a, b)=> a - b);
|
||||
let currentLCM = min;
|
||||
|
||||
while (min < max) {
|
||||
currentLCM = lcm(currentLCM, ++min);
|
||||
}
|
||||
|
||||
return currentLCM;
|
||||
};
|
||||
|
||||
// test here
|
||||
smallestCommons([1,5]);
|
||||
|
||||
@ -199,13 +179,13 @@ Note: If the array only has two elements, then the `for` loop never gets used an
|
||||
|
||||
### Code Explanation:
|
||||
|
||||
* Extract minimum and maximum from provided **arr**.
|
||||
* Extract minimum and maximum from provided **arr** by sorting and grabbing the first and last values.
|
||||
* Initialise **smallestCommon** with the LCM of first two numbers.
|
||||
* Loop through range computing LCM of current LCM and next number in range **lcm(a, b, c) = lcm(lcm(a, b), c)**.
|
||||
|
||||
#### Relevant Links
|
||||
|
||||
* <a href='https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply' target='_blank' rel='nofollow'>JS Function.prototype.apply()</a>
|
||||
* <a href='https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Increment' target='_blank' rel='nofollow'>Prefix increment operator ++</a>
|
||||
|
||||
|
||||
##  NOTES FOR CONTRIBUTIONS:
|
||||
|
Reference in New Issue
Block a user