@@ -96,3 +96,60 @@ public func part1() -> Int {
96
96
search ( inputData ( ) , Set ( [ " AA " ] ) , 0 , " AA " , 29 , & result)
97
97
return result
98
98
}
99
+
100
+ func paths( _ world: World , _ path: [ ( String , Int ) ] , _ cur: String , _ timeLeft: Int , _ result: inout [ [ ( String , Int ) ] ] ) {
101
+ if timeLeft <= 0 {
102
+ result. append ( path)
103
+ return
104
+ }
105
+ if !path. contains ( where: { $0. 0 == cur } ) {
106
+ paths ( world, path + [ ( cur, timeLeft) ] , cur, timeLeft - 1 , & result)
107
+ } else {
108
+ for n in world. costs [ cur] ! where !path. contains ( where: { $0. 0 == n. 0 } ) {
109
+ paths ( world, path, n. 0 , timeLeft - n. 1 , & result)
110
+ }
111
+ }
112
+ }
113
+
114
+ struct Path : Equatable {
115
+ let path : [ String ]
116
+ let points : Set < String >
117
+ let flow : Int
118
+
119
+ init ( path: [ String ] , flow: Int ) {
120
+ self . path = path
121
+ self . flow = flow
122
+ points = Set ( path)
123
+ }
124
+ }
125
+
126
+ public func part2( ) -> Int {
127
+ let world = inputData ( )
128
+ var allPaths = [ [ ( String, Int) ] ] ( )
129
+ paths ( world, [ ( " AA " , 0 ) ] , " AA " , 25 , & allPaths)
130
+ var computed : [ Path ] = allPaths. map { p in
131
+ Path (
132
+ path: p. reduce ( into: [ String] ( ) , { if " AA " != $1. 0 { $0. append ( $1. 0 ) } } ) ,
133
+ flow: p. reduce ( 0 , { $0 + $1. 1 * ( world. flow [ $1. 0 ] ?? 0 ) } )
134
+ )
135
+ }
136
+ var best = Dictionary < Set < String > , Path > ( )
137
+ for p in computed {
138
+ if let prev = best [ p. points] {
139
+ if p. flow > prev. flow {
140
+ best [ p. points] = p
141
+ }
142
+ } else {
143
+ best [ p. points] = p
144
+ }
145
+ }
146
+ computed = best. values. sorted ( by: { $0. flow < $1. flow } )
147
+ var result = - 1
148
+ for p in computed {
149
+ for q in computed{
150
+ guard p. points. intersection ( q. points) . isEmpty else { continue }
151
+ result = max ( result, q. flow + p. flow)
152
+ }
153
+ }
154
+ return result
155
+ }
0 commit comments