adventofcode/2022/day16/main.go

113 lines
2.4 KiB
Go

package main
import (
"fmt"
"math"
"strings"
h "git.bullercodeworks.com/brian/adventofcode/helpers"
)
func main() {
inp := h.StdinToStringSlice()
part1(inp)
}
func part1(inp []string) {
volcano := NewVolcano(inp)
timeLeft := 30
currRoom := volcano.FindRoom("AA")
_, _ = timeLeft, currRoom
fmt.Println("Steps from AA -> JJ:", volcano.CountSteps("AA", "JJ"))
}
type Volcano struct {
rooms []*Room
}
func NewVolcano(inp []string) *Volcano {
v := &Volcano{}
for i := range inp {
v.rooms = append(v.rooms, StringToRoom(inp[i]))
}
for i := range v.rooms {
for _, valve := range v.rooms[i].RawTunnels {
v.rooms[i].Tunnels = append(v.rooms[i].Tunnels, v.FindRoom(valve))
}
}
return v
}
func (v *Volcano) CountSteps(from string, to string) int {
start, end := v.FindRoom(from), v.FindRoom(to)
if start == nil || end == nil {
fmt.Println("Couldn't find requested rooms:", from, ":", start, " ; ", to, ":", end)
return math.MaxInt
}
return v.TrackStepCount(start, end, []*Room{})
}
func (v *Volcano) TrackStepCount(from *Room, to *Room, visited []*Room) int {
if from == to {
return 0
}
minSteps := math.MaxInt
for _, t := range from.Tunnels {
fmt.Println("TrackStepCount:", from, "->", to, "::", t)
if !IsRoomIn(t, visited) {
fmt.Println(" Haven't Visited")
wrk := v.TrackStepCount(t, to, append(visited, t)) + 1
fmt.Println(" From", from, "to", to, "in", wrk)
minSteps = h.Min(minSteps, wrk)
}
}
return minSteps
}
func (v *Volcano) FindRoom(valve string) *Room {
for _, r := range v.rooms {
if r.Valve == valve {
return r
}
}
return nil
}
func IsRoomIn(room *Room, rooms []*Room) bool {
for i := range rooms {
if rooms[i] == room {
return true
}
}
return false
}
type Room struct {
Valve string
FlowRate int
RawTunnels []string
Tunnels []*Room
}
func StringToRoom(s string) *Room {
room := &Room{}
r := strings.NewReader(s)
fmt.Fscanf(r, "Valve %s has flow rate=%d; tunnels lead to valve", &room.Valve, &room.FlowRate)
readTunnels := strings.Split(s, " valve")[1]
if readTunnels[0] == ' ' {
readTunnels = readTunnels[1:]
} else {
readTunnels = readTunnels[2:]
}
room.RawTunnels = strings.Split(readTunnels, ", ")
return room
}
func (r Room) String() string {
return r.Valve
}
func (r Room) FullString() string {
return fmt.Sprintf("Valve %s has flow rate=%d; tunnels lead to valves %v", r.Valve, r.FlowRate, r.RawTunnels)
}