Compare commits

...

2 Commits

Author SHA1 Message Date
796a7a1b4f
tests 2025-12-13 22:57:12 +02:00
4b8bf419e2
day 11 2025-12-13 22:47:34 +02:00
4 changed files with 192 additions and 0 deletions

8
.gitignore vendored
View File

@ -1 +1,9 @@
/problems /problems
tmp
# Ignore these to avoid leaking local replacements to the devkit
./go.mod
./go.sum
go.mod
go.sum

56
tests/tests.go Normal file
View File

@ -0,0 +1,56 @@
package tests
import (
"fmt"
"os"
"testing"
"time"
"git.bizdoc.ro/gabi-public/Advent-of-Code.git/aoc"
)
func assert(t *testing.T, err error, a, b any) {
t.Helper()
if err != nil {
t.Error(err)
}
want := fmt.Sprintf("%v", a)
got := fmt.Sprintf("%v", b)
if got != want {
err = fmt.Errorf("want %s, got %s", want, got)
t.Error(err)
}
}
func Handler[T any](f func(ctx aoc.Context) (T, error)) func(ctx aoc.Context) (any, error) {
return func(c aoc.Context) (any, error) {
return f(c)
}
}
func Handler2[T any, K any](param T, f func(ctx aoc.Context, param T) (K, error)) func(ctx aoc.Context) (any, error) {
return func(c aoc.Context) (any, error) {
return f(c, param)
}
}
func Test(t *testing.T, file string, handler func(aoc.Context) (any, error), want any) {
t.Helper()
f, err := os.Open("tmp/" + file)
if err != nil {
panic(err)
}
defer f.Close()
start := time.Now()
got, err := handler(aoc.Context{
Body: f,
Logger: nil,
Context: nil,
})
t.Log("took", time.Since(start))
assert(t, err, want, got)
}

101
year25/day11/day.go Normal file
View File

@ -0,0 +1,101 @@
package day11
import (
"fmt"
"strings"
"git.bizdoc.ro/gabi-public/Advent-of-Code.git/aoc"
"git.bizdoc.ro/private/devkit.git/collections/dsa"
)
func parseInput(ctx aoc.Context) (map[string][]string, error) {
graph := make(map[string][]string)
s := ctx.Scanner()
for s.Scan() {
line := s.Text()
parts := strings.Split(line, ": ")
key := parts[0]
graph[key] = strings.Split(parts[1], " ")
}
if err := s.Err(); err != nil {
return nil, fmt.Errorf("scanner error: %w", err)
}
return graph, nil
}
func Part1(ctx aoc.Context) (int, error) {
graph, err := parseInput(ctx)
if err != nil {
return 0, err
}
const start = "you"
const end = "out"
stack := dsa.NewStack[string]()
stack.Push(start)
var pathsToEnd int
for !stack.IsEmpty() {
this := stack.Pop()
for _, next := range graph[this] {
stack.Push(next)
}
if this == end {
pathsToEnd += 1
}
}
return pathsToEnd, nil
}
func Part2(ctx aoc.Context) (uint64, error) {
graph, err := parseInput(ctx)
if err != nil {
return 0, err
}
type Item struct {
DAC, FFT bool
Name string
}
cache := make(map[Item]uint64)
var recursion func(current Item, end string) uint64
recursion = func(current Item, end string) uint64 {
if current.Name == end {
return bool2int(current.DAC && current.FFT)
}
switch current.Name {
case "dac":
current.DAC = true
case "fft":
current.FFT = true
}
var sum uint64
for _, next := range graph[current.Name] {
current.Name = next
paths, ok := cache[current]
if !ok {
paths = recursion(current, end)
cache[current] = paths
}
sum += paths
}
return sum
}
return recursion(Item{DAC: false, FFT: false, Name: "svr"}, "out"), nil
}
func bool2int(b bool) uint64 {
var i uint64
if b {
i = 1
} else {
i = 0
}
return i
}

27
year25/day11/day_test.go Normal file
View File

@ -0,0 +1,27 @@
package day11
import (
"testing"
"git.bizdoc.ro/gabi-public/Advent-of-Code.git/tests"
)
func TestPart1Example(t *testing.T) {
const want = 5
tests.Test(t, "example.txt", tests.Handler(Part1), want)
}
func TestPart1(t *testing.T) {
const want = 764
tests.Test(t, "input.txt", tests.Handler(Part1), want)
}
func TestPart2Example(t *testing.T) {
const want = 2
tests.Test(t, "example_part2.txt", tests.Handler(Part2), want)
}
func TestPart2(t *testing.T) {
const want = 462444153119850
tests.Test(t, "input.txt", tests.Handler(Part2), want)
}