Solves 9x9 sudoku puzzles.
A script by V.
function sudoku(puzzle) { | |
// returns the solved puzzle as a 2d array of 9 x 9 | |
const possibleValues = [1,2,3,4,5,6,7,8,9]; | |
let sections = []; | |
// create array of values for 3x3 sections | |
for (let i = 0; i < 9; i++) { sections.push([]); } | |
puzzle.forEach((row, rIndex) => { | |
row.forEach((cell, cIndex) => { | |
if (cell) { // ignore 0 | |
if (rIndex <= 2) { | |
if (cIndex <= 2) { sections[0].push(cell); } | |
else if (cIndex <= 5) { sections[1].push(cell); } | |
else if (cIndex <= 8) { sections[2].push(cell); } | |
} else if (rIndex <= 5) { | |
if (cIndex <= 2) { sections[3].push(cell); } | |
else if (cIndex <= 5) { sections[4].push(cell); } | |
else if (cIndex <= 8) { sections[5].push(cell); } | |
} else if (rIndex <= 8) { | |
if (cIndex <= 2) { sections[6].push(cell); } | |
else if (cIndex <= 5) { sections[7].push(cell); } | |
else if (cIndex <= 8) { sections[8].push(cell); } | |
} | |
} | |
}); | |
}); | |
//console.log('sections:', JSON.stringify(sections)); | |
// iterate puzzle and solve it | |
while (sections.filter((val) => val.length < 9).length > 0) { | |
for (let rIndex = 0, rMax = puzzle.length; rIndex < rMax; rIndex++) { | |
for (let cIndex = 0, cMax = puzzle[rIndex].length; cIndex < cMax; cIndex++) { | |
if (!puzzle[rIndex][cIndex]) { | |
let square; // current section | |
if (rIndex <= 2) { | |
if (cIndex <= 2) { square = sections[0]; } | |
else if (cIndex <= 5) { square = sections[1]; } | |
else if (cIndex <= 8) { square = sections[2]; } | |
} else if (rIndex <= 5) { | |
if (cIndex <= 2) { square = sections[3]; } | |
else if (cIndex <= 5) { square = sections[4]; } | |
else if (cIndex <= 8) { square = sections[5]; } | |
} else if (rIndex <= 8) { | |
if (cIndex <= 2) { square = sections[6]; } | |
else if (cIndex <= 5) { square = sections[7]; } | |
else if (cIndex <= 8) { square = sections[8]; } | |
} | |
const squareMissing = possibleValues.filter((val) => square.indexOf(val) === -1); | |
const rowMissing = possibleValues.filter((val, i) => puzzle[rIndex].indexOf(val) === -1); | |
const columnPresent = puzzle.reduce((a, b) => { return (b[cIndex] !== 0) ? a.concat(b[cIndex]) : a }, []); | |
const columnMissing = possibleValues.filter((val) => columnPresent.indexOf(val) === -1); | |
/* | |
console.log('squareMissing:', squareMissing); | |
console.log('rowMissing:', rowMissing); | |
console.log('columnPresent:', columnPresent); | |
console.log('columnMissing:', columnMissing); | |
*/ | |
const options = squareMissing.filter((val) => rowMissing.indexOf(val) !== -1 && columnMissing.indexOf(val) !== -1); | |
//console.log('options:', options); | |
if (options.length === 1) { | |
const option = options[0]; | |
if (squareMissing.indexOf(option) !== -1 && rowMissing.indexOf(option) !== -1 && columnMissing.indexOf(option) !== -1) { | |
square.push(option); | |
puzzle[rIndex][cIndex] = option; | |
} | |
//console.log('sections:', JSON.stringify(sections)); | |
} | |
} | |
} | |
} | |
} | |
//console.log(puzzle); | |
return puzzle; | |
} |