// // File.swift // // // Created by Max Nuding on 11.12.21. // import Foundation import Runner struct Coord: Hashable { let row: Int let col: Int var left: Coord { Coord(row: row, col: col - 1) } var right: Coord { Coord(row: row, col: col + 1) } var top: Coord { Coord(row: row - 1, col: col) } var bottom: Coord { Coord(row: row + 1, col: col) } var topLeft: Coord { Coord(row: row - 1, col: col - 1) } var topRight: Coord { Coord(row: row - 1, col: col + 1) } var bottomLeft: Coord { Coord(row: row + 1, col: col - 1) } var bottomRight: Coord { Coord(row: row + 1, col: col + 1) } var neighbors: [Coord] { [topLeft, top, topRight, left, right, bottomLeft, bottom, bottomRight] .filter {coord in coord.col >= 0 && coord.col < 10 && coord.row >= 0 && coord.row < 10} } } class Day11: Runnable { let inputPath: String var octopuses = [[Int]]() var flashed = Set() let numRows = 10 let numCols = 10 var numFlashes = 0 required init(inputPath: String) { self.inputPath = inputPath } public func run() { let input = try! String(contentsOfFile: inputPath) octopuses = input .trimmingCharacters(in: .newlines) .components(separatedBy: .newlines) .map { Array($0) } .map { ar in ar.map {c in Int(c.description)!} } var step = 0 while(flashed.count < numRows * numCols) { flashed = Set() for row in octopuses.indices { for col in octopuses[row].indices { octopuses[row][col] += 1 } } for row in octopuses.indices { for col in octopuses[row].indices { let coord = Coord(row: row, col: col) checkAndFlash(at: coord) } } for flash in flashed { octopuses[flash] = 0 } step += 1 if step == 100 { print(numFlashes) } } print("All flashing at step: \(step)") } func checkAndFlash(at coord: Coord) { if octopuses[coord] <= 9 || flashed.contains(coord) { return } flashed.insert(coord) numFlashes += 1 for neighbor in coord.neighbors.filter({!flashed.contains($0)}) { octopuses[neighbor] += 1 checkAndFlash(at: neighbor) } } } extension Array where Element == Array { subscript(coord: Coord) -> Int { get { self[coord.row][coord.col] } set(newValue) { self[coord.row][coord.col] = newValue } } func fieldDescription(flashed: Set) -> String { var desc = "" for row in indices { for col in self[row].indices { let c = flashed.contains(Coord(row: row, col: col)) ? " X" : String(format: "%02d", self[row][col]) desc.append("\(c),") } desc.append("\n") } return desc } }