codexinteger-partitions-of-five.py
integer-partitions-of-five.py
"""Enumerate and draw Ferrers diagrams; Python 3.14.4, matplotlib 3.10.7.
Write integer-partitions-of-five.png in the current directory.
"""
from itertools import combinations_with_replacement
from pathlib import Path
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
def partitions(total, largest=None):
if total == 0:
yield ()
return
if largest is None:
largest = total
for part in range(min(total, largest), 0, -1):
for tail in partitions(total - part, part):
yield (part,) + tail
def main():
values = list(partitions(5))
independent = {tuple(reversed(parts)) for length in range(1, 6)
for parts in combinations_with_replacement(range(1, 6), length)
if sum(parts) == 5}
assert len(values) == 7 and set(values) == independent
coefficients = [1] + [0] * 5
for part in range(1, 6):
for total in range(part, 6):
coefficients[total] += coefficients[total - part]
assert coefficients == [len(list(partitions(n))) for n in range(6)] == [1, 1, 2, 3, 5, 7]
fig = plt.figure(figsize=(9, 5.9), dpi=120, facecolor="white")
for index, parts in enumerate(values):
row, column = divmod(index, 4)
left = 0.03 + column * 0.24 + (0.12 if row == 1 else 0)
bottom = 0.50 if row == 0 else 0.10
ax = fig.add_axes((left, bottom, 0.22, 0.31))
ax.set(xlim=(-0.5, 4.5), ylim=(4.5, -0.7))
ax.set_aspect("equal")
ax.axis("off")
for i, part in enumerate(parts):
ax.scatter(range(part), [i] * part, s=92, color="#186c9c")
ax.set_title(" + ".join(map(str, parts)), fontsize=12, pad=8,
color="#253746")
fig.suptitle("The seven integer partitions of five", fontsize=16, y=0.98)
fig.text(0.5, 0.89, "One dot per unit; row lengths decrease from top to bottom.",
ha="center", fontsize=11, color="#253746")
fig.text(0.5, 0.035, "Order of summands is ignored: 3 + 2 and 2 + 3 give the same partition.",
ha="center", fontsize=11, color="#253746")
fig.savefig(Path.cwd() / Path(__file__).with_suffix(".png").name,
facecolor="white", transparent=False)
plt.close(fig)
print(f"Independent enumerations agree: {values}; coefficients through degree five: {coefficients}.")
if __name__ == "__main__":
main()