99 lines
1.8 KiB
Go
99 lines
1.8 KiB
Go
package main
|
|
|
|
import (
|
|
"bufio"
|
|
_ "embed"
|
|
"fmt"
|
|
|
|
aoc "go.sour.is/advent-of-code"
|
|
)
|
|
|
|
// var log = aoc.Log
|
|
|
|
func main() { aoc.MustResult(aoc.Runner(runner(64))) }
|
|
|
|
type result struct {
|
|
valuePT1 int
|
|
valuePT2 int
|
|
}
|
|
|
|
func (r result) String() string { return fmt.Sprintf("%#v", r) }
|
|
|
|
func runner(rounds int) func(scan *bufio.Scanner) (*result, error) {
|
|
return func(scan *bufio.Scanner) (*result, error) {
|
|
var garden garden
|
|
|
|
for scan.Scan() {
|
|
txt := scan.Text()
|
|
garden.m = append(garden.m, []rune(txt))
|
|
|
|
for i, c := range txt {
|
|
if c == 'S' {
|
|
garden.start[0] = len(garden.m) - 1
|
|
garden.start[1] = i
|
|
}
|
|
}
|
|
}
|
|
garden.Step(rounds)
|
|
return &result{
|
|
valuePT1: len(garden.steps[len(garden.steps)-1]),
|
|
}, nil
|
|
}
|
|
}
|
|
|
|
type garden struct {
|
|
start aoc.Point[int]
|
|
m [][]rune
|
|
steps []aoc.Set[aoc.Point[int]]
|
|
}
|
|
|
|
func (g *garden) Neighbors(p aoc.Point[int]) []aoc.Point[int] {
|
|
var neighbors []aoc.Point[int]
|
|
for _, n := range []aoc.Point[int]{
|
|
{p[0] - 1, p[1]},
|
|
{p[0] + 1, p[1]},
|
|
{p[0], p[1] - 1},
|
|
{p[0], p[1] + 1},
|
|
} {
|
|
if n[0] >= 0 && n[0] < len(g.m) && n[1] >= 0 && n[1] < len(g.m[0]) && g.m[n[0]][n[1]] != '#' {
|
|
neighbors = append(neighbors, n)
|
|
}
|
|
}
|
|
return neighbors
|
|
}
|
|
|
|
func (g *garden) Step(n int) {
|
|
if len(g.steps) == 0 {
|
|
g.steps = append(g.steps, aoc.NewSet(g.start))
|
|
}
|
|
|
|
for step := range(n) {
|
|
g.steps = append(g.steps, aoc.NewSet[aoc.Point[int]]())
|
|
for p := range g.steps[step] {
|
|
for _, n := range g.Neighbors(p) {
|
|
g.steps[step+1].Add(n)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func (g garden) String() string {
|
|
var b []rune
|
|
for i, line := range g.m {
|
|
if i == g.start[0] {
|
|
line[g.start[1]] = 'X'
|
|
}
|
|
|
|
if steps := len(g.steps) - 1; steps > 0 {
|
|
for p := range g.steps[len(g.steps)-1] {
|
|
if p[0] == i {
|
|
line[p[1]] = 'O'
|
|
}
|
|
}
|
|
}
|
|
|
|
b = append(b, line...)
|
|
b = append(b, '\n')
|
|
}
|
|
return string(b)
|
|
} |