aoc2021/Sources/11/11.swift

110 lines
3.1 KiB
Swift
Raw Permalink Normal View History

2021-12-11 10:06:13 +00:00
//
// 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<Coord>()
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)!} }
2021-12-12 08:26:08 +00:00
var step = 0
while(flashed.count < numRows * numCols) {
2021-12-11 10:06:13 +00:00
flashed = Set<Coord>()
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
}
2021-12-12 08:26:08 +00:00
step += 1
if step == 100 {
print(numFlashes)
}
2021-12-11 10:06:13 +00:00
}
2021-12-12 08:26:08 +00:00
print("All flashing at step: \(step)")
2021-12-11 10:06:13 +00:00
}
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<Int> {
subscript(coord: Coord) -> Int {
get { self[coord.row][coord.col] }
set(newValue) {
self[coord.row][coord.col] = newValue
}
}
func fieldDescription(flashed: Set<Coord>) -> 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
}
}