Library · The Fiddler: Solutions · Chapter 137
Iceberg, Right Ahead!
A large iceberg is a perfect cube. Because ice is less dense than water, percent of its mass sits above sea level and percent below. In its “optimal” orientation, the iceberg’s centre of mass is as deep below the water as possible. In that orientation, its highest point is a distance above sea level and its lowest point a distance below. What is the ratio ?
The Fiddler, Zach Wissner-Gross, November 3, 2023(original post)
The official solution appeared in the post of November 10, 2023 and gives for the main puzzle and about for the Extra Credit. Both agree with the answers below.
Solution
Take the cube to have side , with its centre at the origin. Whatever the orientation, the sea level is the horizontal plane that leaves exactly of the cube’s volume above it. The centre of mass is the centre of the cube, so its depth is just the distance from the centre up to that plane. If the cube’s highest point is above the centre, its lowest point is below it, by symmetry, and so The question is which way up makes largest. The natural candidates are the three most symmetric ones.
Face up. The top is a slab thick, so the water is above the centre: and .
Edge up. Every cross-section across the top edge is a square of side standing on a corner, so the part above water is a prism whose end is a right-angled isosceles triangle. With legs , its volume is , so , and the triangle’s height is . The top edge is above the centre, so .
Vertex up. The part above water is a corner of the cube: a pyramid with three mutually perpendicular edges of length meeting at the top, of volume , so . Its height above the waterline is . (The pyramid’s base is an equilateral triangle of side , whose centre is from each corner, and Pythagoras gives the height.) The top vertex is above the centre, so .
The vertex-up orientation, which looks the most “keel-like”, is the worst of the three. The reason is that a corner is a narrow place to cut: to put of the ice above water through a small triangular cross-section, the cut must come low, near the centre. Face up, the exposed ice is spread over a whole face, so a thin slab is enough and the waterline sits high above the centre. That the face-up orientation beats every tilted one, not just these three, is harder to prove by hand than it looks (the official write-up calls the proof “a beast”), and it is settled here by the computation below, which checks every orientation and finds none with above . So the iceberg floats face up, with and : The ratio is the same as the ratio of the volumes above and below water, as it must be for a slab.
The computation
The check searches over the directions that could point straight up. For each direction it finds the waterline by bisection, using an exact formula for the volume of the part of a cube on one side of a plane (inclusion and exclusion over the corners the plane has passed), and records how deep the centre sits. By symmetry it is enough to search one eighth of the directions, on a grid of angles that stops just short of the faces, where the formula would divide by zero.
from itertools import combinations
from math import acos, cos, degrees, pi, sin
def below(n, s):
"""Volume of the unit cube [0,1]^3 with n.u <= s, for a
direction n with positive parts (inclusion-exclusion over
the corners the plane has passed)."""
a, b, c = n
total = 0.0
for k in range(4):
for S in combinations(n, k):
total += (-1) ** k * max(0.0, s - sum(S)) ** 3
return total / (6 * a * b * c)
def depth(n):
"""Depth of the cube's centre below the water when n
points straight up: find the plane leaving 10% of the
cube above it, by bisection, and measure from the centre."""
lo, hi = 0.0, sum(n)
for _ in range(60):
mid = (lo + hi) / 2
if below(n, mid) < 0.9:
lo = mid
else:
hi = mid
return (lo + hi) / 2 - sum(n) / 2
best = (0.0, None)
K = 200 # directions per angle
for i in range(1, K):
for j in range(1, K):
t, p = pi / 2 * i / K, pi / 2 * j / K
n = (sin(t) * cos(p), sin(t) * sin(p), cos(t))
best = max(best, (depth(n), n))
d, n = best
r = 3 ** -0.5
print(f"vertex up: centre depth {depth((r, r, r)):.4f}")
tilt = degrees(acos(max(n))) # angle from nearest face
print(f"deepest centre found: {d:.4f}, {tilt:.2f} degrees"
" from straight face-up")
It prints
vertex up: centre depth 0.3791
deepest centre found: 0.4000, 0.45 degrees from straight face-up
The deepest centre on the grid is at the grid point closest to a face, and its depth rounds to the face-up value .
Extra Credit
Now the iceberg is a perfect sphere, with of its volume above sea level. What is the ratio now?
Solution
A sphere looks the same every way up, so there is nothing to optimise. Take radius . The part above water is a cap of height , and a cap of height on a unit sphere has volume . (Add up circular slices: at height above the centre the slice has area , and integrating from to gives this.) Setting it equal to a tenth of , This cubic has a neat exact solution. Put to remove the square term: . The identity says that turns into , so the equation becomes . The root with between and comes from : So although only a tenth of the sphere’s volume is above water, a fifth of its height is: the top of a sphere is thin, so it takes a tall cap to hold a tenth of the volume.
The computation
This check does not use the cap formula. It adds up thin circular slices of the ball directly to measure the share above a given waterline, and bisects for the waterline that leaves exactly above.
def cap_fraction(x, slices=20000):
"""Share of a unit ball's volume above the plane at height
1 - x, adding up thin circular slices of area pi(1-z^2)."""
dz = x / slices
vol = sum(pi * (1 - (1 - x + (k + 0.5) * dz) ** 2) * dz
for k in range(slices))
return vol / (4 / 3 * pi)
lo, hi = 0.0, 1.0
for _ in range(50):
mid = (lo + hi) / 2
lo, hi = (mid, hi) if cap_fraction(mid) < 0.1 else (lo, mid)
x = (lo + hi) / 2
print(f"extra credit: x = {x:.5f}, x/y = {x / (2 - x):.5f}")
It prints
extra credit: x = 0.39160, x/y = 0.24347