package main import ( "fmt" "slices" "strings" h "git.bullercodeworks.com/brian/adventofcode/helpers" ) func main() { inp := h.StdinToStringSlice() part1(inp) fmt.Println() part2(inp) } func part1(inp []string) { m := parseInput(inp) cache = make(map[string]int) fmt.Println("# Part 1") fmt.Println(findPaths("you", "out", m)) } func part2(inp []string) { m := parseInput(inp) fmt.Println("# Part 2") fmt.Println(findPaths2(m, m["svr"], false, false, map[track]int{})) } type track struct { node string fft, dac bool } func parseInput(inp []string) map[string][]string { ret := make(map[string][]string) for i := range inp { pts := strings.Fields(inp[i]) st := pts[0][:len(pts[0])-1] ret[st] = pts[1:] } return ret } var cache map[string]int func findPaths(start, end string, m map[string][]string) int { if v, ok := cache[start]; ok { return v } var ret int v := m[start] for i := range v { if v[i] == end { ret++ } else { ret += findPaths(v[i], end, m) } } cache[start] = ret return ret } func findPaths2(m map[string][]string, vals []string, fft, dac bool, cache map[track]int) int { var ret int if slices.Contains(vals, "out") { if fft && dac { return 1 } return 0 } for _, i := range vals { hfft, hdac := fft, dac t := track{ node: i, fft: hfft, dac: hdac, } if v, ok := cache[t]; ok { ret += v continue } switch i { case "fft": hfft = true case "dac": hdac = true } t = track{ node: i, fft: hfft, dac: hdac, } cache[t] = findPaths2(m, m[i], hfft, hdac, cache) ret += cache[t] } return ret }