Go
Oh my scheduling God! Part 1 was easy. Then for part 2 I started tracing each particle one by one using goroutines, but spawning billions of goroutines seemed to make my poor laptop sad. So I implemented a whole thread pool with process management and stuff, but nothing worked. So at the end I started doing the unthinkable: using my brain.
It seems we can just reuse the same idea as part 1 one but with a clever counting scheme. Thing works and is as fast as part 1. I'm both happy and deeply sad not to have been able to leverage Go's supposed killer features - which are actually rarely useful when programming things other than servers tbh.
Here we goooooo:
day07.go
package main
import (
"aoc/utils"
)
func parseStartLine(line string) []bool {
runes := []rune(line)
beams := make([]bool, len(runes))
for idx, char := range runes {
if char == 'S' {
beams[idx] = true
}
}
return beams
}
func stepOne(input chan string) (int, error) {
beams := parseStartLine(<-input)
splitCount := 0
for line := range input {
runes := []rune(line)
for idx, char := range runes {
if char == '^' && beams[idx] {
splitCount++
if idx > 0 {
beams[idx-1] = true
}
if idx < len(runes)-1 {
beams[idx+1] = true
}
beams[idx] = false
}
}
}
return splitCount, nil
}
func valueBeams(beams []bool) []int {
valBeams := make([]int, len(beams))
for idx, b := range beams {
val := 0
if b {
val = 1
}
valBeams[idx] = val
}
return valBeams
}
func stepTwo(input chan string) (int, error) {
beams := valueBeams(parseStartLine(<-input))
for line := range input {
runes := []rune(line)
for idx, char := range runes {
bc := beams[idx]
if char == '^' && bc > 0 {
beams[idx] = 0
if idx > 0 {
beams[idx-1] += bc
}
if idx < len(runes)-1 {
beams[idx+1] += bc
}
}
}
}
sum := 0
for _, bc := range beams {
sum += bc
}
return sum, nil
}
func main() {
inputFile := utils.FilePath("day07.txt")
utils.RunStep(utils.ONE, inputFile, stepOne)
utils.RunStep(utils.TWO, inputFile, stepTwo)
}