Par Is a Graph Property
Stroke metric, measured difficulty dial, par as a query result.
Six degrees of Kevin Bacon as a golf course: pair of film people, every film a stroke, fewest wins. Par, difficulty, valid shot, fair hole — each is a graph query.
Building the board
Four IMDb TSV dumps (title.basics, title.ratings, title.principals,
name.basics) — ~1.5 GB compressed, principals ~90M rows — streamed with
filters per pass, memory under 1 GB:
- Movies only, no adult, year ≥ 1930, Documentary and Short excluded
- ≥ 1,000 votes
- Cast capped at 10 (billed roles)
- Crew: directors, composers, cinematographers only
- Films with fewer than two people dropped
Result: 45,904 films, 218,793 people, 598,198 typed edges (450,728 cast, 48,888 director, 50,936 composer, 47,646 cinematographer). Pickled adjacency — loads in seconds. Full graph is the generator.
Shipped course plays on graph_us: 6,081 films, 29,981 people, 79,639
edges. Admit rule: (English original ∧ ≥25,000 votes) or crossover fame
(≥250,000 votes any language) — 6,044 + 37. Every connector in a valid chain
has to be a film the player can name.
Stroke cost
Chain alternates person / film / person. Cost of
[film, person, film, …, film] is (len + 1) / 2 — one stroke per film. BFS
over person states, expanding person → films → people, with:
- No immediate film reuse — arrival film can’t be departure film (zero-progress paths). Non-adjacent recurrence allowed.
- Banned films — when generating non-ace routes, the search bans shared films that would be aces so those routes stay distinct.
- Typed-route satisfaction as search state —
(person, satisfied)so search finds a crew-typed route.
Ace = shared-film check before any search. Everything above is layers on one BFS.
Stroke cost
strokes = (len + 1) / 2. An ace is the shared-film case checked before search.The difficulty dial, measured
Endpoints from a vote-ranked pool (people by summed film votes, min five films). Pool depth = how far down the fame curve tee/pin may sit. Full graph, 1,000 random pairs per pool: top-1,000 → 848 of 1,000 connect in two strokes; top-5,000 splits twos/threes; top-20,000 majority threes with 186 at four-plus.
Difficulty dial: generator vs shipped board
On the shipped board: only 2,664 of 29,981 people clear the five-film bar, so pools of 5k/20k silently cap and return identical histograms. Measured (1,000 pairs, seed 7): top-1,000 → 53 aces / 878 twos / 69 threes; max depth → 16 / 681 / 302 / 1 — one four-stroke pair in a thousand, zero unreachable within six. Keeping connectors nameable prunes long-filmography obscurity that manufactures distance. A par-4 needs a bigger board or typed-route constraints that lengthen.
Playtesting: a hole ending on an unplaceable Bollywood actor failed when players couldn’t place the endpoint. Dial uses open/mid/deep bands by pool depth. Shipped board ~50 MB resident; BFS pair 24.5 ms median (p95 ~1.1 s on deep stragglers); generator-side only.
Top connectors across a thousand shortest chains: Hans Zimmer (20), Jerry Goldsmith (13), James Newton Howard (12), Danny Elfman (10) — five of top seven are composers despite composer edges ~8% of the graph. Concentration mild (Zimmer in 2% of chains).
Film IDs
Early hole data keyed films by title string. Playtest surfaced Flatliners —
two films, 1990 and 2017, disjoint casts. Title-as-key merged them → chains no
single film satisfies. Fix: tconst everywhere; titles display as
“Title (YEAR)”. Same-titled different-cast pairs are a queryable pattern — the
doppelgänger hole.
Par as a property
Par is a BFS result. Difficulty is a histogram. Hole validity is a two-route existence check. Shot legality is membership in a shortest-path closure. Fairness is a vote floor at ingest.