Skip to content

Improve crossword puzzle solver implementation#14568

Open
Ewanjohndennis wants to merge 3 commits intoTheAlgorithms:masterfrom
Ewanjohndennis:patch-1
Open

Improve crossword puzzle solver implementation#14568
Ewanjohndennis wants to merge 3 commits intoTheAlgorithms:masterfrom
Ewanjohndennis:patch-1

Conversation

@Ewanjohndennis
Copy link
Copy Markdown

The original is_valid returned False for any non-empty cell, which meant two words sharing a letter could never be placed together. Since crossword grids are built on exactly those intersections, this broke the core use case. Related to that, remove_word during backtracking blindly blanked every cell of the removed word, wiping out letters that belonged to already-placed crossing words. The fix snapshots the grid before placement and only clears cells that were empty beforehand. There was also a mutation bug: words.remove(word) does an O(n) scan and modifies state shared across the call stack, replaced here with a local slice per frame. On top of the fixes, the solver now tries the longest word first at each level, a standard "most-constrained variable" heuristic that cuts down backtracks significantly on larger inputs.

Describe your change:

  • Add an algorithm?
  • Fix a bug or typo in an existing algorithm?
  • Add or change doctests?
  • Documentation change?

Checklist:

Ewanjohndennis and others added 2 commits April 20, 2026 14:38
The original `is_valid` returned `False` for any non-empty cell, which meant two words sharing a letter could never be placed together. Since crossword grids are built on exactly those intersections, this broke the core use case. Related to that, `remove_word` during backtracking blindly blanked every cell of the removed word, wiping out letters that belonged to already-placed crossing words. The fix snapshots the grid before placement and only clears cells that were empty beforehand. There was also a mutation bug: `words.remove(word)` does an O(n) scan and modifies state shared across the call stack, replaced here with a local slice per frame. On top of the fixes, the solver now tries the longest word first at each level, a standard "most-constrained variable" heuristic that cuts down backtracks significantly on larger inputs.
@algorithms-keeper algorithms-keeper bot added enhancement This PR modified some existing files awaiting reviews This PR is ready to be reviewed labels Apr 20, 2026
@algorithms-keeper algorithms-keeper bot added tests are failing Do not merge until tests pass and removed tests are failing Do not merge until tests pass labels Apr 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

awaiting reviews This PR is ready to be reviewed enhancement This PR modified some existing files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant