API Reference

sudoku

class sudoku.SudokuSolver()[source]

import {SudokuSolver} from "sudoku-javascript"

Represent a Sudoku Solver object.

constructor()[source]

Create a Sudoku Solver.

The list of strategies to use in order to resolve a grid is initiated.

get strategies()[source]

Return a list of all strategies available.

get strategiesUsed()[source]

Return a list of identifiers for each strategy used.

resolve(grid)[source]

Apply all strategies successively in order to resolve the grid.

Each strategy is applied to the grid until the grid is resolved or until no progress can be made.

grid must be a sudoku.grid.SudokuGrid() instance.

Return whether the grid has been successfully solved.

applyStrategiesUntilFirstResult(grid)[source]

Apply the strategies until one is resolving part of the grid.

grid must be a sudoku.grid.SudokuGrid() instance.

Return a mapping of each modified sudoku.cell.SudokuCell() instances organized per identifier.

Example:

>>> solver.applyStrategiesUntilFirstResult(grid)
{
    "c40": [SudokuCell],
    "c43": [SudokuCell],
}

class sudoku.SudokuGrid(cellMapping = {}, candidatesMapping = {})[source]

import {SudokuGrid} from "sudoku-javascript"

Represent a Sudoku Grid object.

constructor(cellMapping = {}, candidatesMapping = {})[source]

Create a Sudoku Grid 9x9 from a cellMapping.

cellMapping could be a mapping containing values of each cell between 0 and 9 (0 means that the cell is not filled). The grid contains 81 cells with 81 corresponding cell identifier properties that specify the position of the cell in the grid. The first number and the second number of the property name indicate respectfully the row index and the column index. ‘c00’ indicates the cell in the top left corner and ‘c88’ the cell in the bottom right corner.

By default, each cell is initiated to 0.

Example:

>>> new SudokuGrid({
...     c03: 1, c05: 5,
...     c10: 1, c11: 4, c16: 6, c17: 7,
...     c21: 8, c25: 2, c26: 4,
...     c31: 6, c32: 3, c34: 7, c37: 1,
...     c40: 9, c48: 3,
...     c51: 1, c54: 9, c56: 5, c57: 2,
...     c62: 7, c63: 2, c67: 8,
...     c71: 2, c72: 6, c77: 3, c78: 5,
...     c83: 4, c85: 9,
... });

candidatesMapping could be a mapping containing candidate numbers of each cell, following the same identification logic as the cellMapping.

By default, the candidate numbers of each cell are generated according to the initial value of the cell.

Example:

>>> grid = new SudokuGrid(
...     {
...         c00: 3,
...         c10: 9, c11: 7, c13: 2, c14: 1,
...         c20: 6, c23: 5, c24: 8, c25: 3,
...         c30: 2, c36: 9,
...         c40: 5, c43: 6, c44: 2, c45: 1, c48: 3,
...         c52: 8, c58: 5,
...         c63: 4, c64: 3, c65: 5, c68: 2,
...         c74: 9, c77: 5, c78: 6,
...         c88: 1,
...     },
...     {
...         c01: [1, 2, 4, 5, 8], c02: [1, 2, 4, 5], c03: [2, 7, 9],
...         c04: [4, 6, 7], c05: [2, 4, 6, 7, 9],
...         c06: [1, 2, 4, 5, 6, 7, 8], c07: [1, 2, 4, 6, 7, 8, 9],
...         c08: [4, 7, 8, 9],
...         c12: [2, 4, 5], c15: [2, 4, 6], c16: [2, 3, 4, 5, 6, 8],
...         c17: [2, 3, 4, 6, 8], c18: [4, 8],
...         c21: [1, 2, 4], c22: [1, 2, 4], c26: [1, 2, 4, 7],
...         c27: [1, 2, 4, 7, 9], c28: [4, 7, 9],
...         c31: [1, 3, 4, 6], c32: [1, 3, 4, 6, 7], c33: [3, 7, 8],
...         c34: [4, 5, 7], c35: [4, 7, 8], c37: [1, 4, 6, 7, 8],
...         c38: [4, 7, 8],
...         c41: [4, 9], c42: [4, 7, 9], c46: [4, 7, 8], c47: [4, 7, 8],
...         c50: [1, 4, 7], c51: [1, 3, 4, 6, 9], c53: [3, 7, 9],
...         c54: [4, 7], c55: [4, 7, 9], c56: [1, 2, 4, 6, 7],
...         c57: [1, 2, 4, 6, 7],
...         c60: [1, 7, 8], c61: [1, 6, 8, 9], c62: [1, 6, 7, 9],
...         c66: [7, 8], c67: [7, 8, 9],
...         c70: [1, 4, 7, 8], c71: [1, 2, 3, 4, 8],
...         c72: [1, 2, 3, 4, 7], c73: [1, 2, 7, 8], c75: [2, 7, 8],
...         c76: [3, 4, 7, 8],
...         c80: [4, 7, 8], c81: [2, 3, 4, 5, 6, 8, 9],
...         c82: [2, 3, 4, 5, 6, 7, 9], c83: [2, 7, 8], c84: [6, 7],
...         c85: [2, 6, 7, 8], c86: [3, 4, 7, 8, 9],
...         c87: [3, 4, 7, 8, 9],
...     }
... );

Warning

An Error will be raised if the custom list of candidates given to a cell is incoherent with its value.

get rowSize()[source]

Return the number of rows.

get columnSize()[source]

Return the number of columns.

get blockRowSize()[source]

Return the number of rows within each block.

get blockColumnSize()[source]

Return the number of columns within each block.

cell(rowIndex, columnIndex)[source]

Return the value of a cell from rowIndex and columnIndex.

cellFromId(identifier)[source]

Return the cell from its identifier.

Throw an error if the identifier is incorrect.

cellsInRow(rowIndex)[source]

Return list of values from all cells in row from rowIndex.

cellsInColumn(columnIndex)[source]

Return list of values from all cells in column from columnIndex.

cellsInBlock(rowIndex, columnIndex)[source]

Return list of values from all cells in block from rowIndex and columnIndex.

isSolved()[source]

Indicate whether the grid is solved.

A grid is considered solved when all cells are solved, meaning when all cell has a value other than zero.

update()[source]

Update the grid and return the number of solutions found.

Analyse the grid for possible solved cells and compute the resulting candidates for each cell. Repeat this two operations as long as new candidates are found.

updateSolvedCells()[source]

Attempt to resolve all cells in the grid and return the number of solutions found.

A cell which has a single candidate left can be updated with the value of this candidate.

updateCandidates()[source]

Update candidates for all cells and return whether the grid has been modified.

For each 3x3 block, each cell candidates is compared with the value contained in the neighbor block, row and column. If a number from the cell candidates list is matching values from neighbors, it is removed from the cell candidates list.

validate()[source]

Validate the grid and return potential errors.

Errors are returned in the form of an object mapping each cell identifier with a sudoku.cell.SudokuCell() instance:

>>> grid.validate()
{
    "c42": [SudokuCell],
    "c47": [SudokuCell],
}

A valid grid would return an empty object.

toValueMapping()[source]

Return all cell values of the grid as a cell mapping.

The mapping is similar to the cellsMapping argument given to the constructor().

toCandidateMapping()[source]

Return all cell candidates of the grid as a cell mapping.

The mapping is similar to the candidatesMapping argument given to the constructor().

class sudoku.SudokuCell(value, rowIndex, columnIndex, candidates = null)[source]

import {SudokuCell} from "sudoku-javascript"

Represent a Sudoku Cell object.

constructor(value, rowIndex, columnIndex, candidates = null)[source]

Create a Sudoku Cell with an initial value between 0 and 9.

The coordinates of the cell within a grid must be indicated with the rowIndex and columnIndex value.

If the value is 0, the cell is considered as not solved and a list of candidates from 1 to 9 is set. If the value is not 0, the cell is considered as solved and an empty list of candidates is set.

Example:

>>> const cell1 = new SudokuCell(0, 0, 0);
>>> cell1.candidates;
[1, 2, 3, 4, 5, 6, 7, 8, 9]

>>> const cell2 = new SudokuCell(4, 0, 0);
>>> cell2.candidates;
[]

A custom list of candidates can be given.

Warning

A SudokuCellError() is thrown if the custom list of candidates is incoherent with the cell value.

validateCandidates(candidates)[source]

Validate candidates and throw an error if invalid.

A SudokuCellError() is thrown if the candidates list is not empty while the cell already has a non-zero value, or if the candidates list is empty while the cell do not has a non-zero value yet.

get identifier()[source]

Return cell identifier.

get rowIndex()[source]

Return row index of the cell.

get columnIndex()[source]

Return column index of the cell.

get value()[source]

Return value of the cell.

get candidates()[source]

Return list of candidate numbers of the cell.

set candidates(candidates)[source]

Set a new list of candidates to replace the current cell candidates.

Warning

A SudokuCellError() is thrown if the new list of candidates is incoherent with the cell value.

isSolved()[source]

Indicate whether the cell is solved.

updateCandidates(rowValues, columnValues, blockValues)[source]

Compute candidates from its neighbor list of rowValues, columnValues and blockValues.

If a number from the candidates list is matching values from one of these list, it is removed from the candidates list.

Return whether a list of new candidates has been successfully computed.

Warning

If the list of new candidates is bigger than the current list of candidates, it is not applied.

Warning

A SudokuCellError() is thrown if the updated list of candidates is incoherent with the cell value.

resolve()[source]

Attempt to resolve the cell and return whether it has been solved.

When one number remains in the candidates list, extract this number and set it as the new cell value.

clone(candidates = null)[source]

Return a new cell instance cloning the current instance.

A new list of candidates can be given. Otherwise the current list of candidates will be passed to the cloned instance.

sudoku.SudokuCellError(message, identifier)[source]

import {SudokuCellError} from "sudoku-javascript"

Error thrown when an error appears in the SudokuCell().

It includes the identifier of the cell.

Example:

const cell = new SudokuCell(0, 3, 5);

try {
    cell.candidates = [];
}
catch (error) {
    console.log(error.message);
    console.log(error.identifier);
}

class sudoku.HiddenTripleStrategy()[source]

import {HiddenTripleStrategy} from "sudoku-javascript"

Hidden Triple Strategy.

Identify when three cells from a row, a column or a block can only contain three specific candidate numbers and remove other candidate numbers from those cells.

static processCells(cells)[source]

Attempt to resolve cells.

cells must be a list of SudokuCell() instances.

Return a mapping of sudoku.cell.SudokuCell() cloned instances with updated candidates list per cell identifier.

class sudoku.HiddenQuadStrategy()[source]

import {HiddenQuadStrategy} from "sudoku-javascript"

Hidden Quad Strategy.

Identify when four cells from a row, a column or a block can only contain four specific candidate numbers and remove other candidate numbers from those cells.

static processCells(cells)[source]

Attempt to resolve cells.

cells must be a list of SudokuCell() instances.

Return a mapping of sudoku.cell.SudokuCell() cloned instances with updated candidates list per cell identifier.

class sudoku.HiddenSingleStrategy()[source]

import {HiddenSingleStrategy} from "sudoku-javascript"

Hidden Single Strategy.

Identify when a cell from a row, a column or a block can only contain a specific candidate number and remove other candidate numbers from this cell.

static processCells(cells)[source]

Attempt to resolve cells.

cells must be a list of SudokuCell() instances.

Return a mapping of sudoku.cell.SudokuCell() cloned instances with updated candidates list per cell identifier.

class sudoku.NakedPairStrategy()[source]

import {NakedPairStrategy} from "sudoku-javascript"

Naked Pair Strategy.

Identify when two candidate numbers can only be in two specific cells from a row, a column or a block and remove these candidates from other cells.

static processCells(cells)[source]

Attempt to resolve cells.

cells must be a list of SudokuCell() instances.

Return a mapping of sudoku.cell.SudokuCell() cloned instances with updated candidates list per cell identifier.

class sudoku.NakedTripleStrategy()[source]

import {NakedTripleStrategy} from "sudoku-javascript"

Naked Triple Strategy.

Identify when three candidate numbers can only be in three specific cells from a row, a column or a block and remove these candidates from other cells.

static processCells(cells)[source]

Attempt to resolve cells.

cells must be a list of SudokuCell() instances.

Return a mapping of sudoku.cell.SudokuCell() cloned instances with updated candidates list per cell identifier.

class sudoku.HiddenPairStrategy()[source]

import {HiddenPairStrategy} from "sudoku-javascript"

Hidden Pair Strategy.

Identify when two cells from a row, a column or a block can only contain two specific candidate numbers and remove other candidate numbers from those cells.

