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)) }