diff --git a/Sources/15/15.swift b/Sources/15/15.swift index 9b90183..e06d373 100644 --- a/Sources/15/15.swift +++ b/Sources/15/15.swift @@ -29,7 +29,6 @@ struct Coord: Hashable, CustomStringConvertible { class Day15: Runnable { let inputPath: String - var field = [Coord]() var lastRow: Int = 0 var lastCol: Int = 0 var parts = [[ThreatLevel]]() @@ -71,22 +70,29 @@ class Day15: Runnable { lastRow = parts.count - 1 lastCol = (parts.first?.count ?? 0) - 1 - var unvisited = Set() // Distances to startNode var totalThreatLevel = [Coord: ThreatLevel]() - for row in parts.enumerated() { - for col in row.element.indices { - let c = Coord(row: row.offset, col: col) - unvisited.insert(c) - //totalThreatLevel[c] = Int.max + + var unvisited = Set(parts.enumerated().flatMap {row in + row.element.indices.map { col in + Coord(row: row.offset, col: col) } - } + }) + var threatLevelDistrubution = [ThreatLevel: Set]() let startNode = Coord(row: 0, col: 0) totalThreatLevel[startNode] = 0 + threatLevelDistrubution[Int.max] = unvisited + threatLevelDistrubution[Int.max]!.remove(startNode) + threatLevelDistrubution[0] = Set([startNode]) - while let currentNode = unvisited.min(by: { totalThreatLevel[$0, default: Int.max] < totalThreatLevel[$1, default: Int.max] }) { - //var currentNode = ! + while let threatLevel = threatLevelDistrubution.keys.min() { + let currentNode = threatLevelDistrubution[threatLevel]!.first! unvisited.remove(currentNode) + threatLevelDistrubution[threatLevel]!.remove(currentNode) + if threatLevelDistrubution[threatLevel]!.isEmpty { + threatLevelDistrubution.removeValue(forKey: threatLevel) + } + if neighbors[currentNode] == nil { neighbors[currentNode] = currentNode .neighbors() @@ -103,8 +109,14 @@ class Day15: Runnable { let currentThreatLevel = totalThreatLevel[currentNode, default: Int.max] for a in adjacent { let testCost = parts[a] + currentThreatLevel - if totalThreatLevel[a, default: Int.max] > testCost { + let currentCost = totalThreatLevel[a, default: Int.max] + if currentCost > testCost { totalThreatLevel[a] = testCost + threatLevelDistrubution[currentCost]!.remove(a) + threatLevelDistrubution[testCost, default: Set()].insert(a) + if threatLevelDistrubution[currentCost]!.isEmpty { + threatLevelDistrubution.removeValue(forKey: currentCost) + } } } }