static processCells(cells)[source]

Attempt to resolve cells.

cells must be a list of SudokuCell() instances.

Return a mapping of sudoku.cell.SudokuCell() cloned instances with updated candidates list per cell identifier.

class sudoku.PointingStrategy()[source]

import {PointingStrategy} from "sudoku-javascript"

Pointing Strategy.

Identify when a candidate number appears two or three time within the row or column of a block and remove it from other cells in the rest of the row or column.

static processCells(cellsInRows, cellsInColumns)[source]

Attempt to resolve cells.

cellsInRows and cellsInColumns are collections of sudoku.cell.SudokuCell() instance lists.

Return a mapping of sudoku.cell.SudokuCell() cloned instances with updated candidates list per cell identifier.

static getBlockCounters(cells)[source]

Return candidate counters for intersection block of rows and columns.

Count the occurrence of each cell candidate for the entire block and for each row and column within the intersection.

cells must be a list of sudoku.cell.SudokuCell() instances.

Example:

>>> getBlocCounters(cells);
{
    global: {'4': 5, '1': 4, '8': 3, '9': 3, '2': 2, '3': 2},
    row: {
        0: {'8': 2, '4': 2, '2': 1},
        1: {'1': 3, '9': 3, '3': 2, '4': 2, '2': 1},
        2: {'8': 1, '1': 1, '4': 1},
    },
    column: {
        0: {'1': 1, '3': 1, '9': 1},
        1: {'4': 3, '8': 2, '1': 2, '9': 1},
        2: {'2': 2, '4': 2, '1': 1, '3': 1, '8': 1, '9': 1},
    },
}
static getNonBlockCellsMapping(cellsInBlock, cellsInRows, cellsInColumns)[source]

Return mapping of cells per row and column indices.

cellsInBlock is a collection of all sudoku.cell.SudokuCell() instance lists within the block.

cellsInRows is a collection of sudoku.cell.SudokuCell() instance lists for each row which has an intersection with the block.

cellsInColumns is a collection of sudoku.cell.SudokuCell() instance lists for each column which has an intersection with the block.

Example:

>>> getNonBlockCellsMapping(
...     cellsInBlock, cellsInRows, cellsInColumns
... );
{
    row: {
        0: [[SudokuCell], [SudokuCell], [SudokuCell]],
        1: [[SudokuCell], [SudokuCell], [SudokuCell]],
        2: [[SudokuCell], [SudokuCell], [SudokuCell]],
        6: [[SudokuCell], [SudokuCell], [SudokuCell]],
        7: [[SudokuCell], [SudokuCell], [SudokuCell]],
        8: [[SudokuCell], [SudokuCell], [SudokuCell]],
    },
    column: {
        3: [[SudokuCell], [SudokuCell], [SudokuCell]],
        4: [[SudokuCell], [SudokuCell], [SudokuCell]],
        5: [[SudokuCell], [SudokuCell], [SudokuCell]],
        6: [[SudokuCell], [SudokuCell], [SudokuCell]],
        7: [[SudokuCell], [SudokuCell], [SudokuCell]],
        8: [[SudokuCell], [SudokuCell], [SudokuCell]],
    },
}
static getMatchingCandidates(counters)[source]

Return list of matching cell candidates per row and column.

counters is a mapping of candidate counters for intersection block of rows and columns, such as the one returned by getBlockCounters()

Each candidate is organised by tuple where the first element is the row or column index and the second is the candidate number.

Example:

>>> getMatchingCandidates(counters)
{
    row: [
        [1, 3], [1, 9]
    ],
    column: [
        [8, 2]
    ],
}
static getMatchingCells(candidatesMapping, cellsMapping)[source]

Return cloned cells with updated candidates from candidatesMapping.

The result is a mapping of sudoku.cell.SudokuCell() cloned instances with updated candidates list per cell identifier.

candidatesMapping is a mapping of cell candidates lists organised per rows and columns, such as the one returned by getMatchingCandidates()

cellsMapping is a mapping of all non-block cells organised per row and columns, such as the one returned by getNonBlockCellsMapping()

class sudoku.BoxLineReductionStrategy()[source]

import {BoxLineReductionStrategy} from "sudoku-javascript"

Box Line Reduction Strategy.

Identify when a candidate number appears two or three time within the row or column of a block and remove it from other cells of the block.

