Skip to content

Improve crossword puzzle solver implementation - #14568

Merged
cclauss merged 4 commits into
TheAlgorithms:masterfrom
Ewanjohndennis:patch-1
Sep 17, 2026
Merged

cclauss merged 4 commits into
TheAlgorithms:masterfrom
Ewanjohndennis:patch-1

Conversation

@Ewanjohndennis

@Ewanjohndennis Ewanjohndennis commented Apr 20, 2026

Copy link
Copy Markdown
Contributor

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
@Ewanjohndennis

Copy link
Copy Markdown
Contributor Author

Hi, thanks for the review!

Sorry for the ping, but since this PR has been approved, could a maintainer please take a look and merge if everything looks good?

@cclauss @MaximSmolskiy

@algorithms-keeper algorithms-keeper Bot removed the awaiting reviews This PR is ready to be reviewed label Sep 17, 2026
@cclauss
cclauss merged commit 06b0756 into TheAlgorithms:master Sep 17, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement This PR modified some existing files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants