class Sudoku { // Sudoku Class to hold the board and related functions constructor(board) { this.board = board } findEmptyCell() { // Find a empty cell in the board (returns [-1, -1] if all cells are filled) for (let i = 0; i < 9; i++) { for (let j = 0; j < 9; j++) { if (this.board[i][j] === 0) return [i, j] } } return [-1, -1] } check([y, x], value) { // checks if the value to be added in the board is an acceptable value for the cell // checking through the row for (let i = 0; i < 9; i++) { if (this.board[i][x] === value) return false } // checking through the column for (let i = 0; i < 9; i++) { if (this.board[y][i] === value) return false } // checking through the 3x3 block of the cell const secRow = Math.floor(y / 3) const secCol = Math.floor(x / 3) for (let i = secRow * 3; i < secRow * 3 + 3; i++) { for (let j = secCol * 3; j < secCol * 3 + 3; j++) { if (y !== i && x !== j && this.board[i][j] === value) return false } } return true } solve() { const [y, x] = this.findEmptyCell() // checking if the board is complete if (y === -1 && x === -1) return true for (let val = 1; val < 10; val++) { if (this.check([y, x], val)) { this.board[y][x] = val if (this.solve()) return true // backtracking if the board cannot be solved using current configuration this.board[y][x] = 0 } } // returning false the board cannot be solved using current configuration return false } getSection(row, [start, end]) { return this.board[row].slice(start, end) } printBoard(output = (...v) => console.log(...v)) { // helper function to display board for (let i = 0; i < 9; i++) { if (i % 3 === 0 && i !== 0) { output('- - - - - - - - - - - -') } output( ...this.getSection(i, [0, 3]), ' | ', ...this.getSection(i, [3, 6]), ' | ', ...this.getSection(i, [6, 9]) ) } } } export { Sudoku }