2021 Day 25 Part 1
This commit is contained in:
parent
fde48e8321
commit
daa30dde06
1 changed files with 123 additions and 0 deletions
123
2021/day25/main.go
Normal file
123
2021/day25/main.go
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/jdkaplan/advent-of-code/aoc"
|
||||
)
|
||||
|
||||
func main() {
|
||||
lines := aoc.Input().ReadLines("day25.txt")
|
||||
fmt.Println(part1(lines))
|
||||
}
|
||||
|
||||
func part1(lines []string) int {
|
||||
f := NewFloor(lines)
|
||||
moved := true
|
||||
i := 0
|
||||
for moved {
|
||||
f, moved = f.Tick()
|
||||
i++
|
||||
}
|
||||
return i
|
||||
}
|
||||
|
||||
type RC struct{ r, c int }
|
||||
|
||||
type Floor struct {
|
||||
east, south map[RC]bool
|
||||
rows, cols int
|
||||
}
|
||||
|
||||
func NewFloor(lines []string) Floor {
|
||||
f := Floor{
|
||||
east: make(map[RC]bool),
|
||||
south: make(map[RC]bool),
|
||||
rows: len(lines),
|
||||
cols: len(lines[0]),
|
||||
}
|
||||
for r, row := range lines {
|
||||
for c, char := range row {
|
||||
rc := RC{r, c}
|
||||
switch char {
|
||||
case 'v':
|
||||
f.south[rc] = true
|
||||
case '>':
|
||||
f.east[rc] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
return f
|
||||
}
|
||||
|
||||
func (f Floor) Occupied(rc RC) bool {
|
||||
return f.east[rc] || f.south[rc]
|
||||
}
|
||||
|
||||
func (f Floor) EastOf(rc RC) RC {
|
||||
c := (rc.c + 1) % f.cols
|
||||
return RC{rc.r, c}
|
||||
}
|
||||
|
||||
func (f Floor) SouthOf(rc RC) RC {
|
||||
r := (rc.r + 1) % f.rows
|
||||
return RC{r, rc.c}
|
||||
}
|
||||
|
||||
func (f Floor) Tick() (Floor, bool) {
|
||||
next, eastward := f.TickEast()
|
||||
next, southward := next.TickSouth()
|
||||
return next, eastward || southward
|
||||
}
|
||||
|
||||
func (f Floor) TickEast() (Floor, bool) {
|
||||
next := f
|
||||
next.east = make(map[RC]bool)
|
||||
moved := false
|
||||
for rc := range f.east {
|
||||
t := f.EastOf(rc)
|
||||
if f.Occupied(t) {
|
||||
next.east[rc] = true
|
||||
} else {
|
||||
next.east[t] = true
|
||||
moved = true
|
||||
}
|
||||
}
|
||||
return next, moved
|
||||
}
|
||||
|
||||
func (f Floor) TickSouth() (Floor, bool) {
|
||||
next := f
|
||||
next.south = make(map[RC]bool)
|
||||
moved := false
|
||||
for rc := range f.south {
|
||||
t := f.SouthOf(rc)
|
||||
if f.Occupied(t) {
|
||||
next.south[rc] = true
|
||||
} else {
|
||||
next.south[t] = true
|
||||
moved = true
|
||||
}
|
||||
}
|
||||
return next, moved
|
||||
}
|
||||
|
||||
func (f Floor) String() string {
|
||||
var sb strings.Builder
|
||||
for r := 0; r < f.rows; r++ {
|
||||
for c := 0; c < f.cols; c++ {
|
||||
rc := RC{r, c}
|
||||
switch {
|
||||
case f.east[rc]:
|
||||
sb.WriteByte('>')
|
||||
case f.south[rc]:
|
||||
sb.WriteByte('v')
|
||||
default:
|
||||
sb.WriteByte('.')
|
||||
}
|
||||
}
|
||||
sb.WriteString("\n")
|
||||
}
|
||||
return sb.String()
|
||||
}
|
||||
Loading…
Reference in a new issue