kens
18 hours ago
Author here if anyone has questions. I was inspired to look at constraint solvers by the recent HN discussion "Many hard LeetCode problems are easy constraint problems" https://news.ycombinator.com/item?id=45222695
tzs
5 hours ago
I too have a solver, but it is the dumb kind, with the only real optimization being the one you described:
> An easy optimization is to check the constraints after each domino is added. For instance, as soon as the "less than 5" constraint is violated, you can backtrack and skip that entire section of the tree. In this way, only a subset of the tree needs to be searched; the number of branches will be large, but hopefully manageable
The solve function simply finds the first unoccupied square, then for each unoccupied neighbor of that square and each unused tile it places that tile on those two squares, checks the constraint groups those squares belong to to see if this placement violates them, and if not calls itself recursively. When that call returns if the tile is not symmetric it flips the orientation, checks constraints, and recurses.
If when called it cannot find an unoccupied square that means the level above actually solved the puzzle so it records the solution.
So far there has only been one puzzle where this was really slow, 2025-10-17 hard, which had 16 tiles. On my M2 Max Mac Studio it took 37 minutes. Every other puzzle I've given it has taken at most a few seconds, including hard 2025-10-09 which was also a 16 tile puzzle. That one was 7 seconds.
My guess is that if I changed the way the solve functions picks the square to start with it could greatly change the time. Right now it just takes the first open square found scanning right to left and top to bottom. Maybe something like giving priority to squares in small constraint groups would be more effective.
I'm not fully sure mine is correct. The code is simple enough that I can't see how it could be missing solutions...but on that one you said has 384 solutions mine only finds 344.