Created
August 17, 2023 21:43
-
-
Save ntatko/04bcacfb6ce3e12daac23b33ff0fed79 to your computer and use it in GitHub Desktop.
Sample sudoku solver
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const floor3 = (n) => { | |
| if (n%3 === 0) { | |
| return n | |
| } | |
| return floor3(n - 1) | |
| } | |
| // Class to help keep track of the proper order of things. | |
| class Sudoku { | |
| constructor (puzzle, annotations) { | |
| this.puzzle = puzzle | |
| this.originalPuzzle = puzzle | |
| this.annotations = annotations | |
| this.originalAnnotations = annotations | |
| } | |
| get isUnchanged () { | |
| return deepEqual(this.annotations, this.originalAnnotations) && deepEqual(this.puzzle, this.originalPuzzle) | |
| } | |
| post () { return [this.puzzle, this.annotations]; } | |
| getRow(n) { return this.puzzle[n]; } | |
| getColumn(n) { return this.puzzle.map(row => row[n]); } | |
| getSquare(i, j) { | |
| const is = [floor3(i), floor3(i) + 1, floor3(i) + 2] | |
| const js = [floor3(j), floor3(j) + 3] | |
| return is.map(rowIndex => this.puzzle[rowIndex].slice(...js)).reduce((acc, rowBits) => [...acc, ...rowBits], []) | |
| } | |
| getRowAnnotations(n) { return this.annotations[n] } | |
| getColumnAnnotations(n) { return this.annotations.map(row => row[n])} | |
| getSquareAnnotations(i, j) { | |
| const is = [floor3(i), floor3(i) + 1, floor3(i) + 2] | |
| const js = [floor3(j), floor3(j) + 3] | |
| return is.map(rowIndex => this.annotations[rowIndex].slice(...js)).reduce((acc, rowBits) => [...acc, ...rowBits], []) | |
| } | |
| } | |
| const getAnnotationCountOf = (annotations, n) => { | |
| return annotations.reduce((all, cellAnnotations) => { | |
| return [...all, ...cellAnnotations] | |
| }).filter(ann => ann === n).length | |
| } | |
| const annotate = (puzzle) => { | |
| const annotations = puzzle.puzzle.map((row, i) => { | |
| return row.map((cell, j) => { | |
| if (cell !== 0) { | |
| return [] | |
| } | |
| const possibles = [1, 2, 3, 4, 5, 6, 7, 8, 9] | |
| const row = puzzle.getRow(i) | |
| const column = puzzle.getColumn(j) | |
| const square = puzzle.getSquare(i, j) | |
| const remaining = [...row, ...column, ...square].reduce((acc, num) => { | |
| return acc.filter(n => n !== num) | |
| }, possibles) | |
| return remaining | |
| }) | |
| }) | |
| puzzle.annotations = annotations | |
| puzzle.puzzle.forEach((row, i) => { | |
| row.forEach((cell, j) => { | |
| if (cell === 0 && puzzle.annotations[i][j].length === 1) { | |
| puzzle.puzzle[i][j] = puzzle.annotations[i][j][0] | |
| } else if (puzzle.annotations[i][j].length > 1) { | |
| puzzle.annotations[i][j].find(annotation => { | |
| const rowCount = getAnnotationCountOf(puzzle.getRowAnnotations(i), annotation) | |
| const columnCount = getAnnotationCountOf(puzzle.getColumnAnnotations(j), annotation) | |
| const squareCount = getAnnotationCountOf(puzzle.getSquareAnnotations(i, j), annotation) | |
| if ([rowCount, columnCount, squareCount].includes(1)) { | |
| puzzle.puzzle[i][j] = annotation | |
| } | |
| }) | |
| } | |
| }) | |
| }) | |
| } | |
| const loop = (currentPuzzle, currentAnnotations) => { | |
| const sudokuPuzzle = new Sudoku(currentPuzzle, currentAnnotations) | |
| annotate(sudokuPuzzle) | |
| return sudokuPuzzle.post() | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment