A sudoku solver using Go.
Simple! Forget about storage space and care only about speed!
- the
Entryin eachTile.- An
Entryis anint, since I don't care about input. - A
Tileis auint8, since we only need numbers 0 through 9 (where 0 is an emptyTile).
- An
- the total number of entries placed in the puzzle.
- Stored as an
int
- Stored as an
- the entries present in each row.
- Represented as a
Presence, which isuint16 - The bits on
Presencerepresent which entries are present in that row, where1 << 0means 1 is present,1 << 1means 2 is present, etc. - We make it a
uint16because we need at least 9 bits to represent numbers 1 through 9 and use 0 as "No entrys present in this row".
- Represented as a
- the entries present in each column.
- the entries present in each box.
- the number of open spots in each row.
- Represented as a
uint8 - Initialized to 9 on creation of the
Puzzle - We cache this so that we don't have to calculate it from the
Presencefor the row every time we need it.
- Represented as a
- the number of open spots in each col.
- the number of open spots in each box.
Base Case: The puzzle has the number of entries equal to the number of tiles
- Assume the puzzle is solved and return the
Puzzle
Else: Try solving the Puzzle!
- Find the best (row, col) location
[br][bc]for attempting placement- Scan the rows and cols and find the row and the col with the least number of entries
- If the best row
brhas fewer or the same free spots as the best col,- Find the column
cwhich has an open tile in[br][c]and the fewest open tiles in columnc
- Find the column
- Else the best column
bchas fewer free spots than the best row,- Find the row
rwhich has an open tile in[r][bc]and the fewest open tiles in rowr
- Find the row
- Get the Entrys,
entries, which are available at the best location- Basically use the bitstrings of the present Entrys in the row, col, box to identify what can be placed at
[br][bc]
- Basically use the bitstrings of the present Entrys in the row, col, box to identify what can be placed at
- foreach
Entry einentries- Copy the current puzzle into
pClone - In
pClone, placeeat[br][bc]and update all the other puzzle state vars - Call
solveonpClone - If that returns a valid solution, pass that on up
- Else, continue with the foreach loop because we are guaranteed one of the possible entries goes in this location
- Copy the current puzzle into
- Make sure this is in your machine's Go path.
- Running
go run main_runner.gowill solve all the puzzles in the example file.
Don't.
A coworker and I want to try solving three dimensional Sudokus, if that's possible. So we're in a little friendly competition about who can write the better two dimensional solver. His solves in 120ms, but mine's at 9ms on average.