aoc2024/day-08/internal/two/solve.go

66 lines
1.3 KiB
Go
Raw Normal View History

2024-12-08 19:55:23 +00:00
package two
import (
"bytes"
"math"
"sync"
log "github.com/sirupsen/logrus"
)
func Solve(buf []byte) (int, error) {
r := bytes.NewReader(buf)
graph, err := parseLines(r)
if err != nil {
return 0, err
}
var wg sync.WaitGroup
wg.Add(len(graph.antennae))
for i, a := range graph.antennae {
go func() {
defer wg.Done()
for j, b := range graph.antennae {
if i == j || a.identifier != b.identifier {
continue
}
2025-01-07 17:24:01 +00:00
for _, coords := range calcAntiNodePos(a.coords, b.coords, []coords{a.coords, b.coords}, graph) {
2024-12-08 21:46:44 +00:00
if !graph.antinodes.contains(coords) {
2024-12-08 19:55:23 +00:00
graph.antinodes.insert(coords)
}
}
}
}()
}
wg.Wait()
log.Debugf("\n%s\n", graph.debug())
return graph.antinodes.len(), nil
}
2025-01-07 17:24:01 +00:00
func calcAntiNodePos(a, b coords, all []coords, g *graph) []coords {
2024-12-08 19:55:23 +00:00
xdiff := int(math.Abs(float64(a.x - b.x)))
ydiff := int(math.Abs(float64(a.y - b.y)))
var next coords
if a.x < b.x && a.y < b.y {
next = newCoords(b.x+xdiff, b.y+ydiff)
} else if a.x < b.x && a.y > b.y {
next = newCoords(b.x+xdiff, b.y-ydiff)
} else if a.x > b.x && a.y < b.y {
next = newCoords(b.x-xdiff, b.y+ydiff)
} else {
next = newCoords(b.x-xdiff, b.y-ydiff)
}
2025-01-07 17:24:01 +00:00
if g.isOutOfBounds(next) {
2024-12-08 19:55:23 +00:00
return all
}
2025-01-07 17:24:01 +00:00
return calcAntiNodePos(b, next, append(all, next), g)
2024-12-08 19:55:23 +00:00
}