adventofcode/helpers/coordinateByteMap.go

169 lines
3.1 KiB
Go

package aoc
type CoordByteMap struct {
Field map[Coordinate]byte
Height int
Width int
}
func StringSliceToCoordByteMap(input []string) CoordByteMap {
ret := CoordByteMap{
Field: make(map[Coordinate]byte),
Height: len(input),
Width: 0,
}
for y := range input {
for x := range input[y] {
ret.Field[Coordinate{X: x, Y: y}] = input[y][x]
if x > ret.Width {
ret.Width = x
}
}
}
return ret
}
func (m *CoordByteMap) Get(pos Coordinate) byte {
if v, ok := m.Field[pos]; ok {
return v
}
return 0
}
func (m *CoordByteMap) Opt(pos Coordinate, def byte) byte {
if v, ok := m.Field[pos]; ok {
return v
}
return def
}
func (m *CoordByteMap) Put(pos Coordinate, val byte) {
m.Field[pos] = val
}
func (m CoordByteMap) String() string {
var ret string
for y := 0; y <= m.Height; y++ {
for x := 0; x <= m.Width; x++ {
ret = ret + string(m.Field[Coordinate{X: x, Y: y}])
}
ret = ret + "\n"
}
return ret
}
// And the 3d Version
type Coord3dByteMap struct {
Field map[Coordinate3d]byte
MinX, MaxX int
MinY, MaxY int
MinZ, MaxZ int
}
func StringSliceToCoord3dByteMap(input []string) Coord3dByteMap {
ret := Coord3dByteMap{
Field: make(map[Coordinate3d]byte),
}
for y := range input {
for x := range input[y] {
ret.Put(Coordinate3d{X: x, Y: y, Z: 0}, input[y][x])
}
}
return ret
}
func (m *Coord3dByteMap) Copy() Coord3dByteMap {
ret := Coord3dByteMap{
Field: make(map[Coordinate3d]byte),
MinX: m.MinX, MaxX: m.MaxX,
MinY: m.MinY, MaxY: m.MaxY,
MinZ: m.MinZ, MaxZ: m.MaxZ,
}
for z := m.MinZ; z <= m.MaxZ; z++ {
for y := m.MinY; y <= m.MaxY; y++ {
for x := m.MinX; x <= m.MaxX; x++ {
c := Coordinate3d{X: x, Y: y, Z: z}
ret.Field[c] = m.Get(c)
}
}
}
return ret
}
func (m *Coord3dByteMap) Get(pos Coordinate3d) byte {
if _, ok := m.Field[pos]; !ok {
return 0
}
return m.Field[pos]
}
func (m *Coord3dByteMap) Opt(pos Coordinate3d, def byte) byte {
if v, ok := m.Field[pos]; ok {
return v
}
return def
}
func (m *Coord3dByteMap) Put(pos Coordinate3d, val byte) {
m.Field[pos] = val
if pos.X < m.MinX {
m.MinX = pos.X
}
if pos.X > m.MaxX {
m.MaxX = pos.X
}
if pos.Y < m.MinY {
m.MinY = pos.X
}
if pos.Y > m.MaxY {
m.MaxY = pos.Y
}
if pos.Z < m.MinZ {
m.MinZ = pos.Z
}
if pos.Z > m.MaxZ {
m.MaxZ = pos.Z
}
}
func (m *Coord3dByteMap) CountNeighbors(pos Coordinate3d, val byte) int {
var res int
for z := pos.Z - 1; z <= pos.Z+1; z++ {
for y := pos.Y - 1; y <= pos.Y+1; y++ {
for x := pos.X - 1; x <= pos.X+1; x++ {
if m.Get(Coordinate3d{X: x, Y: y, Z: z}) == val {
res++
}
}
}
}
return res
}
func (m Coord3dByteMap) Count(val byte) int {
var ret int
for z := m.MinZ; z <= m.MaxZ; z++ {
for y := m.MinY; y <= m.MaxY; y++ {
for x := m.MinX; x <= m.MaxX; x++ {
if m.Get(Coordinate3d{X: x, Y: y, Z: z}) == val {
ret++
}
}
}
}
return ret
}
func (m Coord3dByteMap) String() string {
var ret string
for z := m.MinZ; z <= m.MaxZ; z++ {
for y := m.MinY; y <= m.MaxY; y++ {
for x := m.MinX; x <= m.MaxX; x++ {
ret = ret + string(m.Field[Coordinate3d{X: x, Y: y, Z: z}])
}
ret = ret + "\n"
}
ret = ret + "\n\n"
}
return ret
}