Library · The Fiddler: Solutions · Chapter 2

Can You Design a Quadrangular Logo?

Revised Report an error

You and a designer are making a logo for Fiddler Airlines. The designer starts with an equilateral triangle of side 11, and you pick a random point inside it. That gives four points, the triangle’s three corners and your point, and several simple quadrilaterals (ones whose sides do not cross) have exactly these four points as their corners. The designer picks one of them at random, each equally likely, and that quadrilateral is the logo. On average, what is its area?

The Fiddler, Zach Wissner-Gross, October 23, 2026(original post)

The official solution appeared in the post of October 30, 2026 and gives 3/6≈0.2887\sqrt3/6 \approx 0.2887 for the main puzzle, agreeing with the answer below. The Extra Credit half of that post is paywalled, so the length L=2L = 2 is my own.

Solution

Call the corners AA, BB, CC and the chosen point PP, and write TT for the area of the triangle. A quadrilateral on four given points is fixed by the order in which its sides visit them, and three of the points, the corners, already form a cycle A→B→C→AA \to B \to C \to A. The only freedom is where PP goes in that cycle: between AA and BB, between BB and CC, or between CC and AA. So there are three candidates, and every other ordering is one of these traversed from a different start or in reverse.

All three are simple. Take PP between AA and BB, giving the outline A→P→B→C→AA \to P \to B \to C \to A. The two new sides APAP and PBPB lie inside the triangle, so they cannot cross the sides BCBC and CACA. The shape is the triangle with a notch cut out of it, and the notch is the small triangle APBAPB. The figure shows all three.

The three simple quadrilaterals on A , B , C and an inner point P . Each is the whole triangle less one of the three small triangles that P cuts it into.
The three simple quadrilaterals on AA, BB, CC and an inner point PP. Each is the whole triangle less one of the three small triangles that PP cuts it into.

The point PP cuts the triangle into three small triangles, PBCPBC, PCAPCA and PABPAB, and each quadrilateral is the whole triangle less exactly one of them. Writing [XYZ][XYZ] for the area of triangle XYZXYZ, the three areas are T−[PAB]T - [PAB], T−[PBC]T - [PBC] and T−[PCA]T - [PCA]. Their average is 3T−([PAB]+[PBC]+[PCA])3  =  3T−T3  =  23 T,\frac{3T - \bigl([PAB] + [PBC] + [PCA]\bigr)}{3} \;=\; \frac{3T - T}{3} \;=\; \frac23\,T, because the three small triangles fill the large one exactly.

This is the whole puzzle. The average over the designer’s choice is 23T\frac23 T wherever PP lands, so picking PP at random changes nothing. An equilateral triangle of side 11 has area T=3/4T = \sqrt3/4, and  expected area =23⋅34  =  36  ≈  0.2887. \boxed{\ \text{expected area } = \frac23\cdot\frac{\sqrt3}{4} \;=\; \frac{\sqrt3}{6} \;\approx\; 0.2887. \ } Nothing here used the triangle being equilateral: for any triangle the answer is two thirds of its area.

The computation

The check builds the quadrilaterals from scratch. For each of 20,00020{,}000 random points it tries every ordering of the four points, discards those whose sides cross, removes repeats (the same outline from a different start or in reverse), and averages the shoelace areas of what is left. It reports how many simple quadrilaterals it found per point, the overall average, and how much the per-point average varies.

import numpy as np
from itertools import permutations

rng = np.random.default_rng(2026)
A = np.array([0.0, 0.0])
B = np.array([1.0, 0.0])
C = np.array([0.5, np.sqrt(3)/2])

def area(poly):                      # shoelace formula
    x, y = np.array(poly).T
    return abs(x @ np.roll(y, -1) - y @ np.roll(x, -1))/2

def cross(o, a, b):
    return (a[0]-o[0])*(b[1]-o[1]) - (a[1]-o[1])*(b[0]-o[0])

def edges_cross(p1, p2, q1, q2):     # proper crossing
    return (cross(p1, p2, q1)*cross(p1, p2, q2) < 0 and
            cross(q1, q2, p1)*cross(q1, q2, p2) < 0)

def simple_quadrilaterals(pts):
    """Each distinct simple quadrilateral on four points."""
    found = {}
    for order in permutations(range(4)):
        if order[0] != 0:
            continue                 # fix the starting point
        P = [pts[i] for i in order]
        if (edges_cross(P[0], P[1], P[2], P[3]) or
                edges_cross(P[1], P[2], P[3], P[0])):
            continue
        # the same outline, read backwards, has the same sides
        key = frozenset(frozenset((order[i], order[(i+1) % 4]))
                        for i in range(4))
        found[key] = P
    return list(found.values())

means, counts = [], set()
for _ in range(20000):
    u, v = rng.random(2)
    if u + v > 1:
        u, v = 1 - u, 1 - v          # uniform in the triangle
    P = A + u*(B - A) + v*(C - A)
    quads = simple_quadrilaterals([A, B, C, P])
    counts.add(len(quads))
    means.append(np.mean([area(q) for q in quads]))
