feat: completed day 11 for advent of code

This commit is contained in:
Ceferino Patino 2025-12-21 18:09:34 -06:00
commit 9cf9674e7f
Signed by: c4patino
SSH key fingerprint: SHA256:9fQ9TsujGrdNNi76mnsu63v7dS5JOmHRZEqBOl49OR8
5 changed files with 179 additions and 0 deletions

View file

@ -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{

119
2025/day11/day11.go Executable file
View file

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

35
2025/day11/day11_test.go Executable file
View file

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

10
2025/day11/test.txt Executable file
View file

@ -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

13
2025/day11/test2.txt Normal file
View file

@ -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