2022 Day 24 Complete
This commit is contained in:
121
2022/day24/main.go
Normal file
121
2022/day24/main.go
Normal file
@@ -0,0 +1,121 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
h "git.bullercodeworks.com/brian/adventofcode/helpers"
|
||||
)
|
||||
|
||||
func main() {
|
||||
input := h.StdinToStringSlice()
|
||||
part1(input)
|
||||
part2(input)
|
||||
}
|
||||
|
||||
func part1(input []string) {
|
||||
field, blizzards, start, target := parseInput(input)
|
||||
fmt.Println("# Part 1")
|
||||
fmt.Println(run(field, blizzards, start, target))
|
||||
}
|
||||
|
||||
func part2(input []string) {
|
||||
field, blizzards, start, target := parseInput(input)
|
||||
fmt.Println("# Part 2")
|
||||
fmt.Println(run(field, blizzards, start, target) +
|
||||
run(field, blizzards, target, start) +
|
||||
run(field, blizzards, start, target))
|
||||
}
|
||||
|
||||
type Blizzard struct {
|
||||
pos, dir, wrap h.Coordinate
|
||||
}
|
||||
|
||||
var (
|
||||
U = h.Coordinate{X: 0, Y: -1}
|
||||
D = h.Coordinate{X: 0, Y: 1}
|
||||
L = h.Coordinate{X: -1, Y: 0}
|
||||
R = h.Coordinate{X: 1, Y: 0}
|
||||
)
|
||||
|
||||
var directions []h.Coordinate = []h.Coordinate{U, D, L, R}
|
||||
|
||||
func parseInput(lines []string) (field [][]rune, blizzards []Blizzard, start, target h.Coordinate) {
|
||||
start.X = strings.Index(lines[0], "E")
|
||||
if start.X == -1 {
|
||||
start.X = strings.Index(lines[0], ".")
|
||||
}
|
||||
target.Y = len(lines) - 1
|
||||
target.X = strings.Index(lines[target.Y], ".")
|
||||
for _, line := range lines {
|
||||
line = strings.TrimSpace(line)
|
||||
field = append(field, []rune(line))
|
||||
}
|
||||
for y, row := range field {
|
||||
for x, c := range row {
|
||||
switch c {
|
||||
case '^':
|
||||
blizzards = append(blizzards, Blizzard{
|
||||
h.Coordinate{X: x, Y: y}, U, h.Coordinate{X: x, Y: len(field) - 2},
|
||||
})
|
||||
case 'v':
|
||||
blizzards = append(blizzards, Blizzard{
|
||||
h.Coordinate{X: x, Y: y}, D, h.Coordinate{X: x, Y: 1},
|
||||
})
|
||||
case '<':
|
||||
blizzards = append(blizzards, Blizzard{
|
||||
h.Coordinate{X: x, Y: y}, L, h.Coordinate{X: len(field[0]) - 2, Y: y},
|
||||
})
|
||||
case '>':
|
||||
blizzards = append(blizzards, Blizzard{
|
||||
h.Coordinate{X: x, Y: y}, R, h.Coordinate{X: 1, Y: y},
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func valid(field [][]rune, pos h.Coordinate) bool {
|
||||
return pos.X >= 0 && pos.X < len(field[0]) && pos.Y >= 0 && pos.Y < len(field)
|
||||
}
|
||||
|
||||
func run(field [][]rune, blizzards []Blizzard, start, target h.Coordinate) int {
|
||||
minutes := 0
|
||||
currentStep := make(map[h.Coordinate]bool)
|
||||
currentStep[start] = true
|
||||
|
||||
for !currentStep[target] {
|
||||
//update blizzards
|
||||
whereBlizzards := make(map[h.Coordinate]bool)
|
||||
for i, b := range blizzards {
|
||||
bb := b.pos.Add(b.dir)
|
||||
if valid(field, bb) {
|
||||
if field[bb.Y][bb.X] == '#' {
|
||||
blizzards[i].pos = b.wrap
|
||||
} else {
|
||||
blizzards[i].pos = bb
|
||||
}
|
||||
}
|
||||
whereBlizzards[blizzards[i].pos] = true
|
||||
}
|
||||
|
||||
//find new steps
|
||||
newStep := make(map[h.Coordinate]bool)
|
||||
for pos := range currentStep {
|
||||
if !(whereBlizzards[pos]) {
|
||||
newStep[pos] = true
|
||||
}
|
||||
for _, d := range directions {
|
||||
n := pos.Add(d)
|
||||
if valid(field, n) && field[n.Y][n.X] != '#' && !whereBlizzards[n] {
|
||||
newStep[n] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
currentStep = newStep
|
||||
minutes++
|
||||
}
|
||||
|
||||
return minutes
|
||||
}
|
||||
Reference in New Issue
Block a user