Solve day 7

This commit is contained in:
2025-12-07 14:18:52 +02:00
parent ce1b496761
commit 8b102c2c61
2 changed files with 161 additions and 0 deletions

16
day7/example.txt Normal file
View File

@@ -0,0 +1,16 @@
.......S.......
...............
.......^.......
...............
......^.^......
...............
.....^.^.^.....
...............
....^.^...^....
...............
...^.^...^.^...
...............
..^...^.....^..
...............
.^.^.^.^.^...^.
...............

145
day7/main.go Normal file
View File

@@ -0,0 +1,145 @@
package main
import (
"bufio"
"flag"
"fmt"
"io"
"log"
"os"
"slices"
)
func main() {
debug := flag.Bool("debug", false, "Debug.")
flag.Parse()
f := os.Stdin
if flag.NArg() > 0 && flag.Arg(0) != "-" {
var err error
f, err = os.Open(flag.Arg(0))
if err != nil {
log.Fatal(err)
}
defer f.Close()
}
diagram, err := readDiagram(f)
if err != nil {
log.Fatal(err)
}
splits := diagram.Propagate()
var timelines int
for _, row := range slices.Backward(diagram) {
for _, c := range row {
if c.Marker != BeamMarker {
continue
}
timelines += c.WaysToReach
}
break
}
if *debug {
for _, row := range diagram {
for _, c := range row {
if c.Marker == BeamMarker {
if c.WaysToReach < 10 {
fmt.Print(c.WaysToReach)
} else {
b := 'A' + c.WaysToReach - 10
if b > 'Z' {
b = int(c.Marker)
}
fmt.Printf("%c", b)
}
} else {
fmt.Printf("%c", c.Marker)
}
}
fmt.Println()
}
}
fmt.Println("beam split", splits, "times into", timelines, "timelines")
}
type Marker byte
const (
BeamEmitterMarker Marker = 'S'
BeamMarker Marker = '|'
SplitterMarker Marker = '^'
EmptyMarker Marker = '.'
)
type Cell struct {
Marker Marker
WaysToReach int
}
type diagram [][]Cell
func (d diagram) Propagate() (splits int) {
splitoff := func(x, y, dx int) {
x1 := x + dx
if x1 < 0 || x1 >= len(d[y]) {
return // out of range
}
switch d[y][x1].Marker {
case EmptyMarker:
d[y][x1] = Cell{
Marker: BeamMarker,
WaysToReach: d[y-1][x].WaysToReach,
}
case BeamMarker:
d[y][x1].WaysToReach += d[y-1][x].WaysToReach
}
}
propagateCell := func(x, y int) {
switch d[y-1][x].Marker {
case BeamEmitterMarker:
d[y-1][x].WaysToReach = 1
case BeamMarker:
default:
return
}
// we have a beam above
switch d[y][x].Marker {
case EmptyMarker:
d[y][x] = Cell{
Marker: BeamMarker,
WaysToReach: d[y-1][x].WaysToReach,
}
case BeamMarker:
d[y][x].WaysToReach += d[y-1][x].WaysToReach
case SplitterMarker:
splitoff(x, y, -1)
splitoff(x, y, +1)
splits++
}
}
for y := 1; y < len(d); y++ {
for x := range d[y] {
propagateCell(x, y)
}
}
return splits
}
func readDiagram(r io.Reader) (diagram, error) {
var diagram diagram
sc := bufio.NewScanner(r)
for sc.Scan() {
cells := make([]Cell, 0, len(sc.Bytes()))
for _, b := range sc.Bytes() {
cells = append(cells, Cell{Marker: Marker(b)})
}
diagram = append(diagram, cells)
}
return diagram, sc.Err()
}