101 lines
2.0 KiB
Go
101 lines
2.0 KiB
Go
|
package day_08
|
||
|
|
||
|
import (
|
||
|
"strings"
|
||
|
)
|
||
|
|
||
|
type Point struct {
|
||
|
X, Y int
|
||
|
}
|
||
|
|
||
|
// task:https://adventofcode.com/2024/day/8
|
||
|
func SolveBasic(input string) int {
|
||
|
antennas, width, height := loadAntennas(input)
|
||
|
antinodes := map[Point]bool{}
|
||
|
|
||
|
for _, v := range antennas {
|
||
|
for i := 0; i < len(v); i++ {
|
||
|
for j := i + 1; j < len(v); j++ {
|
||
|
for _, antinode := range findAntinodes(v[i], v[j], width, height) {
|
||
|
antinodes[antinode] = true
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return len(antinodes)
|
||
|
}
|
||
|
|
||
|
// task:https://adventofcode.com/2024/day/8#part2
|
||
|
func SolveComplex(input string) int {
|
||
|
antennas, width, height := loadAntennas(input)
|
||
|
antinodes := map[Point]bool{}
|
||
|
|
||
|
for _, v := range antennas {
|
||
|
for i := 0; i < len(v); i++ {
|
||
|
for j := i + 1; j < len(v); j++ {
|
||
|
for _, antinode := range findAllAntinodes(v[i], v[j], width, height) {
|
||
|
antinodes[antinode] = true
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return len(antinodes)
|
||
|
}
|
||
|
|
||
|
func findAntinodes(A Point, B Point, width int, height int) []Point {
|
||
|
dx := B.X - A.X
|
||
|
dy := B.Y - A.Y
|
||
|
|
||
|
points := []Point{}
|
||
|
p := Point{
|
||
|
X: A.X - dx,
|
||
|
Y: A.Y - dy,
|
||
|
}
|
||
|
if inGrid(p, width, height) {
|
||
|
points = append(points, p)
|
||
|
}
|
||
|
p = Point{
|
||
|
X: B.X + dx,
|
||
|
Y: B.Y + dy,
|
||
|
}
|
||
|
if inGrid(p, width, height) {
|
||
|
points = append(points, p)
|
||
|
}
|
||
|
return points
|
||
|
}
|
||
|
|
||
|
func findAllAntinodes(A Point, B Point, width int, height int) []Point {
|
||
|
dx := B.X - A.X
|
||
|
dy := B.Y - A.Y
|
||
|
|
||
|
points := []Point{}
|
||
|
for inGrid(A, width, height) {
|
||
|
points = append(points, Point{A.X, A.Y})
|
||
|
A.X -= dx
|
||
|
A.Y -= dy
|
||
|
}
|
||
|
for inGrid(B, width, height) {
|
||
|
points = append(points, Point{B.X, B.Y})
|
||
|
B.X += dx
|
||
|
B.Y += dy
|
||
|
}
|
||
|
return points
|
||
|
}
|
||
|
|
||
|
func inGrid(p Point, width, height int) bool {
|
||
|
return p.X >= 0 && p.X < width && p.Y >= 0 && p.Y < height
|
||
|
}
|
||
|
|
||
|
func loadAntennas(input string) (map[rune][]Point, int, int) {
|
||
|
results := map[rune][]Point{}
|
||
|
substrings := strings.Split(input, "\n")
|
||
|
for y, line := range substrings {
|
||
|
for x, char := range line {
|
||
|
if char != '.' {
|
||
|
results[char] = append(results[char], Point{x, y})
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return results, len(substrings[0]), len(substrings)
|
||
|
}
|