From 675fd58f8b9ee032e854aa7a3e3e9e89c619707c Mon Sep 17 00:00:00 2001 From: Chris Hallberg Date: Wed, 3 Dec 2025 18:48:30 -0500 Subject: [PATCH 1/2] feat: use prime factors to speed up Euler 005. --- Project-Euler/Problem005.js | 44 +++++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/Project-Euler/Problem005.js b/Project-Euler/Problem005.js index 92f3df9b68..69b2e538fd 100644 --- a/Project-Euler/Problem005.js +++ b/Project-Euler/Problem005.js @@ -1,20 +1,36 @@ -/* -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? + */ -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 + ) } From 030a0fde9f18bde8ae70d17c52be25f77176d9df Mon Sep 17 00:00:00 2001 From: Chris Hallberg Date: Wed, 3 Dec 2025 18:58:11 -0500 Subject: [PATCH 2/2] doc: explain method. --- Project-Euler/Problem005.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Project-Euler/Problem005.js b/Project-Euler/Problem005.js index 69b2e538fd..32dfd10cf5 100644 --- a/Project-Euler/Problem005.js +++ b/Project-Euler/Problem005.js @@ -4,9 +4,11 @@ import { PrimeFactors } from '../Maths/PrimeFactors.js' * 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. + * 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? * - * 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 function findSmallestMultiple(maxDivisor) {