Project Euler Problem 88 Statement
A natural number, $N$, that can be written as the sum and product of a given set of at least two natural numbers, $\{a_1, a_2, \dots, a_k\}$ is called a product-sum number: $N = a_1 + a_2 + \cdots + a_k = a_1 \times a_2 \times \cdots \times a_k$.
For example, $6 = 1 + 2 + 3 = 1 \times 2 \times 3$.
For a given set of size, $k$, we shall call the smallest $N$ with this property a minimal product-sum number. The minimal product-sum numbers for sets of size, $k = 2, 3, 4, 5$, and $6$ are as follows.
- $k=2$: $4 = 2 \times 2 = 2 + 2$
- $k=3$: $6 = 1 \times 2 \times 3 = 1 + 2 + 3$
- $k=4$: $8 = 1 \times 1 \times 2 \times 4 = 1 + 1 + 2 + 4$
- $k=5$: $8 = 1 \times 1 \times 2 \times 2 \times 2 = 1 + 1 + 2 + 2 + 2$
- $k=6$: $12 = 1 \times 1 \times 1 \times 1 \times 2 \times 6 = 1 + 1 + 1 + 1 + 2 + 6$
Hence for $2 \le k \le 6$, the sum of all the minimal product-sum numbers is $4+6+8+12 = 30$; note that $8$ is only counted once in the sum.
In fact, as the complete set of minimal product-sum numbers for $2 \le k \le 12$ is $\{4, 6, 8, 12, 15, 16\}$, the sum is $61$.
What is the sum of all the minimal product-sum numbers for $2 \le k \le 12000$?
Solution
Product-Sum Number
A natural number, \( N \), is called a product-sum number for a given \( k \) if it can be written as both the sum and the product of the same set of \( k \) positive integers. Formally:
\[ N = a_1 + a_2 + \dots + a_k = a_1 \times a_2 \times \dots \times a_k \]
For example, \( 6 = 1 + 2 + 3 = 1 \times 2 \times 3 \), so 6 is a product-sum number for \( k = 3 \).
Goal
For each \( k \) from 2 up to a specified maximum (denoted as \( k_{\text{max}} \)), find the minimal \( N \) that is a product-sum number for that \( k \). Finally, sum all unique minimal \( N \) values found for each \( k \).
Let's dissect the provided Python script:
def prodsum(p, s, c, start): k = p - s + c # product - sum + number of factors = k if k < kmax: if p < n[k]: n[k] = p # Update if we found a smaller product-sum for i in range(start, kmax//p * 2 + 1): prodsum(p*i, s+i, c+1, i) kmax = int(input())+1 n = [2*kmax] * kmax prodsum(1, 1, 1, 2) print(sum(set(n[2:])))
1. Function prodsum
This is a recursive function designed to explore all possible combinations of factors that can form product-sum numbers. Here's what each parameter represents:
p
(Product): The current product of the factors.s
(Sum): The current sum of the factors.c
(Count): The current number of factors.start
: The starting point for the next factor to ensure combinations are considered in non-decreasing order, avoiding duplicates.
Inside the Function:
Calculate \( k \)
\[ k = p - s + c \]
This formula derives from rearranging the product-sum equation:
\[ N = p = s \Rightarrow p - s = 0 \Rightarrow k = c \]
However, when introducing additional 1's into the factors (which don't change the product but increase the sum), \( k \) adjusts accordingly.
Check if \( k \) is within bounds
The function only processes combinations where \( k < k_{\text{max}} \). This ensures we only consider relevant \( k \) values.
Update Minimal Product-Sum \( N \)
If the current product \( p \) is smaller than the previously recorded minimal \( N \) for this \( k \), update it:
if p < n[k]: n[k] = p # Update if we found a smaller product-sum
Recursion to Explore Further Factors
The loop iterates through possible next factors, starting from start
to maintain non-decreasing order. The upper limit for the loop is determined by:
\[ \text{upper bound} = \frac{k_{\text{max}}}{p} \times 2 + 1 \]
This ensures that the product doesn't exceed the necessary bounds, optimizing the search.
For each possible next factor \( i \), the function recursively calls itself with updated parameters:
prodsum(p * i, s + i, c + 1, i)
2. Initialization and Execution
Input and Setup
kmax = int(input()) + 1
Reads the maximum \( k \) value from user input and adds 1 to accommodate Python's zero-based indexing.
Initialize the Minimal Product-Sum List
n = [2 * kmax] * kmax
Creates a list n
of size kmax
, initializing all entries to a high value (2 * kmax
). This list will store the minimal \( N \) for each \( k \).
Start the Recursive Search
prodsum(1, 1, 1, 2)
- Product \( p = 1 \)
- Sum \( s = 1 \)
- Count \( c = 1 \)
- Starting factor \( \text{start} = 2 \)
Compute the Final Sum
print(sum(set(n[2:])))
n[2:]
slices the list to exclude the first two entries (since \( k \) starts from 2).set(n[2:])
removes duplicate minimal \( N \) values to ensure uniqueness.sum(...)
calculates the total sum of these unique minimal \( N \) values.
How It Works Together
The prodsum
function explores all possible combinations of factors that can produce different \( N \) values for varying \( k \). By recursively multiplying and adding factors, it efficiently navigates through potential product-sum scenarios.
As the recursion progresses, it continuously updates the list n
with the smallest \( N \) found for each \( k \). This ensures that by the end of the recursion, n
contains the minimal product-sum numbers for all \( k \) up to kmax - 1
.
After populating the list n
, the script extracts the unique minimal \( N \) values and sums them, providing the desired output.
Example Walkthrough
Let's consider a small example with \( k_{\text{max}} = 12 \):
1. Initialization
kmax = 13 n = [26] * 13 # Since 2 * 13 = 26
2. Starting the Recursion
prodsum(1, 1, 1, 2)
This call begins exploring factor combinations starting with 2.
3. Recursive Calls
The function explores combinations like:
- \( 1 \times 2 = 2 \) and \( 1 + 2 = 3 \), leading to \( k = 2 - 3 + 1 = 0 \) (invalid, skipped).
-
\( 1 \times 2 \times 2 = 4 \) and \( 1 + 2 + 2 = 5 \), leading to \( k = 4 - 5 + 3 = 2 \).
-
Since \( 4 < 26 \), update
n[2] = 4
.
-
Since \( 4 < 26 \), update
- Continue exploring deeper combinations, updating
n[k]
wherever a smaller \( N \) is found.
4. Final Sum
After all recursive explorations, suppose n
is populated as:
n = [26, 26, 4, 6, 8, 6, 12, 12, 12, 12, 16, 18, 20]
Extracting unique values (excluding the first two):
\[ \{4, 6, 8, 12, 16, 18, 20\} \]
Summing them:
\[ 4 + 6 + 8 + 12 + 16 + 18 + 20 = 84 \]
So, the script would output 84
.
HackerRank version
HackerRank Project Euler 88: What is the sum of all the minimal product-sum numbers for $2\le k\le N$ $(10\le N\le 20000$?
Python Source Code
def prodsum(p, s, c, start):
k = p - s + c # product - sum + number of factors = k
if k < kmax:
if p < n[k]:
n[k] = p # Update if we found a smaller product-sum
for i in range(start, kmax//p * 2 + 1):
prodsum(p*i, s+i, c+1, i)
kmax = int(input())+1
n = [2*kmax] * kmax
prodsum(1, 1, 1, 2)
print(sum(set(n[2:])))