IDA* with pattern databases solves the 15-puzzle in the fewest possible moves.
The 15-puzzle has about 10 trillion reachable positions, so the solver needs a sharp estimate of how far each one is from home. It splits the tiles into groups of 6, 6 and 3 and runs a breadth-first search for each group, recording the exact number of moves that group's tiles need: 11.5 million entries, built a few milliseconds per frame as you watch the histograms fill. Every real move moves one tile, so the three lookups add up to an estimate that never overshoots, and IDA* (iterative deepening A*) uses it to prove each solution is the shortest. The frontier plot draws sampled search paths as h against depth, pressed up under the f = g + h bound, then the wooden tiles slide home along the optimal line.
Try it. Click a tile in line with the gap to slide it (or use the arrow keys). Shuffle (S) gives a random position, Solve (Space) finds and plays the optimal solution, Hint (H) makes the next optimal tile glow and keeps glowing as long as you follow it, Picture (P) turns the tiles over to a new painting, and N hides the numbers.
Paste this into Claude Code, Codex or any coding agent to get a simple version running, then take it wherever you like.
Build a 15-puzzle (the 4x4 sliding tile puzzle) that solves itself optimally, with JavaScript and the HTML canvas element. Put everything in a single index.html file with no libraries or build step, so I can open it directly in a browser.
Start simple:
- Store the board as an array of 16 numbers, 0 for the gap. Draw the tiles as rounded squares with their numbers on a canvas that fills the window and stays sharp on high-DPI screens.
- Clicking a tile next to the gap slides it in, animated with an ease over about 150 ms. Arrow keys work too.
- Add a Shuffle button that makes a random arrangement, and check the permutation parity so it is always solvable (half of all arrangements are not).
- Add a Solve button that runs IDA*: a depth-first search limited by f = g + h, where g is the moves made so far and h is the sum of each tile's Manhattan distance home. When a pass fails, raise the limit to the smallest f that went over it and search again. Never undo the previous move. Then play the solution back one move at a time.
- Run the search in slices of a few milliseconds per frame (use an explicit stack instead of recursion) and show the node count and current bound while it works.
Once that works, make it beautiful:
- Paint a picture with gradients and paths (a sunset, a pond) and draw each tile's slice of it, with a bevel, a soft shadow and a wooden frame.
- Add linear conflict to the heuristic: two tiles in their goal row in the wrong order cost two extra moves. Watch the node count drop.
- Plot the bound and nodes per iteration as a small bar chart, and add a Hint button that highlights the first move of the optimal solution.
Random positions can take Manhattan distance a long time, so test with shuffles of 40 to 60 random moves first. Explain the key ideas in short code comments. When you're done, tell me how to open it and suggest three directions I could take it next, such as additive pattern databases for much stronger estimates, the 24-puzzle, or letting people upload their own picture.