adventofcode/helpers/growUpCoordinateByteMap.go

113 lines
2.2 KiB
Go

package aoc
import (
"math"
)
type GrowUpCoordByteMap struct {
Field map[Coordinate]byte
Height int
Width int
// The Top-Left-most X/Y
// (Low X, High Y)
TLX, TLY int
// The Bottom-Right-most X/Y
// (High X, Low Y)
BRX, BRY int
// Options for the 'String' method
StringEmptyIsSpace bool
StringEmptyByte byte
}
func NewGrowUpCoordByteMap() *GrowUpCoordByteMap {
return &GrowUpCoordByteMap{
Field: make(map[Coordinate]byte),
TLX: math.MaxInt,
TLY: math.MinInt,
BRX: math.MinInt,
BRY: math.MaxInt,
StringEmptyByte: ' ',
}
}
func (m *GrowUpCoordByteMap) FindAll(b ...byte) []Coordinate {
var ret []Coordinate
for y := m.TLY; y >= m.BRY; y-- {
for x := m.TLX; x <= m.BRX; x++ {
c := Coordinate{X: x, Y: y}
for i := range b {
if m.Get(c) == b[i] {
ret = append(ret, c)
}
}
}
}
return ret
}
func (m *GrowUpCoordByteMap) Get(pos Coordinate) byte {
if v, ok := m.Field[pos]; ok {
return v
}
return 0
}
func (m *GrowUpCoordByteMap) Opt(pos Coordinate, def byte) byte {
if v, ok := m.Field[pos]; ok {
return v
}
return def
}
func (m *GrowUpCoordByteMap) Put(pos Coordinate, val byte) {
m.Field[pos] = val
m.Measure()
}
func (m *GrowUpCoordByteMap) PutBytes(bytes [][]byte, at Coordinate) {
for y := range bytes {
for x := range bytes[y] {
m.Put(Coordinate{X: at.X + x, Y: at.Y + y}, bytes[y][x])
}
}
m.Measure()
}
func (m *GrowUpCoordByteMap) Delete(pos Coordinate) {
delete(m.Field, pos)
m.Measure()
}
func (m *GrowUpCoordByteMap) Measure() {
m.TLX, m.TLY = math.MaxInt, math.MinInt
m.BRX, m.BRY = math.MinInt, math.MaxInt
for c := range m.Field {
if c.X < m.TLX {
m.TLX = c.X
}
if c.Y < m.BRY {
m.BRY = c.Y
}
if c.X > m.BRX {
m.BRX = c.X
}
if c.Y > m.TLY {
m.TLY = c.Y
}
m.Width = m.BRX - m.TLX + 1
m.Height = m.TLY - m.BRY + 1
}
}
func (m GrowUpCoordByteMap) String() string {
var ret string
for y := m.TLY; y >= m.BRY; y-- {
for x := m.TLX; x <= m.BRX; x++ {
if m.StringEmptyIsSpace {
ret = ret + string(m.Opt(Coordinate{X: x, Y: y}, m.StringEmptyByte))
} else {
ret = ret + string(m.Field[Coordinate{X: x, Y: y}])
}
}
if y > m.BRY {
ret = ret + "\n"
}
}
return ret
}