Project Euler Problem 76
It is possible to write five as a sum in exactly six different ways: How many different ways can one hundred be written
Solution
Answer: 190569291
1. Mathematical analysis
We want the number of ways to write 100 as a sum of at least two positive integers, where order does not matter.
For example:
$$5 = 4+1 = 3+2 = 3+1+1 = 2+2+1 = 2+1+1+1 = 1+1+1+1+1$$
There are 6 ways.
This is exactly the problem of counting integer partitions.
Let:
$$p(n)$$
be the number of partitions of $n$, i.e. the number of unordered ways to write $n$ as a sum of positive integers.
However, $p(n)$ includes the trivial partition:
$$n$$
itself. Since the problem asks for at least two positive integers, we must subtract 1.
So the desired quantity is:
$$p(100)-1$$
The challenge is computing $p(100)$.
Dynamic programming interpretation
This is equivalent to a coin change problem:
- available “coins”: $1,2,3,\dots,99$
- target sum: $100$
- unlimited use of each coin
- order does not matter.
Define:
$$dp[s]$$
= number of ways to make sum $s$.
Initially:
$$dp[0] = 1$$
because there is exactly one way to make zero: choose nothing.
For each integer $k$, update:
$$dp[s] \mathrel{+}= dp[s-k]$$
for all $s \ge k$.
Why does this work?
When processing number $k$:
- every partition of $s-k$ can be extended by adding $k$,
- and because we process numbers in increasing order, permutations are not double-counted.
This is the standard partition DP recurrence.
For the example $n=5$:
Using integers $1,2,3,4$, the DP gives:
$$dp[5] = 6$$
matching the problem statement.
For $100$, we compute:
$$p(100)-1$$
2. Python implementation
def count_partitions(n):
"""
Count the number of ways to write n as a sum
of at least two positive integers.
"""
# dp[s] = number of partitions of s
dp = [0] * (n + 1)
# One way to form sum 0: choose nothing
dp[0] = 1
# Use numbers 1 through n-1
# (excluding n itself removes the trivial partition)
for part in range(1, n):
for total in range(part, n + 1):
dp[total] += dp[total - part]
return dp[n]
# Compute the Project Euler answer
answer = count_partitions(100)
print(answer)
3. Code walkthrough
Function definition
def count_partitions(n):
Defines a function to count valid partitions of $n$.
Create DP table
dp = [0] * (n + 1)
We create an array:
$$dp[0], dp[1], \dots, dp[n]$$
initialized to zero.
Base case
dp[0] = 1
There is exactly one way to form sum 0: choose no numbers.
This base case allows larger sums to build recursively.
Iterate through allowable parts
for part in range(1, n):
We allow integers:
$$1,2,\dots,n-1$$
We intentionally exclude $n$ itself so that the partition:
$$n$$
is not counted.
Update reachable totals
for total in range(part, n + 1):
dp[total] += dp[total - part]
If we want to form total using part, then every way to form:
$$\text{total} - \text{part}$$
extends to a new partition by adding part.
The recurrence is:
$$dp[s] \leftarrow dp[s] + dp[s-k]$$
Return answer
return dp[n]
After processing all parts, dp[n] contains the number of valid partitions.
Small example verification
For $n=5$:
Allowed parts: $1,2,3,4$
The DP counts:
$$4+1,; 3+2,; 3+1+1,; 2+2+1,; 2+1+1+1,; 1+1+1+1+1$$
Total:
$$6$$
which matches the problem statement exactly.
For $n=100$, the computation yields:
$$190569291$$
4. Final verification
A useful check:
The partition number is known to be
$$p(100)=190569292$$
Since the problem excludes the single-term partition:
$$100$$
we subtract one:
$$190569292 - 1 = 190569291$$
The magnitude is reasonable because partition numbers grow rapidly but remain far below exponential values like $2^{100}$.
Answer: 190569291