Skip to content

Instantly share code, notes, and snippets.

@tuxsudo
Last active July 6, 2017 22:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tuxsudo/04a7243ec848e1a7a4ce11c488e38498 to your computer and use it in GitHub Desktop.
Save tuxsudo/04a7243ec848e1a7a4ce11c488e38498 to your computer and use it in GitHub Desktop.
const myPuzzle = [
1, null, 9, null, null, null, null, 6, null,
5, 3, null, null, 7, null, null, null, null,
null, null, 4, null, 2, 6, null, null, null,
null, 5, null, null, null, null, null, null, 4,
null, 7, null, 6, 3, 4, null, 2, null,
6, null, null, null, null, null, null, 7, null,
null, null, null, 7, 4, null, 9, null, null,
null, null, null, null, 1, null, null, 5, 2,
null, 9, null, null, null, null, 4, null, 3
];
const puzzleRowByRowIdx = (puzzle, i) => puzzle.slice(i*9, i*9+9);
const puzzleColByColIdx = (puzzle, i) =>
[ puzzle[i], puzzle[i+9], puzzle[i+18], puzzle[i+27], puzzle[i+36], puzzle[i+45], puzzle[i+54], puzzle[i+63], puzzle[i+72] ];
const puzzleSquareBySquareIdx = (puzzle, i) => {
const cell0 = [0,3,6,27,30,33,54,57,60][i];
return [
puzzle[cell0], puzzle[cell0+1], puzzle[cell0+2],
puzzle[cell0+9], puzzle[cell0+10], puzzle[cell0+11],
puzzle[cell0+18], puzzle[cell0+19], puzzle[cell0+20]
];
}
const validateGroup = (group=[]) =>
group
.reduce(
(acc, num, idx, nums) => acc && (num===null||nums.indexOf(num)===idx),
true
);
const validatePuzzle = puzzle => {
for(let i = 0; i < 9; i++) {
const rowIsValid = validateGroup(puzzleRowByRowIdx(puzzle, i));
if(!rowIsValid) {
return false;
}
const colIsValid = validateGroup(puzzleColByColIdx(puzzle, i));
if(!colIsValid) {
return false;
}
const squareIsValid = validateGroup(puzzleSquareBySquareIdx(puzzle, i));
if(!squareIsValid) {
return false;
}
}
return true;
}
const checkPuzzleCompletion = puzzle =>
puzzle.filter(x=>x).length===81;
const solve = (puzzle, cell = 0, tryWith = 1) => {
// set recursion bounds
if(cell > 80) {
return false;
}
if( checkPuzzleCompletion(puzzle) ) {
return validatePuzzle(puzzle)
? puzzle
: false;
}
const value = puzzle[cell];
// move to next empty cell if already a number in current cell...
if(value!==null) {
return solve(puzzle, cell+1);
}
let attempt = [].concat(puzzle);
attempt[cell] = tryWith;
const isValid = validatePuzzle(attempt);
if(isValid) {
const solved = solve(attempt, cell+1);
if(solved) {
return solved;
}
}
// not valid with current attempt, or unsolveable branch...
if(tryWith < 9) {
return solve(puzzle, cell, tryWith+1);
}
return false;
}
console.log( solve(myPuzzle) );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment