Skip to content

Instantly share code, notes, and snippets.

@dsasse07
Last active February 17, 2021 17:41
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 dsasse07/30f7489219b5af00daeefae2e1688515 to your computer and use it in GitHub Desktop.
Save dsasse07/30f7489219b5af00daeefae2e1688515 to your computer and use it in GitHub Desktop.
Sudoku recursive solver function & shuffler
// startingBoard is a 9x9 matrix of zeros
const numArray = [1, 2, 3, 4, 5, 6, 7, 8, 9]
const shuffle = array => {
let newArray = [...array]
for ( let i = newArray.length - 1; i > 0; i-- ) {
const j = Math.floor( Math.random() * ( i + 1 ) );
[ newArray[ i ], newArray[ j ] ] = [ newArray[ j ], newArray[ i ] ];
}
return newArray;
}
const fillPuzzle = startingBoard => {
const emptyCell = nextEmptyCell(startingBoard)
// If there are no more zeros, the board is finished, return it
return startingBoard if (!emptyCell)
for (num of shuffle(numArray) ) {
// counter is a global variable tracking the number of iterations performed in generating a puzzle
// Most puzzles generate in < 500ms, but occassionally random generation could run in to
// heavy backtracking and result in a long wait. Best to abort this attempt and restart.
// See initializer function for more
counter++
if ( counter > 20_000_000 ) throw new Error ("Recursion Timeout")
if ( safeToPlace( startingBoard, emptyCell, num) ) {
// If safe to place number, place it
startingBoard[ emptyCell.rowIndex ][ emptyCell.colIndex ] = num
// Recursively call the fill function to place num in next empty cell
return startingBoard if ( fillPuzzle(startingBoard) )
// If we were unable to place the future num, that num was wrong.
// Reset it and try next
startingBoard[ emptyCell.rowIndex ][ emptyCell.colIndex ] = 0
}
}
// If unable to place any number, return false,
// causing previous round to go to next num
return false
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment