Files
adventofcode/2022/go/utils/sparseGrid/sparseGrid.go
2023-11-16 10:48:53 +00:00

82 lines
1.5 KiB
Go

package sparsegrid
import (
"fmt"
"strings"
"adventofcode2022/utils"
)
type SparseGrid[T comparable] struct {
minX, maxX, minY, maxY int
data map[string]T
empty T
}
func NewGrid[T comparable](empty T) *SparseGrid[T] {
return &SparseGrid[T]{
minX: utils.MaxInt,
maxX: utils.MinInt,
minY: utils.MaxInt,
maxY: utils.MinInt,
data: map[string]T{},
empty: empty,
}
}
func (g *SparseGrid[T]) SizeX() (int, int) {
return g.minX, g.maxX
}
func (g *SparseGrid[T]) SizeY() (int, int) {
return g.minY, g.maxY
}
func (g *SparseGrid[T]) Visited() int {
return len(g.data)
}
func (g *SparseGrid[T]) Get(x, y int) T {
k := key(x, y)
v, ok := g.data[k]
if !ok {
return g.empty
}
return v
}
func (g *SparseGrid[T]) Set(x, y int, v T) {
k := key(x, y)
current, ok := g.data[k]
if ok && v == current {
return
} else if !ok && v == g.empty {
return
} else if v == g.empty {
delete(g.data, k)
} else {
g.data[k] = v
g.minX = utils.Min(g.minX, x)
g.maxX = utils.Max(g.maxX, x)
g.minY = utils.Min(g.minY, y)
g.maxY = utils.Max(g.maxY, y)
}
}
func (g *SparseGrid[T]) StringWithFormatter(formatter func(T, int, int) string) string {
var r strings.Builder
for j := g.minY; j <= g.maxY; j++ {
for i := g.minX; i <= g.maxX; i++ {
_, err := r.WriteString(formatter(g.Get(i, j), i, j))
utils.PanicOnErr(err)
}
_, err := r.WriteRune('\n')
utils.PanicOnErr(err)
}
return r.String()
}
func key(x, y int) string {
return fmt.Sprintf("%d:%d", x, y)
}