-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsudoku.go
133 lines (110 loc) · 2.02 KB
/
sudoku.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package sudoku
import "fmt"
const (
Unset uint8 = 0
N = 9
)
type Grid [N][N]uint8
// Valid validates a sudoku Grid without modification.
func Valid(g *Grid) bool {
return Solve(clone(g))
}
// Solve solves sudoku Grid inplace and returns true if valid. Otherwise, returns false.
func Solve(g *Grid) bool { return solve(g, 0, 0) }
func solve(g *Grid, row, col int) bool {
if row == N {
return true
}
if col == N {
return solve(g, row+1, 0)
}
if g[row][col] != Unset {
return solve(g, row, col+1)
}
for i := 1; i <= N; i++ {
val := uint8(i)
if !validMove(g, row, col, val) {
continue
}
// set value
g[row][col] = val
// recursively attempt to solve the rest of the cells
if solve(g, row, col+1) {
return true
}
// else backtrack
g[row][col] = Unset
}
return false
}
func validMove(g *Grid, row, col int, val byte) bool {
// validate row
if rowContains(g, row, val) {
return false
}
// validate column
if colContains(g, col, val) {
return false
}
// validate box
if boxContains(g, row, col, val) {
return false
}
return true
}
func rowContains(g *Grid, row int, val byte) bool {
for _, cell := range g[row] {
if cell == val {
return true
}
}
return false
}
func colContains(g *Grid, col int, val byte) bool {
for row := 0; row < N; row++ {
cell := g[row][col]
if cell == val {
return true
}
}
return false
}
func boxContains(g *Grid, row, col int, val byte) bool {
r := int(row/3) * 3
c := int(col/3) * 3
for i, m := r, r+3; i < m; i++ {
for j, n := c, c+3; j < n; j++ {
cell := g[i][j]
if cell == val {
return true
}
}
}
return false
}
// clone preforms a deep clone.
func clone(g *Grid) *Grid {
c := new(Grid)
for i := 0; i < N; i++ {
for j := 0; j < 9; j++ {
c[i][j] = g[i][j]
}
}
return c
}
func Print(g *Grid) {
for i, row := range g {
if i != 0 {
println()
if i%3 == 0 {
println()
}
}
for j, cell := range row {
if j != 0 && j%3 == 0 {
print(" ")
}
fmt.Printf("%d ", cell)
}
}
}