Solve day 7
This commit is contained in:
16
day7/example.txt
Normal file
16
day7/example.txt
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
.......S.......
|
||||||
|
...............
|
||||||
|
.......^.......
|
||||||
|
...............
|
||||||
|
......^.^......
|
||||||
|
...............
|
||||||
|
.....^.^.^.....
|
||||||
|
...............
|
||||||
|
....^.^...^....
|
||||||
|
...............
|
||||||
|
...^.^...^.^...
|
||||||
|
...............
|
||||||
|
..^...^.....^..
|
||||||
|
...............
|
||||||
|
.^.^.^.^.^...^.
|
||||||
|
...............
|
||||||
145
day7/main.go
Normal file
145
day7/main.go
Normal 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()
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user