import Foundation struct Point : Hashable { let x: Int let y: Int } func readInput(_ filePath: String) throws -> (Int, Int, [Character: [Point]]) { let content = try String(contentsOfFile: filePath, encoding: .ascii) let lines = content.split(separator: "\n").map(Array.init) let antennas = lines.enumerated().flatMap { i, line in line.enumerated().compactMap { j, cell in cell == "." ? nil : (cell, i, j) } } var map: [Character: [Point]] = [:] for (type, i, j) in antennas { let current = map[type, default: []] map[type] = current + [Point(x: i, y: j)] } return (lines.count, lines[0].count, map) } func nodes(_ antennas: [Point], h: Int, w: Int) -> Set { var nodes: Set = [] for i in 0..= 0 && next.x < h && next.y >= 0 && next.y < w { nodes.insert(next) k += 1 next = Point(x: (k+1)*a.x - k*b.x, y: (k+1)*a.y - k*b.y) } // going the other way k = -1 next = Point(x: (k+1)*a.x - k*b.x, y: (k+1)*a.y - k*b.y) while next.x >= 0 && next.x < h && next.y >= 0 && next.y < w { nodes.insert(next) k -= 1 next = Point(x: (k+1)*a.x - k*b.x, y: (k+1)*a.y - k*b.y) } } } return nodes } let (height, width, antennas) = try readInput(CommandLine.arguments[1]) let answer = antennas .map { c, points in nodes(points, h: height, w: width) } .reduce(Set([]), { acc, x in acc.union(x) }) .count print(answer)