106 lines
2.9 KiB
Swift
106 lines
2.9 KiB
Swift
//
|
|
// 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)!} }
|
|
|
|
for _ in 0..<100 {
|
|
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
|
|
}
|
|
}
|
|
print(numFlashes)
|
|
}
|
|
|
|
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
|
|
}
|
|
}
|