From 87a9c56a774796e6c37cc6fec450d9b76dcbb197 Mon Sep 17 00:00:00 2001 From: Gabriel Bizdoc Date: Mon, 8 Dec 2025 05:16:46 +0200 Subject: [PATCH] day 7 --- year25/day7.go | 91 +++++++++++++++++++++++++++++++++++++++++ year25/day7_pg/stack.go | 48 ++++++++++++++++++++++ 2 files changed, 139 insertions(+) create mode 100644 year25/day7.go create mode 100644 year25/day7_pg/stack.go diff --git a/year25/day7.go b/year25/day7.go new file mode 100644 index 0000000..f7a74b0 --- /dev/null +++ b/year25/day7.go @@ -0,0 +1,91 @@ +package year25 + +import ( + "fmt" + + "git.bizdoc.ro/gabi-public/Advent-of-Code.git/aocutils" + "git.bizdoc.ro/gabi-public/Advent-of-Code.git/year25/day7_pg" + "git.bizdoc.ro/private/devkit.git/collections/geometry/v2" +) + +func day7ParseInput(c aocutils.Context) (g geometry.Grid[byte], start geometry.Point, _ error) { + g, err := geometry.ReaderToByteGrid(c.Body) + if err != nil { + return g, start, fmt.Errorf("day7: failed to read input %w", err) + } + + findStart := g.Find(func(b byte) bool { + return b == byte('S') + }) + + for start = range findStart { + return g, start, nil + } + + return g, start, fmt.Errorf("day7: failed to find start point") +} + +func Day7Part1(c aocutils.Context) (int, error) { + g, start, err := day7ParseInput(c) + if err != nil { + return 0, fmt.Errorf("day7: failed to parse input %w", err) + } + + var fill func(g geometry.Grid[byte], start geometry.Point) int + fill = func(g geometry.Grid[byte], start geometry.Point) int { + if g.ContainsPoint(start) { + switch g.At(start) { + case 'S': + return fill(g, start.MoveDown()) + case '.': + g.Set(start, '|') + return fill(g, start.MoveDown()) + case '^': + return 1 + fill(g, start.MoveLeft()) + fill(g, start.MoveRight()) + } + } + return 0 + } + return fill(g, start), nil +} + +func Day7Part2(c aocutils.Context) (int, error) { + g, start, err := day7ParseInput(c) + if err != nil { + return 0, fmt.Errorf("day7: failed to parse input %w", err) + } + + h := geometry.NewGrid[int](g.Rows(), g.Cols()) + + var fill func(g geometry.Grid[byte], h geometry.Grid[int], start geometry.Point) int + fill = func(g geometry.Grid[byte], cache geometry.Grid[int], start geometry.Point) int { + if g.ContainsPoint(start) { + switch g.At(start) { + case 'S': + return 1 + fill(g, cache, start.MoveDown()) + case '.': + g.Set(start, '|') + v := fill(g, cache, start.MoveDown()) + cache.Set(start, v) + return v + case '|': + return cache.At(start) // cached value + case '^': + return 1 + fill(g, cache, start.MoveLeft()) + fill(g, cache, start.MoveRight()) + } + } + return 0 + } + return fill(g, h, start), nil +} + +func Day7Part1Render(c aocutils.Context) (int, error) { + g, start, err := day7ParseInput(c) + if err != nil { + return 0, fmt.Errorf("day7: failed to parse input %w", err) + } + var ev day7_pg.Day7Part1RenderEvent + for ev = range day7_pg.Day7ProgressFillPart1(g, start) { + } + return int(ev.TotalProcessed), nil +} diff --git a/year25/day7_pg/stack.go b/year25/day7_pg/stack.go new file mode 100644 index 0000000..bf11dc2 --- /dev/null +++ b/year25/day7_pg/stack.go @@ -0,0 +1,48 @@ +package day7_pg + +import ( + "iter" + + "git.bizdoc.ro/private/devkit.git/collections/dsa" + "git.bizdoc.ro/private/devkit.git/collections/geometry/v2" +) + +type Day7Part1RenderEvent struct { + Point geometry.Point + Grid geometry.Grid[byte] + TotalProcessed int64 + Step int +} + +func Day7ProgressFillPart1(g geometry.Grid[byte], start geometry.Point) iter.Seq[Day7Part1RenderEvent] { + return func(yield func(Day7Part1RenderEvent) bool) { + stack := dsa.NewStack[geometry.Point]() + stack.Push(start) + + ev := Day7Part1RenderEvent{ + Point: start, + Grid: g, + TotalProcessed: 0, + } + for !stack.IsEmpty() { + start := stack.Pop() + if g.ContainsPoint(start) { + switch g.At(start) { + case 'S': + stack.Push(start.MoveDown()) + case '.': + g.Set(start, '|') + stack.Push(start.MoveDown()) + case '^': + stack.Push(start.MoveRight()) + stack.Push(start.MoveLeft()) + ev.TotalProcessed += 1 + } + } + ev.Step += 1 + if !yield(ev) { + return + } + } + } +}