static processCells(cellsInRows, cellsInColumns)[source]

Attempt to resolve cells.

cellsInRows and cellsInColumns are collections of sudoku.cell.SudokuCell() instance lists.

Return a mapping of sudoku.cell.SudokuCell() cloned instances with updated candidates list per cell identifier.

static getCounters(cellsInRows, cellsInColumns)[source]

Return candidate counters for rows and columns.

Count the occurrence of each cell candidate for each row and column.

cellsInRows is a collection of sudoku.cell.SudokuCell() instance lists for each row.

cellsInColumns is a collection of sudoku.cell.SudokuCell() instance lists for each column.

Example:

>>> getCounters(cellsInRows, cellsInColumns);
{
    row: {
         0: {'1': 2, '2': 3, '3': 3, '6': 2, '7': 2, '8': 3},
         1: {'2': 2, '3': 4, '4': 4, '5': 2, '8': 4, '9': 3},
         2: {'1': 2, '4': 3, '6': 2, '7': 2, '8': 3, '9': 4},
         3: {'7': 1, '8': 1, '9': 1},
         4: {'5': 1, '6': 1, '8': 1, '9': 1},
         5: {'5': 1, '6': 2, '7': 2, '8': 3},
         6: {'1': 2, '2': 2, '3': 1, '4': 2, '6': 2, '9': 3},
         7: {'2': 2, '3': 1, '4': 2, '6': 2, '8': 3},
         8: {'1': 1, '2': 1},
    },
    column: {
         0: {'1': 2, '2': 4, '6': 3, '7': 2, '8': 4, '9': 3},
         1: {'2': 3, '4': 3, '7': 3, '8': 4, '9': 2},
         2: {'1': 3, '3': 2, '4': 4, '5': 2, '6': 4, '8': 6, '9': 4},
         3: {'1': 2, '3': 1, '4': 1, '6': 2, '8': 1},
         4: {'3': 1, '4': 1, '5': 1, '8': 1},
         5: {'3': 2, '4': 2, '5': 1, '7': 2},
         6: {'2': 2, '3': 2, '6': 2, '9': 2},
         7: {'2': 1, '3': 1, '8': 2, '9': 1},
         8: {},
    },
}
static getCellsMapping(cells)[source]

Return mapping of cells per row and column indices.

cells must be a list of sudoku.cell.SudokuCell() instances.

Example:

>>> getCellsMapping(cells);
{
    row: {
        0: [[SudokuCell], [SudokuCell], [SudokuCell]],
        1: [[SudokuCell], [SudokuCell], [SudokuCell]],
        2: [[SudokuCell], [SudokuCell], [SudokuCell]],
        6: [[SudokuCell], [SudokuCell], [SudokuCell]],
        7: [[SudokuCell], [SudokuCell], [SudokuCell]],
        8: [[SudokuCell], [SudokuCell], [SudokuCell]],
    },
    column: {
        3: [[SudokuCell], [SudokuCell], [SudokuCell]],
        4: [[SudokuCell], [SudokuCell], [SudokuCell]],
        5: [[SudokuCell], [SudokuCell], [SudokuCell]],
        6: [[SudokuCell], [SudokuCell], [SudokuCell]],
        7: [[SudokuCell], [SudokuCell], [SudokuCell]],
        8: [[SudokuCell], [SudokuCell], [SudokuCell]],
    },
}
static getMatchingCandidates(mapping, counters)[source]

Return list of matching cell candidates per row and column.

mapping is a mapping of block cells per row and column indices.

counters is a mapping of candidate counters for rows and columns, such as the one returned by getCounters()

Each candidate is organised by tuple where the first element is the row or column index and the second is the candidate number.

Example:

>>> getMatchingCandidates(counters)
{
    row: [
        [0, 2], [1, 6]
    ],
    column: [
        [4, 9]
    ],
}
static getMatchingCells(candidatesMapping, cellsMapping)[source]

Return cloned cells with updated candidates from candidatesMapping.

The result is a mapping of sudoku.cell.SudokuCell() cloned instances with updated candidates list per cell identifier.

candidatesMapping is a mapping of cell candidates lists organised per rows and columns, such as the one returned by getMatchingCandidates()

cellsMapping is a mapping of all cells organised per row and columns, such as the one returned by getCellsMapping()