October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsPC HealthRecommendedCrashes, freezes, slowdowns? Check your PC nowSpot repairable issues before they interrupt work.Check PCOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
World desk7 min

How to Generate Unique-Solution Sudoku and Nonograms in JavaScript—with a Repeatable Daily Seed

A practical JavaScript guide to constructing Sudoku and Nonogram puzzles, proving uniqueness with solution counting, and making daily puzzles reproducible with a versioned seed.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

To generate a puzzle with exactly one solution, create a candidate and run a solver that counts solutions, stopping when it finds a second. Keep the candidate only if the count is one. A seeded pseudo-random number generator (PRNG) makes that process repeatable; a date alone does not.

What “exactly one solution” means

A puzzle is unique when its rules and clues permit one completed grid, and no other. A solver that merely finds a solution cannot prove uniqueness: it must keep searching until it either exhausts the possibilities or finds a second solution.

As an Amazon Associate I earn from qualifying purchases.

  • Zero solutions: the clues are inconsistent or the puzzle is invalid.
  • One solution: the puzzle is unique.
  • Two or more solutions: the puzzle is ambiguous. The solver can stop at two; it does not need to count every possible completion.

Uniqueness is not a difficulty rating. A unique puzzle may still require guessing or advanced solving techniques. If you promise that a puzzle can be solved using logic alone, check it with the specific logic-only solver and techniques you intend to support.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Make a repeatable random stream

Math.random() is unsuitable when a player must be able to reproduce a puzzle from a seed: its initial seed is selected by the JavaScript implementation and cannot be chosen or reset by the user. MDN also notes that it is not cryptographically secure. Crypto.getRandomValues() supplies cryptographically strong random values, but its underlying PRNG can vary by user agent, so it is not the right choice for identical seeded output across browsers.

For replayable puzzles, use an explicit seed and a deterministic PRNG. The following small implementation hashes a string seed and then produces a repeatable stream. It is for reproducibility, not cryptographic security.

function hashSeed(text) {
  let h = 2166136261;
  for (let i = 0; i < text.length; i++) {
    h ^= text.charCodeAt(i);
    h = Math.imul(h, 16777619);
  }
  return h >>> 0;
}

function makeRng(seedText) {
  let state = hashSeed(seedText);
  return function random() {
    state = (state + 0x6D2B79F5) | 0;
    let t = state;
    t = Math.imul(t ^ (t >>> 15), t | 1);
    t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
    return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
  };
}

function shuffle(items, random) {
  for (let i = items.length - 1; i > 0; i--) {
    const j = Math.floor(random() * (i + 1));
    [items[i], items[j]] = [items[j], items[i]];
  }
  return items;
}

For a daily puzzle, construct the seed from a canonical date, puzzle identifier, and generator version. For example, use a UTC date string rather than a visitor’s local date:

const utcDate = new Date().toISOString().slice(0, 10);
const seed = `sudoku:${utcDate}:generator-v1`;
const random = makeRng(seed);

Every participant must use the same date rule, seed text, PRNG, generation order, and number of random draws. Changing any of them can change the result for a given date. Version the generator and retain older versions if old daily puzzles need to remain replayable.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Generate Sudoku by constructing, removing, and checking

Build a complete valid grid

Start with an empty 9×9 board and fill it using randomized backtracking. At each step, choose an empty cell, find digits not already present in its row, column, or 3×3 box, and try them in seeded shuffled order. If a choice leads to a dead end, undo it and try the next. A completed valid grid is the solution, not yet the puzzle.

Count solutions with a backtracking solver

The solver below selects an empty cell with the fewest legal candidates, which helps it explore constrained cells first. It mutates the board during recursion and restores each trial value before returning. The limit parameter lets it stop at two solutions.

function candidates(board, index) {
  const row = Math.floor(index / 9);
  const col = index % 9;
  const used = new Set();

  for (let i = 0; i < 9; i++) {
    used.add(board[row * 9 + i]);
    used.add(board[i * 9 + col]);
  }

  const boxRow = Math.floor(row / 3) * 3;
  const boxCol = Math.floor(col / 3) * 3;
  for (let r = boxRow; r < boxRow + 3; r++) {
    for (let c = boxCol; c < boxCol + 3; c++) {
      used.add(board[r * 9 + c]);
    }
  }

  const result = [];
  for (let digit = 1; digit <= 9; digit++) {
    if (!used.has(digit)) result.push(digit);
  }
  return result;
}

function countSudokuSolutions(input, limit = 2) {
  const board = input.slice();
  let count = 0;

  function search() {
    if (count >= limit) return;

    let bestIndex = -1;
    let bestOptions = null;

    for (let i = 0; i < 81; i++) {
      if (board[i] !== 0) continue;
      const options = candidates(board, i);
      if (options.length === 0) return;
      if (bestOptions === null || options.length < bestOptions.length) {
        bestIndex = i;
        bestOptions = options;
        if (options.length === 1) break;
      }
    }

    if (bestIndex === -1) {
      count++;
      return;
    }

    for (const digit of bestOptions) {
      board[bestIndex] = digit;
      search();
      board[bestIndex] = 0;
      if (count >= limit) return;
    }
  }

  search();
  return count;
}

