A word ladder asks you to turn one word into another by changing a single letter at a time, with every step being a real word. COLD → CORD → CARD → WARD → WARM. It's a lovely little puzzle, and it turns out to be a nice small graph problem too.
The graph
Treat every word of a given length as a node, and connect two words if they differ by exactly one letter. A ladder is then just a path, and the shortest ladder is a breadth-first search.
The naive way to build edges compares every pair of words, which is O(n²). A much faster trick is to bucket words by wildcard patterns: cold goes into _old, c_ld, co_d and col_. Any two words sharing a bucket are neighbours.
const buckets = new Map(); for (const w of words) { for (let i = 0; i < w.length; i++) { const key = w.slice(0, i) + "_" + w.slice(i + 1); if (!buckets.has(key)) buckets.set(key, []); buckets.get(key).push(w); } } The word list matters more than the algorithm
The hardest part wasn't BFS, it was the dictionary. A full Scrabble list produces "valid" ladders through words nobody has heard of, which feels unfair. We ended up using two lists: a large one to accept a player's step, and a smaller common-words list to generate puzzles, so the intended solution only uses words people actually know.
Picking a fair daily puzzle
For each candidate start/end pair we compute the shortest path length and how many distinct shortest paths exist. Puzzles with a length of 4–6 steps and a few alternative routes felt best: too few routes and it becomes a guessing game, too many and it's trivial.
Try it
The result is Rungs, a free daily word ladder on Daily Games Page, with an unlimited mode and a 90-second climb. No account, no app. I'd love to hear how others handle dictionary quality in word games.

