UNPKG

fast-sudoku-solver

Version:
64 lines 3.25 kB
import { cloneSudoku, getPossibleEntries, isCorrectlySolved } from './solver-utils'; /** * Calculates the next number for the specified Sudoku puzzle. * The function returns whether the puzzle *isSolvable*, and it returns the *row*, the *column*, and the *entry* itself for the next number. * * In particular, the function returns the entry for the field with the fewest number of possible entries. * For instance, if there is a field with 7 possible entries and another field with only 2 possible entries, a correct entry for the latter is returned. * * **NOTE:** If the Sudoku puzzle is already completely solved, this function returns value -1 for *row*, *column*, and *entry*. * @param sudoku the Sudoku puzzle for which the next entry should be calculated * @returns the entry for the next field */ export function solveNextNumber(sudoku) { let minNumberOfPossibleEntries = 10; // initially set to something greather than 9 such that one field is picked even in empty Sudoku let rowMinNumber = -1; let columnMinNumber = -1; let possibleEntriesMinNumber = []; for (let i = 0; i < 9; i++) { for (let j = 0; j < 9; j++) { // field already filled? continue with next field if (sudoku[i][j] >= 1) { continue; } // get possible entries for current field const possibleEntries = getPossibleEntries(sudoku, i, j); // no possible entries? Sudoku not solvable if (possibleEntries.length === 0) { return { isSolvable: false, row: i, column: j, entry: -1 }; } // only one possibility left? add entry and start recursive call // NOTE: recursive call is needed as we still want to check whether the puzzle is completely solvable if (possibleEntries.length === 1) { const clone = cloneSudoku(sudoku); clone[i][j] = possibleEntries[0]; return { isSolvable: solveNextNumber(clone).isSolvable, row: i, column: j, entry: possibleEntries[0] }; } // multiple possible entries? find field with lowest number of possibilities if (possibleEntries.length < minNumberOfPossibleEntries) { minNumberOfPossibleEntries = possibleEntries.length; rowMinNumber = i; columnMinNumber = j; possibleEntriesMinNumber = possibleEntries; } } } // if arrived here: try out as many possibilities as needed for field with lowest number of possibilities const clone = cloneSudoku(sudoku); for (let i = 0; i < possibleEntriesMinNumber.length; i++) { clone[rowMinNumber][columnMinNumber] = possibleEntriesMinNumber[i]; const result = solveNextNumber(clone); if (!result.isSolvable) { continue; } return { isSolvable: result.isSolvable, row: rowMinNumber, column: columnMinNumber, entry: possibleEntriesMinNumber[i], }; } // if arrived here: solver is done return { isSolvable: isCorrectlySolved(clone), row: -1, column: -1, entry: -1 }; } //# sourceMappingURL=next-number-solver.js.map