Inspired by One Million Checkboxes, I thought it would be cool to create a realtime, collaborative nonogram game where we can collectively try to complete all ~25 million of these puzzles. Just launched it this afternoon and its already at 65k solved!
Let me know if you have any feedback.
This is OEIS sequence A242876 — https://oeis.org/A242876
okayestjoel (below) wrote:
> My nonogram solver goes over every possible configuration for each row and column based on the clues, and either fills in squares that must be filled (all possibilities overlap) or marks squares that must be empty. So if the solver reaches a point where there is ambiguity about what the next move is, then it is deemed not solvable (without guessing).
It would be (mildly) interesting to see an example of one of the 333064 solvable 5x5 nonograms that cannot be solved by okayestjoel's solver's heuristics.
1 1 1
2 1 1 2 1
2 . . . . .
2 . . . . .
11 . . . . .
2 . . . . .
11 . . . . .
This puzzle has a unique solution (141a706), but none of the clues immediately tell you anything about the state of any specific cell.[spoiler alert]
Naming the coumns ABCDE from left to right, and the rows 12345 from top to bottom. Let's consider B2 near the top left. If B2 full:
Then B1 is empty because B has "only" ones. Then the "two" block in row 1 must make D1 full. Then D2 is also full because D has a "two". Now B2 and D2 are full, but that's impossible because B has only a "two".
So the B2 must be empty. From that point it's possible to fill all the others without "guessing".
So no branches and 3 steps to get a contradiction. I can run that in my head, so I call it "thinking" instead of "backtracking".
I'm a little underwater handling the surge of traffic to my game, though when I get a quiet moment I'll run my solver so I can give some more precise answers. Basically my solver iterates over every row and column, marking cells that must be empty and painting cells that must be filled by going over every possible configuration for that row or column and finding the overlap. It does this in multiple passes and generally the more passes it takes, the more challenging the puzzle is. If it makes a pass and is unable to mark or paint any additional cells, then it considers the puzzle to be invalid if the end state is not solved (all clues are not satisfied).
I do find this discussion really interesting. Maybe I should have reserved "Section 666" for these puzzles with unique solution but require a branching strategy :).
I think one thing missing from my 5x5 puzzle thing is that good nonograms are not just those that have a unique solution and require no guessing, but also create a compelling image when the puzzle is complete. My game, Pixelogic, features user-submitted puzzles in addition to in-house ones, and I'm often blown away how creative the pixel art creations are given the constraints of solvability under my game's standards and just on and off pixels.
I wrote about what makes a good nonogram puzzle (in my opinion) in my weekly nonogram newsletter, if anyone is interested: https://weekly.pixelogic.app/p/pixelogic-weekly-4
2 1
41131
1 2 ___#_
2 1 ##x#x
1 2 #__#_
1 #xxxx
2 1 _#_x#
I believe at this point the tactic of "just find a cell that must be black based only on data from its row or column" fails. We can continue only by "using our heads" (i.e. "backtracking"), or by starting to mark cells that must be empty based on data from only their row or column. The cell with the capital X below must be empty because of data in row 3. But the JavaScript didn't auto-mark it with an X. Maybe this is just a logic bug in the JavaScript?: 2 1
41131
1 2 ___#_
2 1 ##x#x
1 2 #X_#_
1 #xxxx
2 1 _#_x#
And from there we can solve column 2, row 1, row 3, and row 5, in that order.I don't think it's a bug in the javascript either, it seems intentional that it only fills in the x's automatically if you've filled in the squares for that row/column.
"Guess and backtrack" is a totally valid form of deduction for pen-and-paper puzzles, it's just not very satisfying. But often (always?) there is a satisfying deduction technique that could have replaced the guess-and-check, it may just be fairly obtuse.
Or do you just mean where the clues for the raster don't result in a unique solution?
* 5, 0, 1 1 1, 2 2, 3 1 and 3 1 are immediately solved
* 4 lets you set 3 squares immediately
* 3, 2 1 and 1 2 let you set 1 square immediately
For example, a valid "advanced" rule is this: consider a line, then consider all permutations of ways to complete it given the current state of the line. If a square is filled in/crossed out in all these permutations, then it you may fill it in/cross it out.
This is an O(n!) algorithm! In practice you only have <5 permutations.
But in general, Nonogram solving, like most pen-and-paper puzzles, is NP-Complete for large enough puzzles, so even such a high-powered rule isn't guaranteed to completely solve a (large) puzzle.
11110
-----
11|....0
2|....0
0|00000
0|00000
0|00000
The sequential constraint solver fails here even though the deduction required is trivial. The first row can only be 10010 or else the 2 in the second row isn't possible.A more difficult problem is the following:
11 1
11211
-----
1|..0..
2|..0..
11|.010.
4|.111.
0|00000
There are two choices at this point. One option is: 11 1
11211
-----
1|..0..
2|..0..
11|.010.
4|01111
0|00000
And we immediately run into a problem with the 3rd row, 1st col which needs to be both 1 and 0.The other solves the problem immediately as all remaining squares are immediately specified by a single constraint.
11 1
11211
-----
1|00010
2|11000
11|00101
4|11110
0|00000
Compared to most sudoku solves, I think this is pretty straightforward (you only need to look ahead one move to one other square). I think this would be fair game to give as a problem.Of all the games with a unique solution that the sequential solver can't do that I looked at, almost all fell somewhere in the range of difficulty between these two. I didn't find any that require more than one move lookahead.
Maybe a heat map of all sections based on completion percentage? And maybe a way to jump to the first or a random unsolved puzzle once you've opened a section?
1 2 |x x |
if I left click the second cell and drag right it should mark all the blank cells black.Similarly in the inverted case, if I have marked cells and right-click-and-drag next to them it should mark the empty spots I cross over with Xs.
Important: this doesn't change the state of any cell that wasn't blank to start out. You should have to click on a marked cell to clear it (or right click to replace it with an X). And similarly to above, if you drag, it should change only the cells you touch that match the starting state of your original cell to the new state.
To get an idea of the speed difference between solving sequentially vs solving using backtracking, on my 10 year old MacBook Pro running on a single core, solving all 28,781,820 possible distinct games: - sequential solver: ~75s to either solve or abandon each problem - backtracking solver: ~175s (2.3x) to find every solution for every problem
The backtracking solver is unfairly disadvantaged in this comparison as it takes more time to solve the difficult games requiring backtracking and those with multiple solutions - for example the game {1, 1, 1, 1, 1 | 1, 1, 1, 1, 1} has 120 solutions that need to be found, but the sequential solver abandons its attempt after making no progress on its first pass through the constraints.
For the 25,309,575 uniquely determined games only, the gap in performance is a bit narrower: - sequential solver: ~60s - backtracking solver: ~120s (2.0x)
The recursive backtracking solver was a far simpler program to write though!
Incidentally, to generate a database of all possible games took ~35s and finding all solutions for all of the games by looking them up took ~20s in total.
Database generation: 25s; Sequential solver - all 'solvable' problems or abandon: 52s; Backtracking solver - all solutions: 19s; Database Lookup - all solutions: 16s;
Key takeaway is that the backtracker is not only much simpler, its actually much faster (for a computer at least) and almost as fast as looking up the answer in a table.
(I wrote a program to calculate this by generating all 2^25 puzzles and their clues, then sorting by the clues. I also verified the count of 25,309,575 clues with unique solutions.)
Logic has two modes, one is going forward and the other is "assuming conversely" and finding if it leads to contradiction to eliminate that possibility. Both are equally valid and logical. There's no guessing involved. You simply pick any option to eliminate, assume it and try to lead to contradiction. If you don't find the contradiction you don't keep your assumption and the following steps that ended in a state that is not a contradiction, instead you try to eliminate another option instead in the same manner. Only when you successfully eliminate at least one you come back to trying forward logic again. The ultimate trick is not to search the contradiction using only the forward logic, but recursively using the entire solver to find if you landed in a contradiction.
Those two modes are basically the only logic that math uses for bulk of its proofs.
One minor UI suggestion: you should allow filling (or marking empty) multiple boxes by holding the mouse button down. This makes it easier to fill in entire rows or columns.
Feature request: It would be nice to have a jump to unsolved puzzle. In section 1 it's difficult to find an empty one. Also, there is something weird with scrolling.
Yeah, a "jump to unsolved" seems like its going to be essential. I'll work on that. I haven't heard of the scrolling issue. What device/browser are you using?
FYI, I've also noticed that on Android (but not on desktop Chrome) sometimes single-tapping to remove a black square will leave a stray X behind. I think this is not a logic bug but rather a mobile input-recognition problem — that on mobile a single-tap is sometimes being recognized as a single-tap followed by a double-tap. (Quickly double-tapping an empty cell usually marks it with an X; although quickly double-tapping a filled cell usually just clears it, no X. So the symptom here is "I meant to single-tap a filled cell, but the game acted as if I'd single-tapped and then double-tapped the same cell again.")
Chrome on Windows 10, nothing fancy. I move pick the scroll bar on the right with the mouse and move slowly down, perhaps to the middle and try to find a empty range, and when I release mouse it goes back near the top. As a guess: Have you tire to scroll at the ame time that other player is solving puzles in the same section? Try section 1.
> requires no backtracking
I have more background in Math Olympiads and plain Math. You can do backtracking to find a unique solution if you write all the options and discard all-1 of them. It sounds fancier if you call it "Reductio ad absurdum" :) . It's an usual trick, and my recommendation is that if you are in the middle of a problem that ask to fill a board and you have two(or more) options, first copy the board as many times as necessary and intermediately fill the two(or more) possibilities, to avoid forgetting one of them.
For games like minesweeper, sudoku or nonogram, my personal criteria is that if I can run the backtracking in my head, it's "thinking", but if I have to draw the two(or more) boards it's "backtracking".
For me it's probably only two options in a square, no further branching and only two or three steps deep before the contradiction. (If your name is Magnus, everything is "thinking".)
(By the way: Nice game implementation!)
Ability to visualize it in your head, without needing to copy the board, or make temporary marks is certainly not unreasonable for complicated puzzles. That is the same rule as Simon uses for logic puzzles (mostly variant sudoku) on the YouTube channel Cracking the Cryptic.
It isn't the most satisfying way to delineate the dividing line, since how much a person can track in their head can vary, but coming up with other rules can be absurdly tricky. Especially if one wants to make a set of rules applicable to multiple types of logic puzzles. After all simple two to three step contradictions may be unusually powerful for some types of logic puzzles, while they can be the basic deduction type for a different one.
Look elsewhere in the thread and you'll see that there are 333,064 uniquely-solution grids that you have excluded.
It's common to have situations where you need to guess between two possibilities, and then you'll find out that one is wrong and you need to backtrack.
So I hope the algo you implement only excludes puzzles with more than one solution. As long as there is exactly one solution, it's completely logical and fair game.
You can do an entire puzzle this way (just keep on trying options and seeing if they work), but this is generally not on. If you build a puzzle that can only be solved this way, then you've built a bad puzzle, at least by the standards of the sudoku solving community. On the other hand, most complex or variant sudoku puzzles will have moments where there are two or three possibilities for a cell, and you need to look at the immediate effects of those possibilities to figure out which one is correct. So clearly some amount of bifurcation and backtracking is fine.
Fwiw, in the nonograms I've done in various apps, there's almost never a need to guess between different possibilities. I don't know if that's because the puzzle format itself is fairly constrained, or if the apps typically try to exclude these cases. But typically, it's always possible to see a next step, without needing to try things out and guess.
Here's a simple Nonogram to annoy everyone
# 1 1
1 . .
1 . .
Your comment made me curious about how often symmetry occurs in the full set of all possible 5x5 configurations. I took a shot at calculating this as an exercise, but I am a bit rusty when it comes to combinatorics...
First consider mirror symmetry via the center column. There are 2^5 configurations of the center column, and for each of those, there are 2^10 configurations of the left two columns. Since we are mirroring the right two columns from the left two, the number of configurations exhibiting mirror symmetry via the center column is 2^5 * 2^10 = 2^15. Rotating these 90 degrees gives us mirror symmetry via the center row, which is another 2^15 configurations. Mirror symmetry via the corner-to-corner axes, which also have 5 squares, is another pair of 2^15 configurations. So now we're at 2^17 configurations for mirror symmetry for the four axes.
Radial symmetry is slightly harder to describe, but it involves similar partitioning. You can partition the 5x5 grid into two 12-square subsets excluding the center square:
x x x x x
x x x x x
x x . o o
o o o o o
o o o o o
For any given configuration of the x-subset, you flip and reverse that to get the configuration of the o-subset. There are 2^12 possible configurations of the x-subset. Since there are two possible values of the center square, that gives us 2^13 configurations of two-subset radial symmetry. I believe rotating 90 or 180 degrees simply produces another configuration that has already been accounted for.There is also four-subset radial symmetry:
a a a B B
a a B B B
D a . c B
D D D c c
D D c c c
however, I think these would all be special cases of two-subset radial symmetry. If I pick a random configuration for the a-partition and apply it to the other subsets, it matches a configuration that would appear in the two-subset group: a a a B B X X o B B X X o o X
a a B B B o X B B B o X X X X
D a . c B => D X . c B => o X . X o
D D D c c D D D c c X X X X o
D D c c c D D c c c X o o X X
So between mirror symmetry and radial symmetry we have: 2^17 + 2^13 = 139,264. There are a total of 2^25 = 33,554,432 configurations irrespective of symmetry, so that's 17/4096 or roughly 0.415% that are symmetric...a bit more than 1/256.EDIT: And by some hilarious bit of fate, I just went to go knock out a few puzzles to reset my brain, and the first one I completed[3] exhibits mirror symmetry in one of the diagonal axes. I'm pretty sure this is the first one I've hit in over 1000 solves.
[1]: https://news.ycombinator.com/item?id=44148396
[2]: https://news.ycombinator.com/item?id=44141047
[3]: https://pixelogic.app/every-5x5-nonogram#3328511
EDIT: formatting; add link to symmetric puzzle
I got a bit sidetracked and wrote a userscript implementing this feature. It's a little hacky but works pretty well (at least, until the site changes):
https://gist.github.com/DanielCausebrook/3836be4b5804fabe997...
If anyone would find this useful, you can run this on the site using an extension like Tampermonkey. Obviously be careful when adding userscripts in general.
The empty board: https://pixelogic.app/every-5x5-nonogram#21035201
The full board: https://pixelogic.app/every-5x5-nonogram#13821100
A greeting board: https://pixelogic.app/every-5x5-nonogram#4282670
A checkerboard: https://pixelogic.app/every-5x5-nonogram#24204839
A board of love: https://pixelogic.app/every-5x5-nonogram#14090887
Question block: https://pixelogic.app/every-5x5-nonogram#18519948
Each nibble (four bits) in those five bytes is a row or column of the board, top to bottom then left to right, encoded as:
0: 0
1: 1
2: 1 1
3: 1 1 1
4: 1 2
5: 1 3
6: 2
7: 2 1
8: 2 2
9: 3
a: 3 1
b: 4
c: 5
If you concatenate all the clues_*.txt files, in order, to a single file, you can search through it to get the number of a pattern using standard tools, e.g. $ grep -n $(echo c222c c222c | xxd -ps -r | base64) clues.txt
452085:wiLMIiw=
Which is the nonogram at https://pixelogic.app/every-5x5-nonogram#452085.I have uploaded and archived a copy of that combined clues.txt file at https://web.archive.org/web/20250604215009id_/https://litter..., to help anyone else who would like to explore this without having to download those tens of thousands of files.
[1]https://medium.com/smith-hcv/solving-hard-instances-of-nonog...
A really useful feature would be to hide finished and/or in progress ones so I don't have to scroll forever.
Great work, nicely polished, cool idea.
That means that no 5x5 requires guesswork.
Surely there’s got to be a maths video about this. It seems like an incredible little quirk…
I can't start solving from the middle
But I don’t understand how I can. The UI design seems broken.
First I couldn’t interact with any puzzles until I realized these were already finished. But how do I get to unfinished ones? I scrolled forever and didn’t find one.
I saw that icon and interpreted it as an export button or something.
Since every box is either filled in (1) or not (0), a solved 5x5 nonogram can be encoded as a 25-bit unsigned integer. So would a 6x6 (36), 7x7 (49), 8x8 (64), etc.
... So if desired, an AES-256 key can be encoded as a solved 16x16 nonogram. The perimeter hints can then be derived by Alice and given to Bob as a weak form of information obfuscation.