diff --git a/Project-Euler/Problem005.js b/Project-Euler/Problem005.js index 92f3df9b68..32dfd10cf5 100644 --- a/Project-Euler/Problem005.js +++ b/Project-Euler/Problem005.js @@ -1,20 +1,38 @@ -/* -Smallest multiple +import { PrimeFactors } from '../Maths/PrimeFactors.js' -2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder. -What is the smallest positive number that is evenly divisible by all of the numbers from 1 to 20? -*/ +/** + * Smallest Multiple + * @link https://projecteuler.net/problem=5 + * + * 2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder. What is the smallest positive number that is evenly divisible by all of the numbers from 1 to 20? + * + * Method: unique factorization + * @link https://en.wikipedia.org/wiki/Least_common_multiple#Using_prime_factorization + * The method used below calculates the Least Common Multiple (LCM) by multiplying the largest powers of the prime factors of the divisors. For example, 8 is the LCM of 2, 4, and 8. The prime factors of these numbers are 2^1, 2^2, and 2^3. We can discard 2^1 and 2^2 since 2^3 is the largest power of 2, leaving us with a result of 2^3 (8). + */ -export const findSmallestMultiple = (maxDivisor) => { - const divisors = Array.from({ length: maxDivisor }, (_, i) => i + 1) - let num = maxDivisor + 1 - let result +export function findSmallestMultiple(maxDivisor) { + const maxPowers = {} + for (let divisor = 2; divisor <= maxDivisor; divisor++) { + const factors = PrimeFactors(divisor) - while (!result) { - const isDivisibleByAll = divisors.every((divisor) => num % divisor === 0) - if (isDivisibleByAll) result = num - else num++ + // combine/count prime factors + let powers = {} + for (const factor of factors) { + powers[factor] = (powers[factor] ?? 0) + 1 + } + + // save largest factors + for (const factor in powers) { + if (powers[factor] > (maxPowers[factor] ?? 0)) { + maxPowers[factor] = powers[factor] + } + } } - return result + // multiply all primes + return Object.entries(maxPowers).reduce( + (product, [prime, power]) => product * Math.pow(prime, power), + 1 + ) }