This commit is contained in:
Gabriel Bizdoc 2025-12-08 05:16:46 +02:00
parent ab99f807e8
commit 87a9c56a77
No known key found for this signature in database
GPG Key ID: 3F0EDAECA5BE9ED9
2 changed files with 139 additions and 0 deletions

91
year25/day7.go Normal file
View File

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

48
year25/day7_pg/stack.go Normal file
View File

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