2021-12-09 06:35:17 +00:00
|
|
|
//
|
|
|
|
// File.swift
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// Created by Max Nuding on 05.12.21.
|
|
|
|
//
|
|
|
|
|
|
|
|
import Foundation
|
|
|
|
import Runner
|
|
|
|
import Collections
|
|
|
|
|
|
|
|
struct Coord {
|
|
|
|
let row: Int
|
|
|
|
let col: Int
|
|
|
|
|
|
|
|
func getLeft() -> Coord? {
|
|
|
|
guard col > 0 else {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
return Coord(row: row, col: col - 1)
|
|
|
|
}
|
|
|
|
|
|
|
|
func getRight() -> Coord { Coord(row: row, col: col + 1) }
|
|
|
|
|
|
|
|
func getAbove() -> Coord? {
|
|
|
|
guard row > 0 else {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
return Coord(row: row - 1, col: col)
|
|
|
|
}
|
|
|
|
|
|
|
|
func getBelow() -> Coord { Coord(row: row + 1, col: col) }
|
|
|
|
}
|
|
|
|
|
2021-12-09 06:48:45 +00:00
|
|
|
struct Field:Sequence, IteratorProtocol {
|
2021-12-09 06:35:17 +00:00
|
|
|
let numbers: [[Int]]
|
|
|
|
let numCols: Int
|
|
|
|
let numRows: Int
|
|
|
|
|
2021-12-09 06:48:45 +00:00
|
|
|
var current: Coord? = Coord(row: 0, col: 0)
|
|
|
|
|
2021-12-09 06:35:17 +00:00
|
|
|
init(numbers: [[Int]]) {
|
|
|
|
self.numbers = numbers
|
|
|
|
numCols = numbers.first!.count
|
|
|
|
numRows = numbers.count
|
|
|
|
}
|
|
|
|
|
|
|
|
func getNeighborsCoordsFor(coord: Coord) -> [Coord] {
|
|
|
|
return [coord.getAbove(), coord.getRight(), coord.getBelow(), coord.getLeft()]
|
|
|
|
.compactMap { $0 }
|
|
|
|
.filter { $0.row < numRows && $0.col < numCols }
|
|
|
|
}
|
|
|
|
|
|
|
|
func lowPointValueAt(coord: Coord) -> Int? {
|
|
|
|
let value = numbers[coord.row][coord.col]
|
|
|
|
return getNeighborsCoordsFor(coord: coord)
|
|
|
|
.map { numbers[$0.row][$0.col] }
|
|
|
|
.allSatisfy { $0 > value }
|
|
|
|
? value
|
|
|
|
: nil
|
|
|
|
}
|
2021-12-09 06:48:45 +00:00
|
|
|
|
|
|
|
private func getNextCoord() -> Coord? {
|
|
|
|
guard let current = current else {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
if current.col == numCols - 1 && current.row == numRows - 1 {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
if current.col == numCols - 1 {
|
|
|
|
return Coord(row: current.row + 1, col: 0)
|
|
|
|
}
|
|
|
|
return Coord(row: current.row, col: current.col + 1)
|
|
|
|
}
|
|
|
|
|
|
|
|
mutating func next() -> Coord? {
|
|
|
|
defer {
|
|
|
|
current = getNextCoord()
|
|
|
|
}
|
|
|
|
return current
|
|
|
|
}
|
2021-12-09 06:35:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
struct Day09: Runnable {
|
|
|
|
let inputPath: String
|
|
|
|
|
|
|
|
func run() {
|
|
|
|
let input = try! String(contentsOfFile: inputPath)
|
|
|
|
let entries = input
|
|
|
|
.trimmingCharacters(in: .newlines)
|
|
|
|
.components(separatedBy: .newlines)
|
|
|
|
.map { line in line.map { $0.wholeNumberValue! } }
|
|
|
|
let field = Field(numbers: entries)
|
2021-12-09 06:48:45 +00:00
|
|
|
let sum = field.compactMap { field.lowPointValueAt(coord: $0) }.reduce(0, { $0 + $1 + 1 })
|
2021-12-09 06:35:17 +00:00
|
|
|
print(sum)
|
|
|
|
}
|
|
|
|
}
|