2025-12-07 07:59:27 -06:00
|
|
|
package grid
|
|
|
|
|
|
2025-12-07 21:25:34 -06:00
|
|
|
import (
|
2025-12-08 05:39:47 -06:00
|
|
|
"strings"
|
|
|
|
|
|
2025-12-07 21:25:34 -06:00
|
|
|
"github.com/StevanFreeborn/advent-of-code-2025/internal/move"
|
|
|
|
|
"github.com/StevanFreeborn/advent-of-code-2025/internal/position"
|
|
|
|
|
)
|
|
|
|
|
|
2025-12-07 07:59:27 -06:00
|
|
|
type Grid interface {
|
2025-12-07 21:25:34 -06:00
|
|
|
NumberOfRows() int
|
|
|
|
|
NumberOfColumns() int
|
|
|
|
|
InBounds(position.Position) bool
|
|
|
|
|
GetValueAt(position.Position) string
|
|
|
|
|
GetSameNeighborsOf(position.Position, []move.Move) []position.Position
|
2025-12-07 21:33:11 -06:00
|
|
|
Positions() map[position.Position]string
|
2025-12-08 05:39:47 -06:00
|
|
|
SetValuesAt(positions []position.Position, value string)
|
2025-12-07 07:59:27 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type grid struct {
|
2025-12-07 21:25:34 -06:00
|
|
|
numberOfRows int
|
|
|
|
|
numberOfColumns int
|
|
|
|
|
positions map[position.Position]string
|
2025-12-07 07:59:27 -06:00
|
|
|
}
|
|
|
|
|
|
2025-12-08 05:39:47 -06:00
|
|
|
func New(positions map[position.Position]string) Grid {
|
|
|
|
|
return grid{positions: positions}
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-07 21:25:34 -06:00
|
|
|
func From(input []string) Grid {
|
2025-12-07 07:59:27 -06:00
|
|
|
numberOfRows := len(input)
|
|
|
|
|
numberOfColumns := len(input[0])
|
2025-12-07 21:25:34 -06:00
|
|
|
positions := map[position.Position]string{}
|
2025-12-07 07:59:27 -06:00
|
|
|
|
|
|
|
|
for row := range numberOfRows {
|
|
|
|
|
for column := range numberOfColumns {
|
|
|
|
|
value := string(input[row][column])
|
2025-12-07 21:25:34 -06:00
|
|
|
pos := position.From(row, column)
|
2025-12-07 07:59:27 -06:00
|
|
|
positions[pos] = value
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return grid{
|
2025-12-07 21:25:34 -06:00
|
|
|
numberOfRows: numberOfRows,
|
|
|
|
|
numberOfColumns: numberOfColumns,
|
|
|
|
|
positions: positions,
|
2025-12-07 07:59:27 -06:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-07 21:25:34 -06:00
|
|
|
func (g grid) NumberOfRows() int {
|
|
|
|
|
return g.numberOfRows
|
|
|
|
|
}
|
2025-12-07 07:59:27 -06:00
|
|
|
|
2025-12-07 21:25:34 -06:00
|
|
|
func (g grid) NumberOfColumns() int {
|
|
|
|
|
return g.numberOfColumns
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (g grid) InBounds(pos position.Position) bool {
|
2025-12-07 21:35:36 -06:00
|
|
|
_, ok := g.positions[pos]
|
|
|
|
|
return ok
|
2025-12-07 07:59:27 -06:00
|
|
|
}
|
|
|
|
|
|
2025-12-07 21:25:34 -06:00
|
|
|
func (g grid) GetValueAt(pos position.Position) string {
|
|
|
|
|
return g.positions[pos]
|
2025-12-07 07:59:27 -06:00
|
|
|
}
|
|
|
|
|
|
2025-12-07 21:25:34 -06:00
|
|
|
func (g grid) GetSameNeighborsOf(pos position.Position, moves []move.Move) []position.Position {
|
|
|
|
|
similarNeighbors := []position.Position{}
|
|
|
|
|
originalValue := g.GetValueAt(pos)
|
2025-12-07 07:59:27 -06:00
|
|
|
|
2025-12-07 21:25:34 -06:00
|
|
|
for _, m := range moves {
|
|
|
|
|
postionRow := pos.Row()
|
|
|
|
|
positionColumn := pos.Column()
|
2025-12-07 07:59:27 -06:00
|
|
|
|
2025-12-07 21:25:34 -06:00
|
|
|
neighborRow := postionRow + m.NumberOfRows()
|
|
|
|
|
neighborColumn := positionColumn + m.NumberOfColumns()
|
|
|
|
|
neighborPos := position.From(neighborRow, neighborColumn)
|
2025-12-07 07:59:27 -06:00
|
|
|
|
2025-12-07 21:25:34 -06:00
|
|
|
if g.InBounds(neighborPos) == false {
|
|
|
|
|
continue
|
|
|
|
|
}
|
2025-12-07 07:59:27 -06:00
|
|
|
|
2025-12-07 21:25:34 -06:00
|
|
|
neighborValue := g.GetValueAt(neighborPos)
|
2025-12-07 07:59:27 -06:00
|
|
|
|
2025-12-07 21:25:34 -06:00
|
|
|
if neighborValue != originalValue {
|
|
|
|
|
continue
|
|
|
|
|
}
|
2025-12-07 07:59:27 -06:00
|
|
|
|
2025-12-07 21:25:34 -06:00
|
|
|
similarNeighbors = append(similarNeighbors, neighborPos)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return similarNeighbors
|
2025-12-07 07:59:27 -06:00
|
|
|
}
|
2025-12-07 21:33:11 -06:00
|
|
|
|
|
|
|
|
func (g grid) Positions() map[position.Position]string {
|
|
|
|
|
positions := map[position.Position]string{}
|
|
|
|
|
|
|
|
|
|
for pos, value := range g.positions {
|
|
|
|
|
newPosition := position.From(pos.Row(), pos.Column())
|
|
|
|
|
positions[newPosition] = value
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return positions
|
|
|
|
|
}
|
2025-12-08 05:39:47 -06:00
|
|
|
|
|
|
|
|
func (g grid) SetValuesAt(positions []position.Position, value string) {
|
|
|
|
|
for _, pos := range positions {
|
|
|
|
|
g.positions[pos] = value
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (g grid) String() string {
|
|
|
|
|
var rowString strings.Builder
|
|
|
|
|
|
|
|
|
|
for row := range g.numberOfRows {
|
|
|
|
|
var colString strings.Builder
|
|
|
|
|
|
|
|
|
|
for col := range g.numberOfColumns {
|
|
|
|
|
pos := position.From(row, col)
|
|
|
|
|
value := g.positions[pos]
|
|
|
|
|
colString.WriteString(value)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rowString.WriteString(colString.String() + "\n")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return rowString.String()
|
|
|
|
|
}
|