day23, part1
This commit is contained in:
112
day23/field.go
Normal file
112
day23/field.go
Normal file
@@ -0,0 +1,112 @@
|
||||
package day23
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Coord struct {
|
||||
Row, Col int
|
||||
}
|
||||
|
||||
type CellType rune
|
||||
|
||||
const (
|
||||
Path CellType = '.'
|
||||
Tree CellType = '#'
|
||||
SlideDown CellType = 'v'
|
||||
SlideUp CellType = '^'
|
||||
SlideLeft CellType = '<'
|
||||
SlideRight CellType = '>'
|
||||
)
|
||||
|
||||
type Field struct {
|
||||
MaxRow, MaxCol int
|
||||
Cells map[Coord]CellType
|
||||
StartCol, EndCol int
|
||||
}
|
||||
|
||||
func (f *Field) Neighbors(c Coord) (neighbors []Coord) {
|
||||
symb, exists := f.Cells[c]
|
||||
if !exists {
|
||||
panic(fmt.Sprintf("coord %+v not found in field", c))
|
||||
}
|
||||
|
||||
var coords []Coord
|
||||
switch symb {
|
||||
case Path:
|
||||
coords = []Coord{
|
||||
{Row: c.Row + 1, Col: c.Col},
|
||||
{Row: c.Row - 1, Col: c.Col},
|
||||
{Row: c.Row, Col: c.Col + 1},
|
||||
{Row: c.Row, Col: c.Col - 1},
|
||||
}
|
||||
case Tree:
|
||||
panic(fmt.Sprintf("attempting to get neighbors of a tree at %+v", c))
|
||||
case SlideDown:
|
||||
coords = []Coord{{Row: c.Row + 1, Col: c.Col}}
|
||||
case SlideUp:
|
||||
coords = []Coord{{Row: c.Row - 1, Col: c.Col}}
|
||||
case SlideLeft:
|
||||
coords = []Coord{{Row: c.Row, Col: c.Col - 1}}
|
||||
case SlideRight:
|
||||
coords = []Coord{{Row: c.Row, Col: c.Col + 1}}
|
||||
}
|
||||
|
||||
for _, coord := range coords {
|
||||
neighborSymb, found := f.Cells[coord]
|
||||
if !found || neighborSymb == Tree {
|
||||
continue
|
||||
}
|
||||
neighbors = append(neighbors, coord)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (f *Field) String() (result string) {
|
||||
result += "\n"
|
||||
for row := 0; row <= f.MaxRow; row++ {
|
||||
for col := 0; col <= f.MaxCol; col++ {
|
||||
if row == 0 && col == f.StartCol {
|
||||
result += "S"
|
||||
continue
|
||||
}
|
||||
if row == f.MaxRow && col == f.EndCol {
|
||||
result += "E"
|
||||
continue
|
||||
}
|
||||
|
||||
symb := f.Cells[Coord{Row: row, Col: col}]
|
||||
result += string(symb)
|
||||
}
|
||||
result += "\n"
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func ReadField(filename string) (result Field) {
|
||||
bytes, err := os.ReadFile(filename)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
lines := strings.Split(strings.TrimSpace(string(bytes)), "\n")
|
||||
result.MaxRow = len(lines) - 1
|
||||
result.MaxCol = len(lines[0]) - 1
|
||||
rows := make(map[Coord]CellType)
|
||||
|
||||
for rowNum, row := range lines {
|
||||
for colNum, symb := range row {
|
||||
rows[Coord{Row: rowNum, Col: colNum}] = CellType(symb)
|
||||
if rowNum == 0 && symb == rune(Path) {
|
||||
result.StartCol = colNum
|
||||
}
|
||||
if rowNum == result.MaxRow && symb == rune(Path) {
|
||||
result.EndCol = colNum
|
||||
}
|
||||
}
|
||||
}
|
||||
result.Cells = rows
|
||||
|
||||
return
|
||||
}
|
||||
Reference in New Issue
Block a user