Files
advent-of-code-2024/day8/antinode.go
2024-12-08 14:54:38 +01:00

110 lines
2.4 KiB
Go

package main
import (
"os"
"fmt"
"strings"
)
// data types
type Point struct {
x int16
y int16
}
type Antenna struct {
point Point
freq byte
}
// general util
func check(e error) {
if e != nil { panic(e) }
}
func (p Point) Mul(scalar int) Point {
return Point { x: p.x * int16(scalar), y: p.y * int16(scalar) }
}
func (p Point) Add(other Point) Point {
return Point { x: p.x + other.x, y: p.y + other.y }
}
func (p Point) Sub(other Point) Point {
return Point { x: p.x - other.x, y: p.y - other.y }
}
func contains(arr []Point, p Point) bool {
for _, elem := range arr {
if elem == p { return true }
}
return false
}
func addNonDuplicate(arr []Point, p Point) []Point {
if contains(arr, p) { return arr
} else { return append(arr, p) }
}
func newAntennas(data string) []Antenna {
/* Reads the puzzle input, return a list of antenna structs.
*/
antennas := make([]Antenna, 0, 100)
for y, line := range strings.Split(data, "\n") {
for x, char := range []byte(line) {
if char != '.' {
antennas = append(antennas, Antenna{ point: Point{x: int16(x), y: int16(y)}, freq: char })
}
}
}
return antennas
}
func antinodes(points [2]Point) [2]Point {
var nodes [2]Point
distance := points[0].Sub(points[1])
nodes[0] = points[0].Add(distance)
nodes[1] = points[1].Sub(distance)
return nodes
}
// main loop
func main() {
// read in file
dat, err := os.ReadFile("data.txt")
check(err)
dat_str := strings.TrimSpace(string(dat))
lines := strings.Split(dat_str, "\n")
height, width := int16(len(lines)), int16(len(lines[0]))
antennas := newAntennas(dat_str)
pairs := make([][2]Point, 0)
for _, ant1 := range antennas {
for _, ant2 := range antennas {
if ant1.freq == ant2.freq && ant1.point != ant2.point {
pairs = append(pairs, [2]Point{ant1.point, ant2.point})
}
}
}
nodes := make([]Point, 0, len(pairs) * 2)
for _, pair := range pairs {
ns := antinodes(pair)
if ns[0].x >= 0 && ns[0].x < width && ns[0].y >= 0 && ns[0].y < height {
nodes = addNonDuplicate(nodes, ns[0])
}
if ns[1].x >= 0 && ns[1].x < width && ns[1].y >= 0 && ns[1].y < height {
nodes = addNonDuplicate(nodes, ns[1])
}
}
fmt.Println(len(nodes))
}