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) }