means = np.array(means)
print("simple quadrilaterals per point:", counts)
print(f"expected area {means.mean():.10f}")
print(f"spread over points {means.max() - means.min():.1e}")
print(f"sqrt(3)/6 = {np.sqrt(3)/6:.10f}")

It prints

simple quadrilaterals per point: {3}
expected area 0.2886751346
spread over points 1.1e-16
sqrt(3)/6 = 0.2886751346

The spread of 10−1610^{-16} is rounding error: every single point gives the same average, as the argument says it must.

Extra Credit

Some points inside the triangle are special: joining one to the three corners makes three small triangles whose areas form an arithmetic sequence. These points make up a locus of total length LL. What is LL?

Solution

Three numbers form an arithmetic sequence, in some order, exactly when one of them is the average of the other two. Call that one mm and the others m−dm - d and m+dm + d. Their sum is 3m3m, and here the sum is fixed: the three small triangles always fill the whole, so their areas add up to TT. Hence m=T/3m = T/3, and a point is special exactly when one of its three small triangles has area exactly T/3T/3. Conversely, if one triangle has area T/3T/3, the other two add up to 23T\frac23 T, so they are 13T±d\frac13 T \pm d for some dd, and the three areas are in arithmetic sequence.

Now take one side, say BCBC. The triangle PBCPBC has base BCBC, and its area is half the base times the height of PP above BCBC. So [PBC]=T/3[PBC] = T/3 exactly when PP sits at one third of the triangle’s full height above BCBC. Those points form a segment parallel to BCBC, running from side ABAB to side ACAC. The part of the triangle above that line is a smaller equilateral triangle with two thirds of the original height, so by similarity the segment has length 23\frac23.

The same holds for each of the three sides, giving three segments of length 23\frac23. They all pass through the centre of the triangle, where all three small triangles have area T/3T/3, but they share only that single point, which adds no length.

The special points: three segments, each a third of the way from a side to the opposite corner and of length \frac23 , crossing at the centre.
The special points: three segments, each a third of the way from a side to the opposite corner and of length 23\frac23, crossing at the centre.

 L  =  3×23  =  2. \boxed{\ L \;=\; 3 \times \tfrac23 \;=\; 2. \ } As with the main puzzle, the shape of the triangle hardly matters. For any triangle the locus is the three lines at a third of each height, and their lengths are two thirds of the corresponding sides, so LL is two thirds of the perimeter.

The computation

The check measures the length without knowing what the locus looks like. It uses the Cauchy–Crofton formula from integral geometry: draw straight lines at random, with a uniformly random direction and a uniformly random offset, and count how often each crosses the curve. The length of the curve is half the total measure of lines, each counted once per crossing, so it equals π2\frac{\pi}{2} times the average, over random directions and offsets, of the crossing count times the triangle’s width in that direction.

Crossings are found by walking along each line’s chord through the triangle and watching the sign of the middle area minus the mean of the other two, a quantity that is zero exactly at the special points. A million lines are used.

def tri_area(p, q, r):
    return np.abs((q[0]-p[0])*(r[1]-p[1])
                  - (q[1]-p[1])*(r[0]-p[0]))/2

def gap(X):
    """Middle area minus the mean of the other two, at the
    points X (shape 2 by n); zero exactly at special points."""
    a = np.sort(np.array([tri_area(X, B, C), tri_area(X, C, A),
                          tri_area(X, A, B)]), axis=0)
    return a[1] - (a[0] + a[2])/2

def walk(p, d, s):                   # points on the line, by s
    return p*d[:, None] + np.array([-d[1], d[0]])[:, None]*s

# Cauchy-Crofton: length = half the measure of lines meeting
# the curve, each counted once per crossing. Lines are
# x cos t + y sin t = p.
rng = np.random.default_rng(7)
V = np.array([A, B, C])
T = np.sqrt(3)/4
n_lines, n_pts, samples = 1000000, 2001, []
for t, f in zip(rng.uniform(0, np.pi, n_lines),
                rng.random(n_lines)):
    d = np.array([np.cos(t), np.sin(t)])
    lo, hi = (V @ d).min(), (V @ d).max()
    p = lo + f*(hi - lo)             # uniform across the width
    # find the chord of the triangle along this line
    s = np.linspace(-1.5, 1.5, 3001)
    X = walk(p, d, s)
    parts = (tri_area(X, B, C) + tri_area(X, C, A)
             + tri_area(X, A, B))
    inside = s[parts <= T + 1e-12]   # areas add up only inside
    if inside.size < 2:
        samples.append(0.0)
        continue
    s = np.linspace(inside.min(), inside.max(), n_pts)
    g = np.sign(gap(walk(p, d, s)))
    crossings = np.count_nonzero(g[1:] != g[:-1])
    samples.append(crossings*(hi - lo))
samples = 0.5*np.pi*np.array(samples)
L, se = samples.mean(), samples.std()/np.sqrt(n_lines)
print(f"length of the locus: {L:.4f} +- {2*se:.4f}")

It prints

length of the locus: 1.9981 +- 0.0034

The estimate agrees with L=2L = 2 well within its sampling error.

Report an error on this page

Reports are stored by Netlify. See the privacy note.