2025 Day 7 Complete!
This commit is contained in:
138
2025/day07/main.go
Normal file
138
2025/day07/main.go
Normal file
@@ -0,0 +1,138 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
h "git.bullercodeworks.com/brian/adventofcode/helpers"
|
||||
)
|
||||
|
||||
func main() {
|
||||
inp := h.StdinToStringSlice()
|
||||
part1(inp)
|
||||
fmt.Println()
|
||||
part2(inp)
|
||||
}
|
||||
|
||||
func part1(inp []string) {
|
||||
var ret int
|
||||
m := h.StringSliceToCoordByteMap(inp)
|
||||
ok := true
|
||||
for ok {
|
||||
var splits int
|
||||
splits, ok = progBeams(&m)
|
||||
ret += splits
|
||||
}
|
||||
fmt.Println("# Part 1")
|
||||
fmt.Println(ret)
|
||||
}
|
||||
|
||||
func progBeams(m *h.CoordByteMap) (int, bool) {
|
||||
var splits int
|
||||
beam, err := m.FindLast('|')
|
||||
if err != nil {
|
||||
beam, _ = m.FindFirst('S')
|
||||
}
|
||||
if beam.Y == m.BRY {
|
||||
return 0, false
|
||||
}
|
||||
beams := m.FindAllOnRow(beam.Y, '|')
|
||||
if len(beams) == 0 {
|
||||
beams = append(beams, beam)
|
||||
}
|
||||
|
||||
for i := range beams {
|
||||
nxt := m.Get(beams[i].South())
|
||||
switch nxt {
|
||||
case '.':
|
||||
m.Put(beams[i].South(), '|')
|
||||
case '^':
|
||||
splits++
|
||||
m.Put(beams[i].South().East(), '|')
|
||||
m.Put(beams[i].South().West(), '|')
|
||||
}
|
||||
}
|
||||
return splits, true
|
||||
}
|
||||
|
||||
func part2(inp []string) {
|
||||
m := h.StringSliceToCoordByteMap(inp)
|
||||
fmt.Println("# Part 2")
|
||||
fmt.Println(quantumRevKickoff(&m))
|
||||
}
|
||||
|
||||
// quantumRevKickoff starts checks for each potential beam output
|
||||
func quantumRevKickoff(m *h.CoordByteMap) int {
|
||||
var ret int
|
||||
var wg sync.WaitGroup
|
||||
status := make([]byte, m.BRX)
|
||||
for i := range status {
|
||||
status[i] = '.'
|
||||
}
|
||||
track := &WorldTracker{
|
||||
t: make(map[h.Coordinate]int),
|
||||
}
|
||||
for x := m.TLX; x < m.BRX; x++ {
|
||||
c := h.Coordinate{X: x, Y: m.BRY}
|
||||
wg.Go(func() {
|
||||
if r, v := quantumRevCalc(m, c, track); v {
|
||||
ret += r
|
||||
status[c.X] = 'O'
|
||||
} else {
|
||||
status[c.X] = 'X'
|
||||
}
|
||||
})
|
||||
}
|
||||
wg.Wait()
|
||||
return ret + 1
|
||||
}
|
||||
|
||||
type WorldTracker struct {
|
||||
t map[h.Coordinate]int
|
||||
lock sync.Mutex
|
||||
}
|
||||
|
||||
func (t *WorldTracker) Get(k h.Coordinate) (int, bool) {
|
||||
t.lock.Lock()
|
||||
defer t.lock.Unlock()
|
||||
v, ok := t.t[k]
|
||||
return v, ok
|
||||
}
|
||||
func (t *WorldTracker) Set(k h.Coordinate, v int) {
|
||||
t.lock.Lock()
|
||||
defer t.lock.Unlock()
|
||||
t.t[k] = v
|
||||
}
|
||||
|
||||
// quantumRevCalc calculates how many worlds would provide a beam at
|
||||
// the given coordinate
|
||||
func quantumRevCalc(m *h.CoordByteMap, c h.Coordinate, track *WorldTracker) (int, bool) {
|
||||
if v, ok := track.Get(c); ok {
|
||||
return v, ok
|
||||
}
|
||||
var ret int
|
||||
var valid bool
|
||||
if m.Get(c.East()) == '^' {
|
||||
if r, v := quantumRevCalc(m, c.East(), track); v {
|
||||
ret += r
|
||||
valid = true
|
||||
}
|
||||
}
|
||||
if m.Get(c.West()) == '^' {
|
||||
if r, v := quantumRevCalc(m, c.West(), track); v {
|
||||
ret += r
|
||||
valid = true
|
||||
}
|
||||
}
|
||||
if m.Get(c.North()) == '.' {
|
||||
if r, v := quantumRevCalc(m, c.North(), track); v {
|
||||
ret += r
|
||||
valid = true
|
||||
}
|
||||
}
|
||||
track.Set(c, ret)
|
||||
if m.Get(c.North()) == 'S' {
|
||||
return 1, true
|
||||
}
|
||||
return ret, valid
|
||||
}
|
||||
Reference in New Issue
Block a user