The number of partitions of a positive integer n, using parts up to size m, is the number of ways in which n can be expressed as the sum of positive integer parts up to m in increasing order. For example, the number of partitions of 6 using parts up to 4 is 9.
- 6 = 2 + 4
- 6 = 1 + 1 + 4
- 6 = 3 + 3
- 6 = 1 + 2 + 3
- 6 = 1 + 1 + 1 + 3
- 6 = 2 + 2 + 2
- 6 = 1 + 1 + 2 + 2
- 6 = 1 + 1 + 1 + 1 + 2
- 6 = 1 + 1 + 1 + 1 + 1 + 1
We will define a function count_partitions(n, m) that returns the number of different partitions of n using parts up to m. This function has a simple solution as a tree-recursive function, based on the following observation:
The number of ways to partition n using integers up to m equals
- the number of ways to partition n-m using integers up to m, and
- the number of ways to partition n using integers up to m-1.
To see why this is true, observe that all the ways of partitioning n can be divided into two groups: those that include at least one m and those that do not. Moreover, each partition in the first group is a partition of n-m, followed by m added at the end. In the example above, the first two partitions contain 4, and the rest do not.
Therefore, we can recursively reduce the problem of partitioning n using integers up to m into two simpler problems: (1) partition a smaller number n-m, and (2) partition with smaller components up to m-1.
To complete the implementation, we need to specify the following base cases:
- There is one way to partition 0: include no parts.
- There are 0 ways to partition a negative n.
- There are 0 ways to partition any n greater than 0 using parts of size 0 or less.
We can think of a tree-recursive function as exploring different possibilities. In this case, we explore the possibility that we use a part of size m and the possibility that we do not. The first and second recursive calls correspond to these possibilities.>>> def count_partitions(n, m):
"""Count the ways to partition n using parts up to m."""
if n == 0:
return 1
elif n < 0:
return 0
elif m == 0:
return 0
else:
return count_partitions(n-m, m) + count_partitions(n, m-1)
>>> count_partitions(6, 4)
9
>>> count_partitions(5, 5)
7
>>> count_partitions(10, 10)
42
>>> count_partitions(15, 15)
176
>>> count_partitions(20, 20)
627
Implementing this function without recursion would be substantially more involved. Interested readers are encouraged to try.