Skip to content

Instantly share code, notes, and snippets.

@linxGnu
Created April 16, 2019 06:27
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 linxGnu/2d7b9712fc69a908ac63aec0c7182de0 to your computer and use it in GitHub Desktop.
Save linxGnu/2d7b9712fc69a908ac63aec0c7182de0 to your computer and use it in GitHub Desktop.
func solveSudoku(board [][]byte) {
convertBoard(board)
// solve sudoku
rows := make([][]bool, 9)
for i := range rows {
rows[i] = make([]bool, 10)
}
cols := make([][]bool, 9)
for i := range cols {
cols[i] = make([]bool, 10)
}
area := make([][]bool, 9)
for i := range area {
area[i] = make([]bool, 10)
}
//
notFill := 0
for i, v := range board {
for j := range v {
if v[j] == 0 {
notFill++
} else {
rows[i][v[j]] = true
cols[j][v[j]] = true
area[getAreaIndex(i,j)][v[j]] = true
}
}
}
//
x, y := make([]int, notFill), make([]int, notFill)
blankCount := 0
for i, v := range board {
for j := range v {
if v[j] == 0 {
x[blankCount], y[blankCount] = i, j
blankCount++
}
}
}
//
_solve(0, byte(notFill), board, x, y, rows, cols, area)
//
convertBoard(board)
}
func _solve(current, limit byte, board [][]byte, x, y []int, rows, cols, area [][]bool) bool {
if current >= limit {
return true
}
i, j := x[current], y[current]
k := getAreaIndex(i, j)
var v byte
for v = 1; v <= 9; v++ {
if !rows[i][v] && !cols[j][v] && !area[k][v] {
rows[i][v], cols[j][v], area[k][v] = true, true, true
board[i][j] = v
if _solve(current+1, limit, board, x, y, rows, cols, area) {
return true
}
rows[i][v], cols[j][v], area[k][v] = false, false, false
}
}
return false
}
func convertBoard(board [][]byte) [][]byte {
for _, v := range board {
for j := range v {
if v[j] == 46 {
v[j] = 0
} else if v[j] >= 48 {
v[j] -= 48
} else if v[j] == 0 {
v[j] = 46
} else {
v[j] += 48
}
}
}
return board
}
func getAreaIndex(i, j int) int {
r, c := i / 3, j / 3
return r * 3 + c
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment