]> fbox.kageds.com Git - adventofcode.git/blob - 2023/gareth/utils/sparseGrid/sparseGrid.go
Day 6
[adventofcode.git] / 2023 / gareth / utils / sparseGrid / sparseGrid.go
1 package sparsegrid
2
3 import (
4 "fmt"
5 "strings"
6
7 "adventofcode2022/utils"
8 )
9
10 type SparseGrid[T comparable] struct {
11 minX, maxX, minY, maxY int
12 data map[string]T
13 empty T
14 }
15
16 func NewGrid[T comparable](empty T) *SparseGrid[T] {
17 return &SparseGrid[T]{
18 minX: utils.MaxInt,
19 maxX: utils.MinInt,
20 minY: utils.MaxInt,
21 maxY: utils.MinInt,
22 data: map[string]T{},
23 empty: empty,
24 }
25 }
26
27 func (g *SparseGrid[T]) SizeX() (int, int) {
28 return g.minX, g.maxX
29 }
30
31 func (g *SparseGrid[T]) SizeY() (int, int) {
32 return g.minY, g.maxY
33 }
34
35 func (g *SparseGrid[T]) Visited() int {
36 return len(g.data)
37 }
38
39 func (g *SparseGrid[T]) Get(x, y int) T {
40 k := key(x, y)
41 v, ok := g.data[k]
42 if !ok {
43 return g.empty
44 }
45 return v
46 }
47
48 func (g *SparseGrid[T]) Set(x, y int, v T) {
49 k := key(x, y)
50 current, ok := g.data[k]
51 if ok && v == current {
52 return
53 } else if !ok && v == g.empty {
54 return
55 } else if v == g.empty {
56 delete(g.data, k)
57 } else {
58 g.data[k] = v
59 g.minX = utils.Min(g.minX, x)
60 g.maxX = utils.Max(g.maxX, x)
61 g.minY = utils.Min(g.minY, y)
62 g.maxY = utils.Max(g.maxY, y)
63 }
64 }
65
66 func (g *SparseGrid[T]) StringWithFormatter(formatter func(T, int, int) string) string {
67 var r strings.Builder
68 for j := g.minY; j <= g.maxY; j++ {
69 for i := g.minX; i <= g.maxX; i++ {
70 _, err := r.WriteString(formatter(g.Get(i, j), i, j))
71 utils.PanicOnErr(err)
72 }
73 _, err := r.WriteRune('\n')
74 utils.PanicOnErr(err)
75 }
76 return r.String()
77 }
78
79 func key(x, y int) string {
80 return fmt.Sprintf("%d:%d", x, y)
81 }