Files
aoc24/day08/d08p2.swift
2024-12-13 15:04:22 -08:00

56 lines
1.8 KiB
Swift

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<Point> {
var nodes: Set<Point> = []
for i in 0..<antennas.count {
for j in i+1..<antennas.count {
let (a, b) = (antennas[i], antennas[j])
// (k+1)a - kb going one way
var k = 0
var 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)
}
// 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)