This function assumes its input is an 81-element array of integers, with zero representing a blank. For untrusted input, validate the length, values, and consistency of the starting clues before counting.

Rank #4
4-Pack 350+ Sudoku Puzzles for Adults, with Tips & Tricks, Puzzle Books for Adults & Seniors, Aging Seniors Brain Stimulation Activity Books, Large 8 X10 and Digest 5 X 8 Combo
  • ★[MANY TO CHOOSE FROM] – Improve your memory, sharpen your mind, and have fun at the same time! If you are a big sudoku game enthusiast, this is a great way to unwind and relax while sharpening your brain with a wide range of sudoku puzzles to choose from in our various sudoku book bundles.
  • ★[INCLUDED IN THIS PACKAGE] – A 4-pack variety of sudoku puzzles, including 2 large size books, measuring 8x10 3/4 inches, and 2 digest size, measuring 5 1/4 X 8 1/4 inches. Also included is one free bonus pen; the color will vary randomly between black, blue, and red.
  • ★[HOURS OF FUN FOR YOUNG AND OLD] – Gift this bundle to your mother, father, friends, and family! These sudoku books are a collection of puzzles with all levels of puzzle difficulties, from one star to four stars, so that all ages can enjoy them. These are fun and challenging.
  • ★[VERSATILE STRUCTURE] – The puzzles are printed on smooth paper with premium ink and the words are easy to read making the puzzles a joy to complete. There are wide margins so the papers are easy to tear out.
  • ★[BONUS PEN INCLUDED] – We hope you’ll love this bundle of sudoku puzzle activity books as much as we do! As a token of appreciation to your loyalty, one pen is included with each bundle for your convenience. Colors vary between black, blue, and red. Happy puzzling!

Remove clues only when uniqueness survives

Try removing clues from the completed grid in a seeded shuffled order. For each tentative removal, count solutions. Keep the blank only if the count is exactly one; otherwise restore the digit.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
function makeSudoku(seedText) {
  const random = makeRng(seedText);
  const solution = Array(81).fill(0);

  function fill() {
    let bestIndex = -1;
    let bestOptions = null;

    for (let i = 0; i < 81; i++) {
      if (solution[i] !== 0) continue;
      const options = candidates(solution, i);
      if (options.length === 0) return false;
      if (bestOptions === null || options.length < bestOptions.length) {
        bestIndex = i;
        bestOptions = options;
        if (options.length === 1) break;
      }
    }

    if (bestIndex === -1) return true;

    shuffle(bestOptions, random);
    for (const digit of bestOptions) {
      solution[bestIndex] = digit;
      if (fill()) return true;
      solution[bestIndex] = 0;
    }
    return false;
  }

  if (!fill()) throw new Error("Could not construct a Sudoku solution");

  const puzzle = solution.slice();
  const positions = shuffle(Array.from({ length: 81 }, (_, i) => i), random);

  for (const index of positions) {
    const saved = puzzle[index];
    puzzle[index] = 0;
    if (countSudokuSolutions(puzzle, 2) !== 1) {
      puzzle[index] = saved;
    }
  }

  return { puzzle, solution };
}

The result contains flat arrays in row-major order; index row * 9 + column addresses a cell. The removal pass tries each position once, so it gives one uniquely solvable puzzle for that generation run, not a promise of a particular clue count or difficulty. A different seeded order can produce a different puzzle.

Best Value
17-Pack 1400+ Sudoku Puzzles for Adults, Large WordSearch Puzzle for Adults, Aging Seniors Brain Stimulation Activity Books (Variety Pack Bulk) - Large 8x10 & Digest 5x8 Combo
  • ★ [MANY TO CHOOSE FROM] – Improve your memory, sharpen your mind, and have fun at the same time! If you are a big word game enthusiast, and a great Sudoku problem solver this is a great way to unwind and relax while sharpening your brain with a wide range of word search and Sudoku puzzles to choose from in our various book bundles.
  • ★ [INCLUDED IN THIS PACKAGE] – A 17-pack variety of Sudoku puzzles, including Loco Sudoku and Sumoku, and a variety of diverse word search puzzles, including large print word finds and more. This is a combo pack of 12 large size books, measuring 8x10, and 5 digest size, measuring 5x8. Also included is one free bonus pen; the color will vary randomly between black, blue, and red.
  • ★ [HOURS OF FUN FOR YOUNG AND OLD] – Gift this bundle to your mother, father, friends, and family! They will love the combination of Word Find books with interesting family-friendly themes. As well, these Sudoku books are a collection of puzzles with all levels of puzzle difficulties, including Loco Sudoku and Sumoku, so that all ages can enjoy them. These are fun and challenging.
  • ★ [BONUS PEN INCLUDED] – We hope you’ll love this bundle of Word Find & Sudoku puzzle activity books as much as we do! As a token of appreciation to your loyalty, one pen is included with each bundle for your convenience. Colors vary between black, blue, and red. Happy puzzling!
  • ★ [OUR HAPPINESS ] – The happiness of our customers is our top priority. We hope you'll love this product! However, if for whatever reason you are dissatisfied with your purchase please reach out to us and we will refund you, no questions asked.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Generate and verify Nonograms from a picture

