12b
This commit is contained in:
parent
5052110cb1
commit
7f201a614b
@ -23,33 +23,42 @@ class Cave: Hashable, CustomStringConvertible, CustomDebugStringConvertible {
|
||||
var connectedCaves = [Cave]()
|
||||
var isBigCave: Bool
|
||||
var isEnd: Bool
|
||||
var isStart: Bool
|
||||
|
||||
required init(name: String) {
|
||||
self.name = name
|
||||
self.isBigCave = name.first!.isUppercase
|
||||
self.isEnd = name == "end"
|
||||
self.isStart = name == "start"
|
||||
}
|
||||
}
|
||||
|
||||
class Path: Hashable, CustomStringConvertible {
|
||||
static func == (lhs: Path, rhs: Path) -> Bool {
|
||||
lhs.parts == rhs.parts
|
||||
struct Path: Hashable, CustomStringConvertible {
|
||||
var parts: [Cave]
|
||||
var visitedSmallCaveTwice = false
|
||||
var description: String
|
||||
|
||||
func contains(cave: Cave) -> Bool { parts.contains(cave) }
|
||||
|
||||
func appending(cave: Cave) -> Path {
|
||||
var newParts = parts
|
||||
newParts.append(cave)
|
||||
return Path(
|
||||
parts: newParts,
|
||||
visitedSmallCaveTwice: visitedSmallCaveTwice || !cave.isBigCave && contains(cave: cave))
|
||||
}
|
||||
|
||||
static func == (lhs: Path, rhs: Path) -> Bool { lhs.description == rhs.description }
|
||||
|
||||
func hash(into hasher: inout Hasher) {
|
||||
hasher.combine(parts)
|
||||
hasher.combine(description)
|
||||
}
|
||||
|
||||
var parts: [Cave]
|
||||
private var partsSet: Set<Cave>
|
||||
var description: String { parts.map {$0.description}.joined(separator: "->") }
|
||||
|
||||
required init(parts: [Cave]) {
|
||||
init(parts: [Cave], visitedSmallCaveTwice: Bool = false) {
|
||||
self.parts = parts
|
||||
partsSet = Set(parts)
|
||||
self.visitedSmallCaveTwice = visitedSmallCaveTwice
|
||||
self.description = (visitedSmallCaveTwice ? "*" : "") + parts.map {$0.description}.joined(separator: "->")
|
||||
}
|
||||
|
||||
func contains(cave: Cave) -> Bool { partsSet.contains(cave) }
|
||||
}
|
||||
|
||||
class Day12: Runnable {
|
||||
@ -77,7 +86,12 @@ class Day12: Runnable {
|
||||
caves[caveToName] = to
|
||||
|
||||
})
|
||||
runA()
|
||||
runB()
|
||||
|
||||
}
|
||||
|
||||
func runA() {
|
||||
var queue = Deque<Path>(minimumCapacity: 10000)
|
||||
var visited = Set<Path>(minimumCapacity: 10000)
|
||||
var numFinished = 0
|
||||
@ -90,7 +104,6 @@ class Day12: Runnable {
|
||||
if visited.contains(cave!) {
|
||||
continue
|
||||
}
|
||||
//print("Current path: \(cave!)")
|
||||
visited.insert(cave!)
|
||||
|
||||
cave!.parts.last!.connectedCaves
|
||||
@ -108,4 +121,35 @@ class Day12: Runnable {
|
||||
}
|
||||
print(numFinished)
|
||||
}
|
||||
|
||||
func runB() {
|
||||
var queue = Deque<Path>(minimumCapacity: 1000000)
|
||||
var visited = Set<Path>(minimumCapacity: 1000000)
|
||||
var numFinished = 0
|
||||
|
||||
var cave: Path? = Path(parts: [caves["start"]!])
|
||||
queue.append(cave!)
|
||||
|
||||
while !queue.isEmpty {
|
||||
cave = queue.popFirst()
|
||||
if visited.contains(cave!) {
|
||||
continue
|
||||
}
|
||||
visited.insert(cave!)
|
||||
cave!.parts.last!.connectedCaves
|
||||
.forEach {
|
||||
if $0.isStart || (cave!.visitedSmallCaveTwice && !$0.isBigCave && cave!.contains(cave: $0)) {
|
||||
return
|
||||
}
|
||||
if $0.isEnd {
|
||||
numFinished += 1
|
||||
return
|
||||
}
|
||||
var newParts = cave!.parts
|
||||
newParts.append($0)
|
||||
queue.append(cave!.appending(cave: $0))
|
||||
}
|
||||
}
|
||||
print(numFinished)
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,7 @@
|
||||
dc-end
|
||||
HN-start
|
||||
start-kj
|
||||
dc-start
|
||||
dc-HN
|
||||
LN-dc
|
||||
HN-end
|
||||
kj-sa
|
||||
kj-HN
|
||||
kj-dc
|
||||
start-A
|
||||
start-b
|
||||
A-c
|
||||
A-b
|
||||
b-d
|
||||
A-end
|
||||
b-end
|
||||
|
Loading…
Reference in New Issue
Block a user