From 8b102c2c61dc611b76d0376a1666227d56cc550c Mon Sep 17 00:00:00 2001 From: Mindaugas Bernotas Date: Sun, 7 Dec 2025 14:18:52 +0200 Subject: [PATCH] Solve day 7 --- day7/example.txt | 16 ++++++ day7/main.go | 145 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 161 insertions(+) create mode 100644 day7/example.txt create mode 100644 day7/main.go diff --git a/day7/example.txt b/day7/example.txt new file mode 100644 index 0000000..57a2466 --- /dev/null +++ b/day7/example.txt @@ -0,0 +1,16 @@ +.......S....... +............... +.......^....... +............... +......^.^...... +............... +.....^.^.^..... +............... +....^.^...^.... +............... +...^.^...^.^... +............... +..^...^.....^.. +............... +.^.^.^.^.^...^. +............... diff --git a/day7/main.go b/day7/main.go new file mode 100644 index 0000000..6204abf --- /dev/null +++ b/day7/main.go @@ -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() +}