Compare commits
No commits in common. "796a7a1b4f090ab5c1496c9774120d9765b99ea9" and "70ced1f6a31353df83d162ae174713b5d37a5669" have entirely different histories.
796a7a1b4f
...
70ced1f6a3
8
.gitignore
vendored
8
.gitignore
vendored
@ -1,9 +1 @@
|
|||||||
/problems
|
/problems
|
||||||
tmp
|
|
||||||
|
|
||||||
# Ignore these to avoid leaking local replacements to the devkit
|
|
||||||
./go.mod
|
|
||||||
./go.sum
|
|
||||||
|
|
||||||
go.mod
|
|
||||||
go.sum
|
|
||||||
@ -1,56 +0,0 @@
|
|||||||
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)
|
|
||||||
}
|
|
||||||
@ -1,101 +0,0 @@
|
|||||||
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
|
|
||||||
}
|
|
||||||
@ -1,27 +0,0 @@
|
|||||||
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)
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue
Block a user