From 9cf9674e7fd200dda37b5bcdc7e682f70aba335d Mon Sep 17 00:00:00 2001 From: C4 Patino Date: Sun, 21 Dec 2025 18:09:34 -0600 Subject: [PATCH] feat: completed day 11 for advent of code --- 2025/cmd/root.go | 2 + 2025/day11/day11.go | 119 +++++++++++++++++++++++++++++++++++++++ 2025/day11/day11_test.go | 35 ++++++++++++ 2025/day11/test.txt | 10 ++++ 2025/day11/test2.txt | 13 +++++ 5 files changed, 179 insertions(+) create mode 100755 2025/day11/day11.go create mode 100755 2025/day11/day11_test.go create mode 100755 2025/day11/test.txt create mode 100644 2025/day11/test2.txt diff --git a/2025/cmd/root.go b/2025/cmd/root.go index 00b09c7..8f1156e 100644 --- a/2025/cmd/root.go +++ b/2025/cmd/root.go @@ -19,6 +19,7 @@ import ( "cpatino.com/advent-of-code/2025/day08" "cpatino.com/advent-of-code/2025/day09" "cpatino.com/advent-of-code/2025/day10" + "cpatino.com/advent-of-code/2025/day11" ) var days = map[int]func(string) (any, any){ @@ -32,6 +33,7 @@ var days = map[int]func(string) (any, any){ 8: day08.Run, 9: day09.Run, 10: day10.Run, + 11: day11.Run, } var rootCmd = &cobra.Command{ diff --git a/2025/day11/day11.go b/2025/day11/day11.go new file mode 100755 index 0000000..8f30f8a --- /dev/null +++ b/2025/day11/day11.go @@ -0,0 +1,119 @@ +package day11 + +import ( + "bufio" + "os" + "strings" +) + +type Key struct { + node string + mask uint8 +} + +func countPaths(graph map[string][]string, start, target string) int { + memo := make(map[string]int) + visiting := make(map[string]bool) + var dfs func(string) int + dfs = func(u string) int { + if u == target { + return 1 + } + if visiting[u] { + return 0 + } + if v, ok := memo[u]; ok { + return v + } + visiting[u] = true + total := 0 + for _, v := range graph[u] { + total += dfs(v) + } + visiting[u] = false + memo[u] = total + return total + } + return dfs(start) +} + +func Part1(graph map[string][]string) int { + return countPaths(graph, "you", "out") +} + +func Part2(graph map[string][]string) int { + start, target := "svr", "out" + const need1, need2 = "dac", "fft" + + memo := make(map[Key]int) + visiting := make(map[string]bool) + var dfs func(string, uint8) int + dfs = func(u string, mask uint8) int { + if u == need1 { + mask |= 0b01 + } + if u == need2 { + mask |= 0b10 + } + + if u == target { + if mask == 0b11 { + return 1 + } + return 0 + } + + if visiting[u] { + return 0 + } + + k := Key{u, mask} + if v, ok := memo[k]; ok { + return v + } + + visiting[u] = true + total := 0 + for _, v := range graph[u] { + total += dfs(v, mask) + } + + visiting[u] = false + memo[k] = total + return total + } + return dfs(start, 0) +} + +func Run(filename string) (any, any) { + file, err := os.Open(filename) + if err != nil { + panic(err) + } + defer file.Close() + + graph := make(map[string][]string) + scanner := bufio.NewScanner(file) + for scanner.Scan() { + line := strings.TrimSpace(scanner.Text()) + if line == "" { + continue + } + parts := strings.Split(line, ":") + if len(parts) != 2 { + continue + } + src := strings.TrimSpace(parts[0]) + outs := strings.Fields(strings.TrimSpace(parts[1])) + graph[src] = outs + } + + if err := scanner.Err(); err != nil { + panic(err) + } + + part1 := Part1(graph) + part2 := Part2(graph) + + return part1, part2 +} diff --git a/2025/day11/day11_test.go b/2025/day11/day11_test.go new file mode 100755 index 0000000..1adabaf --- /dev/null +++ b/2025/day11/day11_test.go @@ -0,0 +1,35 @@ +package day11 + +import ( + "os" + "testing" +) + +type TestCase struct { + FileName string + Part1 any + Part2 any +} + +func TestDay11(t *testing.T) { + tests := []TestCase{ + {"test.txt", 5, nil}, + {"test2.txt", nil, 2}, + {"input.txt", 634, 377452269415704}, + } + + for _, test := range tests { + if _, err := os.Stat(test.FileName); os.IsNotExist(err) { + t.Fatalf("test file does not exist: %v", test.FileName) + } + + part1, part2 := Run(test.FileName) + if test.Part1 != nil && part1 != test.Part1 { + t.Fatalf("%s: unexpected part1:\nwant:\t%v\ngot:\t%v", test.FileName, test.Part1, part1) + } + + if test.Part2 != nil && part2 != test.Part2 { + t.Fatalf("%s: unexpected part2:\nwant:\t%v\ngot:\t%v", test.FileName, test.Part2, part2) + } + } +} diff --git a/2025/day11/test.txt b/2025/day11/test.txt new file mode 100755 index 0000000..01e5b43 --- /dev/null +++ b/2025/day11/test.txt @@ -0,0 +1,10 @@ +aaa: you hhh +you: bbb ccc +bbb: ddd eee +ccc: ddd eee fff +ddd: ggg +eee: out +fff: out +ggg: out +hhh: ccc fff iii +iii: out diff --git a/2025/day11/test2.txt b/2025/day11/test2.txt new file mode 100644 index 0000000..d787665 --- /dev/null +++ b/2025/day11/test2.txt @@ -0,0 +1,13 @@ +svr: aaa bbb +aaa: fft +fft: ccc +bbb: tty +tty: ccc +ccc: ddd eee +ddd: hub +hub: fff +eee: dac +dac: fff +fff: ggg hhh +ggg: out +hhh: out