102 lines
1.6 KiB
Go
102 lines
1.6 KiB
Go
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
|
|
}
|