Skip to content

Commit 96a29a3

Browse files
committed
Optimize by removing memory allocations.
1 parent a67ff42 commit 96a29a3

File tree

2 files changed

+15
-1
lines changed

2 files changed

+15
-1
lines changed

go/sudoku/generator.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ func randomValue(choices uint16) uint8 {
3232
func randomGrid() Grid {
3333
for {
3434
var s solver
35+
s.init()
3536
// Fill cells with random values until the grid is complete
3637
for _, cell := range randomOrder() {
3738
if s.grid[cell] != 0 {
@@ -60,6 +61,7 @@ func minimize(g Grid) Grid {
6061
g[cell], value = uint8(0), g[cell]
6162
var s solver
6263
var grids []Grid
64+
s.init()
6365
if !s.load(&g) {
6466
panic("minimize expects a valid grid")
6567
}

go/sudoku/solver.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,23 @@ type solver struct {
3232
conflicts [81]uint16 // bitmask - uses bits 1 to 9 out of 16
3333
}
3434

35+
func (s *solver) init() {
36+
// Allocate memory only once instead of growing the slice incrementally.
37+
if s.next != nil {
38+
panic("must init only once")
39+
}
40+
s.next = make([]int, 0, 81)
41+
}
42+
3543
func (s *solver) copy() solver {
44+
// Given that s.next is empty, sharing the same underlying array is fine.
45+
// Indeed, mark() only pushes next steps in the queue and then pops them.
46+
// Since search() explores options sequentially, reusing the same memory
47+
// space for next steps doesn't cause problems.
3648
if len(s.next) > 0 {
3749
panic("must process next before making copy")
3850
}
3951
copy := *s
40-
copy.next = nil // avoid sharing underlying array
4152
return copy
4253
}
4354

@@ -141,6 +152,7 @@ func (s *solver) candidate() int {
141152
func Solve(g *Grid) []Grid {
142153
var s solver
143154
var grids []Grid
155+
s.init()
144156
if s.load(g) {
145157
grids = s.search(grids)
146158
}

0 commit comments

Comments
 (0)