diff --git a/Package.swift b/Package.swift index 1ac491e..02c3197 100644 --- a/Package.swift +++ b/Package.swift @@ -20,7 +20,8 @@ let package = Package( .executable(name: "08", targets: ["08"]), .executable(name: "09", targets: ["09"]), .executable(name: "10", targets: ["10"]), - .executable(name: "11", targets: ["11"]) + .executable(name: "11", targets: ["11"]), + .executable(name: "12", targets: ["12"]) ], dependencies: [ // Dependencies declare other packages that this package depends on. @@ -92,9 +93,13 @@ let package = Package( ), .executableTarget( name: "11", + dependencies: [ .targetItem(name: "Runner", condition: nil) ] + ), + .executableTarget( + name: "12", dependencies: [ .targetItem(name: "Runner", condition: nil), - //.product(name: "Collections", package: "swift-collections"), + .product(name: "Collections", package: "swift-collections") ] ) ] diff --git a/Sources/11/11.swift b/Sources/11/11.swift index d665757..4ebc124 100644 --- a/Sources/11/11.swift +++ b/Sources/11/11.swift @@ -49,14 +49,14 @@ class Day11: Runnable { .map { Array($0) } .map { ar in ar.map {c in Int(c.description)!} } - for _ in 0..<100 { + var step = 0 + while(flashed.count < numRows * numCols) { flashed = Set() 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) @@ -66,8 +66,12 @@ class Day11: Runnable { for flash in flashed { octopuses[flash] = 0 } + step += 1 + if step == 100 { + print(numFlashes) + } } - print(numFlashes) + print("All flashing at step: \(step)") } func checkAndFlash(at coord: Coord) { diff --git a/Sources/12/12.swift b/Sources/12/12.swift new file mode 100644 index 0000000..668e9b5 --- /dev/null +++ b/Sources/12/12.swift @@ -0,0 +1,111 @@ +// +// File.swift +// +// +// Created by Max Nuding on 12.12.21. +// + +import Foundation +import Runner +import Collections + +class Cave: Hashable, CustomStringConvertible, CustomDebugStringConvertible { + static func == (lhs: Cave, rhs: Cave) -> Bool { lhs.name == rhs.name } + + func hash(into hasher: inout Hasher) { + hasher.combine(name) + } + + var description: String { name } + var debugDescription: String { name } + + let name: String + var connectedCaves = [Cave]() + var isBigCave: Bool + var isEnd: Bool + + required init(name: String) { + self.name = name + self.isBigCave = name.first!.isUppercase + self.isEnd = name == "end" + } +} + +class Path: Hashable, CustomStringConvertible { + static func == (lhs: Path, rhs: Path) -> Bool { + lhs.parts == rhs.parts + } + + func hash(into hasher: inout Hasher) { + hasher.combine(parts) + } + + var parts: [Cave] + private var partsSet: Set + var description: String { parts.map {$0.description}.joined(separator: "->") } + + required init(parts: [Cave]) { + self.parts = parts + partsSet = Set(parts) + } + + func contains(cave: Cave) -> Bool { partsSet.contains(cave) } +} + +class Day12: Runnable { + let inputPath: String + var caves = [String:Cave]() + + required init(inputPath: String) { + self.inputPath = inputPath + } + + public func run() { + let input = try! String(contentsOfFile: inputPath) + caves = input + .trimmingCharacters(in: .newlines) + .components(separatedBy: .newlines) + .reduce(into: [String:Cave](), { caves, line in + let caveConnection = line.components(separatedBy: "-") + let caveFromName = caveConnection.first! + let caveToName = caveConnection.last! + let from = caves[caveFromName] ?? Cave(name: caveFromName) + let to = caves[caveToName] ?? Cave(name: caveToName) + from.connectedCaves.append(to) + to.connectedCaves.append(from) + caves[caveFromName] = from + caves[caveToName] = to + + }) + + var queue = Deque(minimumCapacity: 10000) + var visited = Set(minimumCapacity: 10000) + var numFinished = 0 + + var cave: Path? = Path(parts: [caves["start"]!]) + queue.append(cave!) + + while !queue.isEmpty { + cave = queue.popFirst() + if visited.contains(cave!) { + continue + } + //print("Current path: \(cave!)") + visited.insert(cave!) + + cave!.parts.last!.connectedCaves + .filter { $0.isBigCave || !cave!.contains(cave: $0) } + .forEach { + if $0.isEnd { + numFinished += 1 + //print("Finished: \(cave!.parts)->end") + return + } + var newParts = cave!.parts + newParts.append($0) + queue.append(Path(parts: newParts)) + } + } + print(numFinished) + } +} diff --git a/Sources/12/main.swift b/Sources/12/main.swift new file mode 100644 index 0000000..21793cd --- /dev/null +++ b/Sources/12/main.swift @@ -0,0 +1,12 @@ +// +// File.swift +// +// +// Created by Max Nuding on 05.12.21. +// + +import Foundation +import Runner + +//Runner(target: Day12.self, day: "12", isTest: true).run() +Runner(target: Day12.self, day: "12", isTest: false).run() diff --git a/Sources/Runner/Resources/input/12.txt b/Sources/Runner/Resources/input/12.txt new file mode 100644 index 0000000..607ff61 --- /dev/null +++ b/Sources/Runner/Resources/input/12.txt @@ -0,0 +1,25 @@ +start-kc +pd-NV +start-zw +UI-pd +HK-end +UI-kc +pd-ih +ih-end +start-UI +kc-zw +end-ks +MF-mq +HK-zw +LF-ks +HK-kc +ih-HK +kc-pd +ks-pd +MF-pd +UI-zw +ih-NV +ks-HK +MF-kc +zw-NV +NV-ks diff --git a/Sources/Runner/Resources/input/12_test.txt b/Sources/Runner/Resources/input/12_test.txt new file mode 100644 index 0000000..62cc714 --- /dev/null +++ b/Sources/Runner/Resources/input/12_test.txt @@ -0,0 +1,10 @@ +dc-end +HN-start +start-kj +dc-start +dc-HN +LN-dc +HN-end +kj-sa +kj-HN +kj-dc