Coin Partitions
Let p(n) represent the number of different ways in which n coins can be separated into piles. Find the least value of n for which p(n) is divisible by one million.
Problem Statement
This archive keeps the full statement, math, and original media on the page.
Let
OOOO O
OOO OO
OOO O O
OO OO O
OO O O O
O O O O O
Find the least value of
Problem 78: Coin Partitions
Mathematical Foundation
Definition 1 (Generalized Pentagonal Numbers). The generalized pentagonal numbers are the values
The sequence lists these in increasing order.
Theorem 1 (Euler’s Pentagonal Number Theorem). As formal power series (and absolutely for ):
Proof (Franklin’s Involution). The coefficient of in equals , where is the set of partitions of into distinct parts and is the number of parts.
For , define:
- : the smallest part.
- : the length of the maximal run of consecutive integers descending from , i.e., .
Construct the involution :
- Move A (when , or when and the smallest part is not part of the top run, i.e., ): Remove and add to each of the largest parts. The result has distinct parts.
- Move B (when Move A is inapplicable): Subtract from each of the largest parts and insert as a new smallest part. The result has distinct parts.
These operations satisfy: (i) (they are mutual inverses), (ii) each changes the parity of , hence reverses the sign , and (iii) the map is undefined (fixed point) exactly when:
- and : giving and .
- and : giving .
Fixed points contribute ; all other terms cancel pairwise.
Theorem 2 (Partition Recurrence). For :
where , for , and the sum terminates when both and exceed .
Proof. From Theorem 1 and the partition generating function , we obtain
Extracting the coefficient of for :
Multiplying through by and using yields the recurrence.
Lemma 1 (Pentagonal Number Count). The number of generalized pentagonal numbers not exceeding is .
Proof. From , we obtain . Similarly for .
Theorem 3 (Validity of Modular Computation). The recurrence in Theorem 2 is a -linear combination of previous partition values with coefficients in . Therefore, for any modulus , computing at each step using for correctly yields .
Proof. Since addition and subtraction in satisfy and , the modular reduction commutes with the recurrence at each step.
Editorial
Euler’s pentagonal recurrence is the whole algorithm. It expresses as an alternating sum of earlier partition values taken at offsets given by the generalized pentagonal numbers. So instead of building partitions explicitly, we generate only the offsets that can actually contribute and combine previously computed values with the required signs.
Because the problem only asks when becomes divisible by one million, we never need the full integers. Reducing modulo after every step preserves the divisibility test and keeps the numbers small. The candidates in each recurrence step are the pentagonal offsets not exceeding the current ; larger offsets are ignored because they would reference negative indices. We advance in order and stop as soon as the partition value becomes .
Pseudocode
Precompute the generalized pentagonal numbers up to a safe search limit, together with their alternating signs.
Set p(0) = 1.
For n from 1 upward:
start the new partition value at 0
For each precomputed pentagonal offset that does not exceed n:
add or subtract the previously computed partition value indicated by its sign
Reduce the result modulo one million
If the result is 0:
return n
Complexity Analysis
Time: Each computation of involves summing over pentagonal terms (Lemma 1). Summing over all from to (the answer):
With , this is approximately operations.
Space: entries storing for .
Answer
Code
Each problem page includes the exact C++ and Python source files from the local archive.
#include <bits/stdc++.h>
using namespace std;
int main() {
const int MOD = 1000000;
const int MAXN = 100000;
vector<int> p(MAXN + 1, 0);
p[0] = 1;
// Precompute generalized pentagonal numbers with signs
vector<pair<int, int>> pent; // (pentagonal number, sign)
for (int k = 1; ; k++) {
int g1 = k * (3 * k - 1) / 2;
int g2 = k * (3 * k + 1) / 2;
if (g1 > MAXN) break;
int sign = (k % 2 == 1) ? 1 : -1;
pent.push_back({g1, sign});
if (g2 <= MAXN)
pent.push_back({g2, sign});
}
for (int n = 1; n <= MAXN; n++) {
long long val = 0;
for (auto& [g, s] : pent) {
if (g > n) break;
val += (long long)s * p[n - g];
}
p[n] = ((int)(val % MOD) + MOD) % MOD;
if (p[n] == 0) {
cout << n << endl;
return 0;
}
}
return 0;
}
"""
Problem 78: Coin Partitions
Find the least value of n for which p(n) is divisible by one million.
Answer: 55374
"""
def main():
MOD = 1_000_000
MAXN = 100_000
# Precompute generalized pentagonal numbers with signs
pentagonals = []
for k in range(1, 1000):
g1 = k * (3 * k - 1) // 2
g2 = k * (3 * k + 1) // 2
if g1 > MAXN:
break
sign = 1 if k % 2 == 1 else -1
pentagonals.append((g1, sign))
if g2 <= MAXN:
pentagonals.append((g2, sign))
p = [0] * (MAXN + 1)
p[0] = 1
for n in range(1, MAXN + 1):
val = 0
for g, s in pentagonals:
if g > n:
break
val += s * p[n - g]
p[n] = val % MOD
if p[n] == 0:
print(n)
return
print(-1)
if __name__ == "__main__":
main()