All Euler problems
Project Euler

Product-sum Numbers

A natural number N can be written as both the sum and product of a set of at least two natural numbers {a_1, a_2,..., a_k}: N = a_1 + a_2 +... + a_k = a_1 x a_2 x... x a_k For a given k, the smalle...

Source sync Apr 19, 2026
Problem #0088
Level Level 04
Solved By 12,002
Languages C++, Python
Answer 7587457
Length 367 words
modular_arithmeticbrute_forcegeometry

Problem Statement

This archive keeps the full statement, math, and original media on the page.

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. \begin {align*} 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 \end {align*}

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\)?

Problem 88: Product-sum Numbers

Mathematical Analysis

Key Observation

Given a set of numbers with product PP and sum SS where PSP \ge S, we can always pad the set with (PS)(P - S) ones to make the sum equal the product. The resulting set has size k=(PS)+(number of non-one elements)k = (P - S) + (\text{number of non-one elements}).

So for any factorization of NN into factors f1,f2,,fmf_1, f_2, \ldots, f_m (each 2\ge 2), the corresponding kk is:

k=N(f1+f2++fm)+mk = N - (f_1 + f_2 + \cdots + f_m) + m

because we add NfiN - \sum f_i ones, giving total count m+(Nfi)=Nfi+mm + (N - \sum f_i) = N - \sum f_i + m.

Bounds

Upper bound on NkN_k: For any kk, we can always use {2,k,1,1,,1}\{2, k, 1, 1, \ldots, 1\} (with k2k-2 ones) giving product =2k= 2k and sum =2+k+(k2)=2k= 2 + k + (k-2) = 2k. So Nk2kN_k \le 2k.

For k12000k \le 12000, we have Nk24000N_k \le 24000.

Lower bound: NkkN_k \ge k since the sum of kk numbers each 1\ge 1 is at least kk.

Editorial

The important simplification is that the ones never need to be generated explicitly. Once a factorization into numbers at least 2 is fixed, the number of ones required is forced, so the corresponding set size is determined by

k=Nfi+m.k = N - \sum f_i + m.

That means the search is really over multiplicative cores rather than over full product-sum sets. The implementation checks each candidate value NN up to the standard bound 2kmax2k_{\max}, recursively enumerates its factorizations in nondecreasing order to avoid duplicates, and turns each factorization into the implied value of kk. Whenever that kk is in range, we update the best known product-sum number for that set size. At the end we take the distinct minima and sum them.

Pseudocode

Create an array best where best[k] stores the smallest product-sum number found for that k.

For each candidate value N from 2 up to 2 x 12000:
    Recursively enumerate factorizations of N into nondecreasing factors at least 2

    For each complete factorization:
        compute the implied set size k using the product-sum formula
        if 2 <= k <= 12000 and N improves best[k], update best[k]

After all candidates have been processed:
    collect the distinct values among best[2] through best[12000]
    return their sum

Factorization Enumeration

We use a recursive approach: for each NN, enumerate factorizations where factors are in non-decreasing order (to avoid duplicates). Start with the smallest factor 2\ge 2 and recurse on N/fN / f.

Correctness

Theorem. The method described above computes exactly the quantity requested in the problem statement.

Proof. The preceding analysis identifies the admissible objects and derives the formula, recurrence, or exhaustive search carried out by the algorithm. The computation evaluates exactly that specification, so every valid contribution is included once and no invalid contribution is counted. Therefore the returned value is the required answer. \square

Complexity Analysis

  • Time: O(Nmaxd(N))O(N_{\max} \cdot d(N)) where d(N)d(N) is the number of factorizations. In practice, very fast since most numbers have few factorizations.
  • Space: O(kmax)O(k_{\max}) for storing the minimal value per kk.

Answer

7587457\boxed{7587457}

Code

Each problem page includes the exact C++ and Python source files from the local archive.

C++ project_euler/problem_088/solution.cpp
#include <bits/stdc++.h>
using namespace std;

const int KMAX = 12000;
int best[KMAX + 1];

// Enumerate factorizations of N.
// prod = current product so far, sum_f = sum of factors so far,
// count = number of factors so far, min_factor = minimum next factor.
// We are building factorizations of the target number N = prod * (remaining).
void factorize(int n, int prod, int sum_f, int count, int min_factor) {
    // n is the remaining part to factorize (prod * n = original N)
    // At any point, we can stop and use n as the last factor
    // Last factor is n itself (n >= min_factor is required)
    if (n >= min_factor) {
        int total_prod = prod * n;
        int total_sum = sum_f + n;
        int total_count = count + 1;
        if (total_count >= 2) {
            int k = total_prod - total_sum + total_count;
            if (k >= 2 && k <= KMAX) {
                if (total_prod < best[k]) {
                    best[k] = total_prod;
                }
            }
        }
    }

    // Try splitting n further: pick factor f from min_factor to sqrt(n)
    for (int f = min_factor; (long long)f * f <= n; f++) {
        if (n % f == 0) {
            factorize(n / f, prod * f, sum_f + f, count + 1, f);
        }
    }
}

int main() {
    fill(best, best + KMAX + 1, INT_MAX);

    // Upper bound: N_k <= 2k, so we check N up to 2 * KMAX
    for (int N = 2; N <= 2 * KMAX; N++) {
        factorize(N, 1, 0, 0, 2);
    }

    // Sum distinct minimal product-sum numbers
    set<int> distinct;
    for (int k = 2; k <= KMAX; k++) {
        distinct.insert(best[k]);
    }

    long long answer = 0;
    for (int v : distinct) answer += v;

    cout << answer << endl;
    return 0;
}