Turn a binary picture into clues

Represent the intended image as a rectangular grid of booleans, where true means filled. A clue is the ordered sequence of lengths of consecutive filled cells. Compute clues across every row and down every column. An all-blank line has no runs; represent it as an empty array, [], consistently in both generator and solver.

function lineClue(line) {
  const clue = [];
  let run = 0;
  for (const filled of line) {
    if (filled) {
      run++;
    } else if (run > 0) {
      clue.push(run);
      run = 0;
    }
  }
  if (run > 0) clue.push(run);
  return clue;
}

function cluesFromPicture(picture) {
  const height = picture.length;
  const width = picture[0].length;
  const rows = picture.map(lineClue);
  const columns = [];

  for (let c = 0; c < width; c++) {
    const column = [];
    for (let r = 0; r < height; r++) column.push(picture[r][c]);
    columns.push(lineClue(column));
  }
  return { rows, columns };
}

Count grids that match the clues

For a modest board, a straightforward verifier can enumerate all possible patterns for each line length, retain patterns whose runs match the clue, then assign rows recursively. After each row assignment, reject a branch if any column prefix cannot be extended to one of its legal full-column patterns. Count completed grids and stop at two.

This approach is deliberately simple rather than optimized: enumerating binary patterns costs up to 2line length per line. It is appropriate for small boards; larger dimensions may need a more specialized line-pattern generator and propagation strategy.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
function patternClue(pattern) {
  return lineClue(pattern);
}

function sameNumbers(a, b) {
  return a.length === b.length && a.every((value, i) => value === b[i]);
}

function linePatterns(length, clue) {
  const patterns = [];
  const total = 2 ** length;

  for (let mask = 0; mask < total; mask++) {
    const pattern = Array.from(
      { length },
      (_, i) => Boolean(mask & (1 << i))
    );
    if (sameNumbers(patternClue(pattern), clue)) patterns.push(pattern);
  }
  return patterns;
}

function countNonogramSolutions(rowClues, columnClues, limit = 2) {
  const height = rowClues.length;
  const width = columnClues.length;
  if (height === 0 || width === 0) return 0;

  const rowOptions = rowClues.map(clue => linePatterns(width, clue));
  const columnOptions = columnClues.map(clue => linePatterns(height, clue));
  if (rowOptions.some(options => options.length === 0) ||
      columnOptions.some(options => options.length === 0)) return 0;

  const chosenRows = [];
  let count = 0;

  function search(rowIndex) {
    if (count >= limit) return;
    if (rowIndex === height) {
      count++;
      return;
    }

    for (const row of rowOptions[rowIndex]) {
      chosenRows.push(row);
      let possible = true;

      for (let c = 0; c < width && possible; c++) {
        const prefix = chosenRows.map(chosen => chosen[c]);
        possible = columnOptions[c].some(pattern =>
          prefix.every((value, r) => pattern[r] === value)
        );
      }

      if (possible) search(rowIndex + 1);
      chosenRows.pop();
      if (count >= limit) return;
    }
  }

  search(0);
  return count;
}

To test a generated Nonogram, derive its row and column clues from the picture and pass them to the counter. Accept the clue set only when the result is one. The verifier counts grids allowed by the clues; it does not establish that a particular human-facing solving technique will solve the puzzle without guessing.

Choose the right checks for your puzzle promise

  • “Has one solution” requires a constraint solver that counts completions, not just one successful completion.
  • “Solvable without guessing” requires running the intended logic-only solving rules to completion; uniqueness alone does not prove it.
  • “Same daily puzzle for everyone” requires a canonical date and stable seed, PRNG, generator version, and generation procedure.
  • “Difficulty: easy/medium/hard” requires a stated grading method, such as which solving techniques are needed or a defined complexity score. Clue count alone is not a reliable difficulty label.

These algorithms trade computation for certainty. Sudoku removal may invoke the solver many times, while the simple Nonogram verifier grows exponentially with line length. There are no comparable runtime measurements here, so test performance at the board sizes and traffic levels your application must handle rather than assuming one size or approach will scale to every puzzle.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
PC Slower Than It Used to Be?Free scan - under a minute
Outdated Drivers Are Slowing You DownFree scan - exact matches

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.