This commit is contained in:
Max Nuding 2021-12-09 19:51:45 +01:00
parent 1ff50f072e
commit 3dd2188f11
Signed by: phlaym
GPG Key ID: A06651BAB6777237
2 changed files with 51 additions and 12 deletions

View File

@ -9,7 +9,7 @@ import Foundation
import Runner import Runner
import Collections import Collections
struct Coord { struct Coord: Hashable {
let row: Int let row: Int
let col: Int let col: Int
@ -33,6 +33,7 @@ struct Coord {
} }
struct Field:Sequence, IteratorProtocol { struct Field:Sequence, IteratorProtocol {
typealias Element = Coord
let numbers: [[Int]] let numbers: [[Int]]
let numCols: Int let numCols: Int
let numRows: Int let numRows: Int
@ -41,7 +42,7 @@ struct Field:Sequence, IteratorProtocol {
init(numbers: [[Int]]) { init(numbers: [[Int]]) {
self.numbers = numbers self.numbers = numbers
numCols = numbers.first!.count numCols = numbers.first?.count ?? 0
numRows = numbers.count numRows = numbers.count
} }
@ -51,13 +52,11 @@ struct Field:Sequence, IteratorProtocol {
.filter { $0.row < numRows && $0.col < numCols } .filter { $0.row < numRows && $0.col < numCols }
} }
func lowPointValueAt(coord: Coord) -> Int? { func isLowPointAt(coord: Coord) -> Bool {
let value = numbers[coord.row][coord.col] let value = self[coord]
return getNeighborsCoordsFor(coord: coord) return getNeighborsCoordsFor(coord: coord)
.map { numbers[$0.row][$0.col] } .map { numbers[$0.row][$0.col] }
.allSatisfy { $0 > value } .allSatisfy { $0 > value }
? value
: nil
} }
private func getNextCoord() -> Coord? { private func getNextCoord() -> Coord? {
@ -79,19 +78,59 @@ struct Field:Sequence, IteratorProtocol {
} }
return current return current
} }
subscript(index: Coord) -> Int {
get {
numbers[index.row][index.col]
}/*
set(newValue) {
// Perform a suitable setting action here.
}*/
}
} }
struct Day09: Runnable { class Day09: Runnable {
let inputPath: String let inputPath: String
var lowestNeighbors = [Coord: Coord]()
var lowPoints = Set<Coord>()
var field = Field(numbers: [[Int]]())
func run() { required init(inputPath: String) {
self.inputPath = inputPath
}
public func run() {
let input = try! String(contentsOfFile: inputPath) let input = try! String(contentsOfFile: inputPath)
let entries = input let entries = input
.trimmingCharacters(in: .newlines) .trimmingCharacters(in: .newlines)
.components(separatedBy: .newlines) .components(separatedBy: .newlines)
.map { line in line.map { $0.wholeNumberValue! } } .map { line in line.map { $0.wholeNumberValue! } }
let field = Field(numbers: entries) field = Field(numbers: entries)
let sum = field.compactMap { field.lowPointValueAt(coord: $0) }.reduce(0, { $0 + $1 + 1 }) lowPoints = Set(field.filter { field.isLowPointAt(coord: $0) })
//Part 1
let sum = lowPoints.map { field[$0] }.reduce(0, +) + lowPoints.count
print(sum) print(sum)
// Part 2:
var basinSize = [Coord: Int]()
for coord in field {
guard field[coord] != 9 else {
continue
}
let bl = basinLocation(for: coord)
basinSize[bl, default: 0] += 1
}
let result = basinSize.values.sorted(by: >)[0..<3].reduce(1, *)
print(result)
}
private func basinLocation(for coord: Coord) -> Coord {
guard !lowPoints.contains(coord) else {
return coord
}
let closestNeighbor = lowestNeighbors[coord] ?? field.getNeighborsCoordsFor(coord: coord).min(by: { field[$0] < field[$1] })!
lowestNeighbors[coord] = closestNeighbor
return basinLocation(for: closestNeighbor)
} }
} }

View File

@ -8,5 +8,5 @@
import Foundation import Foundation
import Runner import Runner
Runner(target: Day09.self, day: "09", isTest: true).run() //Runner(target: Day09.self, day: "09", isTest: true).run()
//Runner(target: Day09.self, day: "09", isTest: false).run() Runner(target: Day09.self, day: "09", isTest: false).run()