Skip to content
Vamshi Jandhyala

Books · The Fiddler: Solutions

Chapter 92

Can You Pack the Circles?

You want to pack four rows of unit circles into a rectangle with a base of width 88. In square packing the four rows each hold four circles, stacked directly on top of one another. In hexagonal packing the bottom row holds four circles and the rows above alternate three and four, each nestled into the dimples of the row below. Which packing fits more circles per unit of area?

The Fiddler, Zach Wissner-Gross, June 14, 2024(original post)

Solution

Square packing puts 1616 circles in an 8×88\times8 box, a density of 16/64=1416/64=\tfrac14 circles per unit area. Hexagonal packing buys height: a circle nestled into a dimple sits a horizontal half-step (offset 11) from the circle below, and the two touch at centre-distance 22, so the rows are only 2212=3\sqrt{2^2-1^2}=\sqrt3 apart instead of 22. Four rows then reach height 2+337.1962+3\sqrt3\approx7.196, but they hold only 4+3+4+3=144+3+4+3=14 circles, for a density of 148(2+33)0.2432.\frac{14}{8\,(2+3\sqrt3)}\approx0.2432 . At just four rows the two circles lost from the short rows outweigh the height saved, so square packing is more efficient,\boxed{\text{square packing is more efficient,}} 0.250.25 to 0.2430.243.

The computation

Count circles over bounding area directly for each packing.

import math
sq = 16 / (8 * 8)                                  # 0.2500
hx = 14 / (8 * (2 + 3 * math.sqrt(3)))             # 0.2432
print(sq, hx)                                      # 0.25  0.2432

Extra Credit

Hexagonal packing must eventually win as the stack grows. From what height on is it strictly more efficient?

Solution

Square packing holds its density at exactly 14\tfrac14: nn rows give 4n4n circles in height 2n2n. Hexagonal density oscillates, higher when the top row is a full four and lower when it is a three, but both cases climb toward 3.583=73480.2526.\frac{3.5}{8\sqrt3}=\frac{7\sqrt3}{48}\approx0.2526 . The last stack where square still matches or beats hexagonal is 1414 rows; from 15 rows onward\boxed{15\ \text{rows onward}} (a height of 2+14326.22+14\sqrt3\approx26.2) hexagonal packing is strictly more efficient at every larger height.

The computation

Compute the hexagonal density row by row and find the first row count beyond which it stays above 14\tfrac14 for good.

def hex_density(n):                                # n rows, alternating 4, 3, 4, 3, ...
    circles = 4 * ((n + 1) // 2) + 3 * (n // 2)
    return circles / (8 * (2 + (n - 1) * math.sqrt(3)))
print(next(n for n in range(1, 100)
           if all(hex_density(m) > 0.25 for m in range(n, 100))))   # 15