|
1 | | -/* |
2 | | -Smallest multiple |
| 1 | +import { PrimeFactors } from '../Maths/PrimeFactors.js' |
3 | 2 |
|
4 | | -2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder. |
5 | | -What is the smallest positive number that is evenly divisible by all of the numbers from 1 to 20? |
6 | | -*/ |
| 3 | +/** |
| 4 | + * Smallest Multiple |
| 5 | + * @link https://projecteuler.net/problem=5 |
| 6 | + * |
| 7 | + * 2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder. |
| 8 | + * |
| 9 | + * What is the smallest positive number that is evenly divisible by all of the numbers from 1 to 20? |
| 10 | + */ |
7 | 11 |
|
8 | | -export const findSmallestMultiple = (maxDivisor) => { |
9 | | - const divisors = Array.from({ length: maxDivisor }, (_, i) => i + 1) |
10 | | - let num = maxDivisor + 1 |
11 | | - let result |
| 12 | +export function findSmallestMultiple(maxDivisor) { |
| 13 | + const maxPowers = {} |
| 14 | + for (let divisor = 2; divisor <= maxDivisor; divisor++) { |
| 15 | + const factors = PrimeFactors(divisor) |
12 | 16 |
|
13 | | - while (!result) { |
14 | | - const isDivisibleByAll = divisors.every((divisor) => num % divisor === 0) |
15 | | - if (isDivisibleByAll) result = num |
16 | | - else num++ |
| 17 | + // combine/count prime factors |
| 18 | + let powers = {} |
| 19 | + for (const factor of factors) { |
| 20 | + powers[factor] = (powers[factor] ?? 0) + 1 |
| 21 | + } |
| 22 | + |
| 23 | + // save largest factors |
| 24 | + for (const factor in powers) { |
| 25 | + if (powers[factor] > (maxPowers[factor] ?? 0)) { |
| 26 | + maxPowers[factor] = powers[factor] |
| 27 | + } |
| 28 | + } |
17 | 29 | } |
18 | 30 |
|
19 | | - return result |
| 31 | + // multiply all primes |
| 32 | + return Object.entries(maxPowers).reduce( |
| 33 | + (product, [prime, power]) => product * Math.pow(prime, power), |
| 34 | + 1 |
| 35 | + ) |
20 | 36 | } |
0 commit comments