From 317442de5eb934369c35aac91874bae4e105da2e Mon Sep 17 00:00:00 2001 From: Oleksandr Tkachenko <41586082+WOLFRIEND@users.noreply.github.com> Date: Fri, 5 Jan 2024 18:16:41 +0200 Subject: [PATCH] fix(curriculum): Inefficient solution for the "Problem 78: Coin partitions" challenge. (#52880) --- .../problem-78-coin-partitions.md | 40 +++++++++---------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/curriculum/challenges/english/18-project-euler/project-euler-problems-1-to-100/problem-78-coin-partitions.md b/curriculum/challenges/english/18-project-euler/project-euler-problems-1-to-100/problem-78-coin-partitions.md index 65d3ebad7e4..26428a8ccaf 100644 --- a/curriculum/challenges/english/18-project-euler/project-euler-problems-1-to-100/problem-78-coin-partitions.md +++ b/curriculum/challenges/english/18-project-euler/project-euler-problems-1-to-100/problem-78-coin-partitions.md @@ -74,30 +74,28 @@ coinPartitions(7); # --solutions-- ```js +// compute pentagonal numbers per generating function +const pentagonalNumbers = Array(251) + .fill(0) + .flatMap((_, i) => i ? [i * (3 * i - 1) / 2, i * (3 * i - 1) / 2 + i] : []); + function coinPartitions(divisor) { - const partitions = [1]; + // helper data + const signs = [1, 1, -1, -1]; - let n = 0; - while (partitions[n] !== 0) { - n++; - partitions.push(0); - - let i = 0; - let pentagonal = 1; - while (pentagonal <= n) { - const sign = i % 4 > 1 ? -1 : 1; - partitions[n] += sign * partitions[n - pentagonal]; - partitions[n] = partitions[n] % divisor; - - i++; - - let k = Math.floor(i / 2) + 1; - if (i % 2 !== 0) { - k *= -1; - } - pentagonal = Math.floor((k * (3 * k - 1)) / 2); + // compute partition counts until we find a multiple of divisor + const partitions = Array(divisor + 1).fill(0); + partitions[0] = 1; + for (let i = 1; partitions[i - 1] > 0; i++) { + // compute next partition count + for (let j = 0; pentagonalNumbers[j] <= i; j++) { + partitions[i] += partitions[i - pentagonalNumbers[j]] * signs[j % 4]; } + + partitions[i] = partitions[i] % divisor; + if (partitions[i] < 0) partitions[i] += divisor; // positive mod + // return when found + if (partitions[i] === 0) return i; } - return n; } ```