var easyBoard = [
[1,0,0,3,0,0,9,5,2],
[0,4,0,6,0,0,1,0,0],
[3,0,0,1,0,0,0,0,0],
[0,6,4,7,2,0,0,1,0],
[8,7,0,9,0,6,0,2,4],
[0,2,0,0,8,5,7,6,0],
[0,0,0,0,0,1,0,0,7],
[0,0,7,0,0,9,0,4,0],
[2,3,9,0,0,4,0,0,1]
];
var hardBoard = [
[4,0,0,6,0,7,0,8,5],
[0,0,0,0,0,0,6,0,0],
[0,0,7,0,0,0,0,0,0],
[0,5,0,0,0,3,0,0,4],
[3,7,0,0,0,8,0,0,0],
[6,0,0,2,0,0,0,0,0],
[8,0,0,0,0,0,3,1,0],
[0,3,1,0,4,9,0,0,0],
[0,0,0,0,0,0,0,0,9]
];
var solve = function (board) {
var empty = []; // We create an array for the 1x1 squares with no value, so we can call upon them with ease later on.
for (var i = 0; i < 9; i++) {
for (var j = 0; j < 9; j++) {
if (board[i][j] === 0) {
empty.push([i,j]);
}
}
}
for (var i = 0; i < empty.length;) { // We check every possible value for all empty 1x1 squares.
var row = empty[i][0]; // Used for row and 3x3 square checks
var column = empty[i][1]; // Used for column and 3x3 square checks
var value = board[row][column] + 1; // We start at 1, because obviously 0 is not a Sudoku value.
var found = false; // We assume the value is invalid, unless it passes all three tests.
while (!found && value <= 9) { // As long as the value is invalid, we increase by one until it reaches more than 9.
var equal = false; // We assume for now that the value is not equal to any other in its row, column or 3x3 square.
for (var y = 0; y < 9; y++) {
if (board[row][y] === value) {
equal = true;
}
}
for (var x = 0; x < 9; x++) {
if (board[x][column] === value) {
equal = true;
}
}
for (var x = 3*Math.floor(row/3); x < 3*Math.floor(row/3)+3; x++) {
for (var y = 3*Math.floor(column/3); y < 3*Math.floor(column/3)+3; y++) {
if (board[x][y] === value) {
equal = true;
}
}
}
if (!equal) { // If the value is not equal to any other in its row, column or 3x3 square, it is valid.
found = true; // We have found a valid value, for now.
board[row][column] = value; // We assign said value to the corresponding board 1x1 square, for now.
i++; // We then move on to the next empty 1x1 square.
}
else {
value++; // If the value is invalid, we simply try the next possible value.
}
}
if (!found) { // If, from 1 to 9, the value is invalid, it means the one before is invalid.
board[row][column] = 0; // We then re-assign an empty value to the 1x1 square, before backtracking.
i--; // We go back to the previous 1x1 square to try a different value.
}
}
};
// test routines
var clone2 = array => array.slice().map( row=>row.slice());
function easyTest() {
var board = clone2( easyBoard);
solve( board);
console.log( "easy board solution:");
console.log( board);
}
function hardTest() {
var board = clone2( hardBoard);
solve( board);
console.log( "hard board solution:");
console.log( board);
}
<button type="button" onclick="easyTest()">Easy Test</button>
<button type="button" onclick="hardTest()">Hard Test</button>