DEV Community

Cover image for Building a Browser Only Sudoku Solver
Corbin
Corbin

Posted on

Building a Browser Only Sudoku Solver

screenshot of Sudoku solver

screenshot of Sudoku solver

Sudoku looks simple, but checking whether a puzzle is valid, has one solution, or is genuinely difficult turns out to be more complicated than it first appears.

I wanted a small tool that could answer a few basic questions without relying on a server or external libraries. Everything runs directly in the browser as a static page.

This post walks through how the analyzer works and why a few design choices mattered.


Puzzle input
The tool accepts a single 81 character string.

Digits 1 to 9 represent givens.
Dots or zeros represent blanks.

Example input:

4.....8.5.3..........7......2.....6.....8.4......1.......6.3.7.5..2.....1.4......
Enter fullscreen mode Exit fullscreen mode

This format is common, compact, and easy to share, which makes it practical for links and testing.


Validity checking comes first

Before doing anything, the grid is checked for basic Sudoku rule violations.

Each row, column, and 3 by 3 box is scanned for duplicate values using simple sets.

function isValidGrid(grid) {
  const seen = new Set();
  for (let r = 0; r < 9; r++) {
    for (let c = 0; c < 9; c++) {
      const v = grid[r][c];
      if (!v) continue;
      const key = `${r}-${c}-${v}`;
      if (seen.has(key)) return false;
      seen.add(key);
    }
  }
  return true;
}
Enter fullscreen mode Exit fullscreen mode

This step filters out invalid puzzles early and prevents unnecessary solver work later on.


Using logic to estimate difficulty

Difficulty is estimated using basic human style techniques rather than brute force.

The solver applies a small set of logical steps.

Naked singles
Hidden singles
Naked pairs

Each time a technique is applied, it is recorded. The hardest technique required becomes the difficulty indicator.

This approach is not perfect, but it is explainable and consistent, which mattered more to me than an opaque rating.


Counting solutions without freezing the page

Counting solutions requires backtracking, which can get expensive very quickly.

Running that on the main thread can lock up the browser, especially for open puzzles with few givens.

To avoid this, the uniqueness check runs inside a Web Worker with a strict time limit.

const worker = new Worker("worker.js");
worker.postMessage({ puzzle, maxSolutions: 2, timeLimitMs: 900 });

Enter fullscreen mode Exit fullscreen mode

If more than one solution is found, the worker stops early.
If the time limit is reached, the result is reported as unknown instead of freezing the interface.

This keeps the page responsive even for difficult inputs.


Why keep everything static

Keeping the project browser only has a few practical advantages.

No server costs
No setup required
Easy to host on GitHub Pages
Simple to inspect or fork

It also makes sharing puzzles easier since the full state can live in the URL.


Demo and source

You can try the live version here:
https://sam-perry-usa.github.io/Sudoku-Analyser/

The full source code is available on GitHub:
https://github.com/Sam-Perry-usa/Sudoku-Analyser


Related

If you enjoy logic and number puzzles, you might also like Sudoku4Adults.

Top comments (0)