|
| 1 | +import Algorithms |
| 2 | + |
| 3 | +struct Day08: AdventDay { |
| 4 | + var antennaLocations: [Character: [Coord]] = [Character: [Coord]]() |
| 5 | + var width: Int |
| 6 | + var height: Int |
| 7 | + |
| 8 | + init(data: String) { |
| 9 | + let lines = data.lines() |
| 10 | + height = lines.count |
| 11 | + width = lines[0].count |
| 12 | + for (colIdx, line) in lines.enumerated() { |
| 13 | + for (rowIdx, char) in line.enumerated() { |
| 14 | + if char != "." { |
| 15 | + let currentPos = Coord(x: rowIdx, y: colIdx) |
| 16 | + antennaLocations[char, default: [Coord]()].append(currentPos) |
| 17 | + } |
| 18 | + } |
| 19 | + } |
| 20 | + } |
| 21 | + |
| 22 | + func isInside(_ node: Coord) -> Bool { |
| 23 | + node.x >= 0 && node.x <= self.width - 1 && node.y >= 0 && node.y <= self.height - 1 |
| 24 | + } |
| 25 | + |
| 26 | + func part1() -> Int { |
| 27 | + var antiNodes: Set<Coord> = Set() |
| 28 | + for (key, values) in antennaLocations { |
| 29 | + for pair in values.combinations(ofCount: 2) { |
| 30 | + let offset = pair[1] - pair[0] |
| 31 | + [ |
| 32 | + pair[0] - offset, |
| 33 | + pair[1] + offset, |
| 34 | + ].filter { isInside($0) }.forEach { |
| 35 | + antiNodes.insert($0) |
| 36 | + } |
| 37 | + } |
| 38 | + } |
| 39 | + return antiNodes.count |
| 40 | + } |
| 41 | + |
| 42 | + func walkAntiNodes(antenna: Coord, offset: Coord) -> [Coord] { |
| 43 | + var allAntiNode = [Coord]() |
| 44 | + var nodePos = antenna |
| 45 | + repeat { |
| 46 | + allAntiNode.append(nodePos) |
| 47 | + nodePos += offset |
| 48 | + } while isInside(nodePos) |
| 49 | + return allAntiNode |
| 50 | + } |
| 51 | + |
| 52 | + func part2() -> Int { |
| 53 | + var antiNodes: Set<Coord> = Set() |
| 54 | + for (key, values) in antennaLocations { |
| 55 | + for pair in values.combinations(ofCount: 2) { |
| 56 | + let offset = pair[1] - pair[0] |
| 57 | + var localNodes = walkAntiNodes(antenna: pair[0], offset: offset * -1) |
| 58 | + localNodes.append(contentsOf: walkAntiNodes(antenna: pair[1], offset: offset)) |
| 59 | + localNodes.forEach { |
| 60 | + antiNodes.insert($0) |
| 61 | + } |
| 62 | + } |
| 63 | + } |
| 64 | + return antiNodes.count |
| 65 | + } |
| 66 | +} |
0 commit comments