Simple Sudoku gives everyone the same puzzle every day, and lets you share any board with an eight-character code, without ever going online.
Simple Sudoku
Algorithms
Simple Sudoku has no account, no ads, and never needs the internet. It also has a daily puzzle that is the same for everyone, and you can send any puzzle to a friend. Those two features usually mean a server. Here is how we got away without one.
Carving a puzzle
Every puzzle starts as a random, completely filled grid. The generator then empties cells one at a time, and after each one checks that the puzzle still has exactly one solution. If removing a cell would allow a second solution, it goes back.
One observation keeps this fast: a cell that cannot be removed now can never be removed later, because emptying more cells only ever adds solutions. So a single pass over the cells is enough. An attempt takes about a millisecond.
Grading by technique, not by blanks
Lots of Sudoku apps grade difficulty by how many squares are empty. That is a poor guide; some sparse puzzles are easy and some full ones are brutal. Instead, a solver works through each new puzzle the way a person would and records the hardest technique it needed. Each level, from Quick to Expert, accepts a band of techniques. If a puzzle lands outside the band, we throw it away and carve another. At a millisecond each, we can afford to.
Same puzzle, everyone, no server
The generator is seeded, so the same seed always carves the same puzzle. The daily puzzle’s seed comes from the date itself, so every phone in the world works out the same board on its own. The level follows the week: easy on Monday, hardest at the weekend.
Codes that survive being read aloud
Any puzzle can be shared as a code like N4F7-K2QX: one letter for the level (Quick, Easy, Normal, Hard, eXpert), then the seed in Crockford base 32. Crockford’s alphabet leaves out I, L, O and U, and reading a code maps the look-alikes back, so an O typed for a 0 still works.
text = raw.toUpperCase()
.replace(/[\s-]/g, '') // spaces and dashes don't matter
.replace(/O/g, '0') // look-alikes read back
.replace(/[IL]/g, '1');
Normalising a typed code, as this website does
Because every well-formed code maps to a seed, any code someone types plays a puzzle. You can try it on our nerds page.
The one bit that runs in the cloud
Share a puzzle link in a chat app and you get a preview naming the level. Chat apps do not run JavaScript, so a tiny Vercel function fills the level and code into the page before it is sent. It is the only server code in the whole feature, and it only exists for the preview.