113 lines
2.4 KiB
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)
|
|
}
|