this repo has no description
at master 24 kB view raw
1<!-- livebook:{"persist_outputs":true} --> 2 3# Day 16 4 5```elixir 6Mix.install([ 7 {:kino_aoc, git: "https://github.com/ljgago/kino_aoc"}, 8 {:libgraph, github: "hauleth/libgraph", ref: "perf/bellman-ford-implementation"} 9]) 10``` 11 12<!-- livebook:{"output":true} --> 13 14``` 15:ok 16``` 17 18## Setup 19 20<!-- livebook:{"attrs":{"day":"16","session_secret":"ADVENT_OF_CODE_SESSION","variable":"puzzle_input","year":"2022"},"chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} --> 21 22```elixir 23{:ok, puzzle_input} = 24 KinoAOC.download_puzzle("2022", "16", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION")) 25``` 26 27<!-- livebook:{"output":true} --> 28 29``` 30{:ok, 31 "Valve QJ has flow rate=11; tunnels lead to valves HB, GL\nValve VZ has flow rate=10; tunnel leads to valve NE\nValve TX has flow rate=19; tunnels lead to valves MG, OQ, HM\nValve ZI has flow rate=5; tunnels lead to valves BY, ON, RU, LF, JR\nValve IH has flow rate=0; tunnels lead to valves YB, QS\nValve QS has flow rate=22; tunnel leads to valve IH\nValve QB has flow rate=0; tunnels lead to valves QX, ES\nValve NX has flow rate=0; tunnels lead to valves UH, OP\nValve PJ has flow rate=0; tunnels lead to valves OC, UH\nValve OR has flow rate=6; tunnels lead to valves QH, BH, HB, JD\nValve OC has flow rate=7; tunnels lead to valves IZ, JR, TA, ZH, PJ\nValve UC has flow rate=0; tunnels lead to valves AA, BY\nValve QX has flow rate=0; tunnels lead to valves AA, QB\nValve IZ has flow rate=0; tunnels lead to valves OC, SX\nValve AG has flow rate=13; tunnels lead to valves NW, GL, SM\nValve ON has flow rate=0; tunnels lead to valves MO, ZI\nValve XT has flow rate=18; tunnels lead to valves QZ, PG\nValve AX has flow rate=0; tunnels lead to valves UH, MO\nValve JD has flow rate=0; tunnels lead to valves OR, SM\nValve HM has flow rate=0; tunnels lead to valves TX, QH\nValve LF has flow rate=0; tunnels lead to valves ZI, UH\nValve QH has flow rate=0; tunnels lead to valves OR, HM\nValve RT has flow rate=21; tunnel leads to valve PG\nValve NE has flow rate=0; tunnels lead to valves VZ, TA\nValve OQ has flow rate=0; tunnels lead to valves TX, GE\nValve AA has flow rate=0; tunnels lead to valves QZ, UC, OP, QX, EH\nValve UH has flow rate=17; tunnels lead to valves PJ, NX, AX, LF\nValve GE has flow rate=0; tunnels lead to valves YB, OQ\nValve EH has flow rate=0; tunnels lead to valves AA, MO\nValve MG has flow rate=0; tunnels lead to valves TX, NW\nValve YB has flow rate=20; tunnels lead to valves IH, GE, XG\nValve MO has flow rate=15; tunnels lead to valves EH, ON, AX, ZH, CB\nValve JR has flow rate=0; tunnels lead to valves ZI, OC\nValve GL has flow rate=0; tunnels lead to valves AG, QJ\nValve SM has flow rate=0; tunnels lead to valves JD, AG\nValve HB has flow rate=0; tunnels lead to valves OR, QJ\nValve TA has flow rate=0; tunnels lead to valves OC, NE\nValve PG has flow rate=0; tunnels lead to valves RT, XT\nValve XG has flow rate=0; tunnels lead to valves CB, YB\nValve ES has flow rate=9; tunnels lead to valves QB, FL\nValve BH has flow rate=0; tunnels lead to valves RU, OR\nValve FL has flow rate=0; tunnels lead to valves SX, ES\nValve CB has flow rate=0; tunnels lead to valves MO, XG\nValve QZ has flow rate=0; tunnels lead to valves AA, XT\nValve BY has flow rate=0; tunnels lead to valves UC, ZI\nValve ZH has flow rate=0; tunnels lead to valves MO, OC\nValve OP has flow rate=0; tunnels lead to valves NX, AA\nValve NW has flow rate=0; tunnels lead to valves MG, AG\nValve RU has flow rate=0; tunnels lead to valves ZI, BH\nValve SX has flow rate=16; tunnels lead to valves IZ, FL"} 32``` 33 34```elixir 35# puzzle_input = """ 36# Valve AA has flow rate=0; tunnels lead to valves DD, II, BB 37# Valve BB has flow rate=13; tunnels lead to valves CC, AA 38# Valve CC has flow rate=2; tunnels lead to valves DD, BB 39# Valve DD has flow rate=20; tunnels lead to valves CC, AA, EE 40# Valve EE has flow rate=3; tunnels lead to valves FF, DD 41# Valve FF has flow rate=0; tunnels lead to valves EE, GG 42# Valve GG has flow rate=0; tunnels lead to valves FF, HH 43# Valve HH has flow rate=22; tunnel leads to valve GG 44# Valve II has flow rate=0; tunnels lead to valves AA, JJ 45# Valve JJ has flow rate=21; tunnel leads to valve II 46# """ 47``` 48 49<!-- livebook:{"output":true} --> 50 51``` 52nil 53``` 54 55```elixir 56{{start, _}, valves} = 57 valves = 58 puzzle_input 59 |> String.split("\n", trim: true) 60 |> Kino.render() 61 |> Enum.map(fn line -> 62 %{ 63 "name" => name, 64 "rate" => rate, 65 "routes" => routes 66 } = 67 Regex.named_captures( 68 ~r/Valve (?<name>..).*rate=(?<rate>\d+);.*valves? (?<routes>.*)$/, 69 line 70 ) 71 72 {name, %{rate: String.to_integer(rate), routes: String.split(routes, ~r/,\s*/, trim: true)}} 73 end) 74 |> then(&{hd(&1), Map.new(&1)}) 75``` 76 77<!-- livebook:{"output":true} --> 78 79``` 80["Valve QJ has flow rate=11; tunnels lead to valves HB, GL", 81 "Valve VZ has flow rate=10; tunnel leads to valve NE", 82 "Valve TX has flow rate=19; tunnels lead to valves MG, OQ, HM", 83 "Valve ZI has flow rate=5; tunnels lead to valves BY, ON, RU, LF, JR", 84 "Valve IH has flow rate=0; tunnels lead to valves YB, QS", 85 "Valve QS has flow rate=22; tunnel leads to valve IH", 86 "Valve QB has flow rate=0; tunnels lead to valves QX, ES", 87 "Valve NX has flow rate=0; tunnels lead to valves UH, OP", 88 "Valve PJ has flow rate=0; tunnels lead to valves OC, UH", 89 "Valve OR has flow rate=6; tunnels lead to valves QH, BH, HB, JD", 90 "Valve OC has flow rate=7; tunnels lead to valves IZ, JR, TA, ZH, PJ", 91 "Valve UC has flow rate=0; tunnels lead to valves AA, BY", 92 "Valve QX has flow rate=0; tunnels lead to valves AA, QB", 93 "Valve IZ has flow rate=0; tunnels lead to valves OC, SX", 94 "Valve AG has flow rate=13; tunnels lead to valves NW, GL, SM", 95 "Valve ON has flow rate=0; tunnels lead to valves MO, ZI", 96 "Valve XT has flow rate=18; tunnels lead to valves QZ, PG", 97 "Valve AX has flow rate=0; tunnels lead to valves UH, MO", 98 "Valve JD has flow rate=0; tunnels lead to valves OR, SM", 99 "Valve HM has flow rate=0; tunnels lead to valves TX, QH", 100 "Valve LF has flow rate=0; tunnels lead to valves ZI, UH", 101 "Valve QH has flow rate=0; tunnels lead to valves OR, HM", 102 "Valve RT has flow rate=21; tunnel leads to valve PG", 103 "Valve NE has flow rate=0; tunnels lead to valves VZ, TA", 104 "Valve OQ has flow rate=0; tunnels lead to valves TX, GE", 105 "Valve AA has flow rate=0; tunnels lead to valves QZ, UC, OP, QX, EH", 106 "Valve UH has flow rate=17; tunnels lead to valves PJ, NX, AX, LF", 107 "Valve GE has flow rate=0; tunnels lead to valves YB, OQ", 108 "Valve EH has flow rate=0; tunnels lead to valves AA, MO", 109 "Valve MG has flow rate=0; tunnels lead to valves TX, NW", 110 "Valve YB has flow rate=20; tunnels lead to valves IH, GE, XG", 111 "Valve MO has flow rate=15; tunnels lead to valves EH, ON, AX, ZH, CB", 112 "Valve JR has flow rate=0; tunnels lead to valves ZI, OC", 113 "Valve GL has flow rate=0; tunnels lead to valves AG, QJ", 114 "Valve SM has flow rate=0; tunnels lead to valves JD, AG", 115 "Valve HB has flow rate=0; tunnels lead to valves OR, QJ", 116 "Valve TA has flow rate=0; tunnels lead to valves OC, NE", 117 "Valve PG has flow rate=0; tunnels lead to valves RT, XT", 118 "Valve XG has flow rate=0; tunnels lead to valves CB, YB", 119 "Valve ES has flow rate=9; tunnels lead to valves QB, FL", 120 "Valve BH has flow rate=0; tunnels lead to valves RU, OR", 121 "Valve FL has flow rate=0; tunnels lead to valves SX, ES", 122 "Valve CB has flow rate=0; tunnels lead to valves MO, XG", 123 "Valve QZ has flow rate=0; tunnels lead to valves AA, XT", 124 "Valve BY has flow rate=0; tunnels lead to valves UC, ZI", 125 "Valve ZH has flow rate=0; tunnels lead to valves MO, OC", 126 "Valve OP has flow rate=0; tunnels lead to valves NX, AA", 127 "Valve NW has flow rate=0; tunnels lead to valves MG, AG", 128 "Valve RU has flow rate=0; tunnels lead to valves ZI, BH", 129 "Valve SX has flow rate=16; tunnels lead to valves IZ, FL"] 130``` 131 132<!-- livebook:{"output":true} --> 133 134``` 135{{"QJ", %{rate: 11, routes: ["HB", "GL"]}}, 136 %{ 137 "CB" => %{rate: 0, routes: ["MO", "XG"]}, 138 "EH" => %{rate: 0, routes: ["AA", "MO"]}, 139 "YB" => %{rate: 20, routes: ["IH", "GE", "XG"]}, 140 "ON" => %{rate: 0, routes: ["MO", "ZI"]}, 141 "ES" => %{rate: 9, routes: ["QB", "FL"]}, 142 "XG" => %{rate: 0, routes: ["CB", "YB"]}, 143 "TX" => %{rate: 19, routes: ["MG", "OQ", "HM"]}, 144 "RT" => %{rate: 21, routes: ["PG"]}, 145 "GL" => %{rate: 0, routes: ["AG", "QJ"]}, 146 "XT" => %{rate: 18, routes: ["QZ", "PG"]}, 147 "BY" => %{rate: 0, routes: ["UC", "ZI"]}, 148 "QJ" => %{rate: 11, routes: ["HB", "GL"]}, 149 "QB" => %{rate: 0, routes: ["QX", "ES"]}, 150 "QH" => %{rate: 0, routes: ["OR", "HM"]}, 151 "SX" => %{rate: 16, routes: ["IZ", "FL"]}, 152 "ZI" => %{rate: 5, routes: ["BY", "ON", "RU", "LF", "JR"]}, 153 "OC" => %{rate: 7, routes: ["IZ", "JR", "TA", "ZH", "PJ"]}, 154 "NW" => %{rate: 0, routes: ["MG", "AG"]}, 155 "UH" => %{rate: 17, routes: ["PJ", "NX", "AX", "LF"]}, 156 "VZ" => %{rate: 10, routes: ["NE"]}, 157 "MO" => %{rate: 15, routes: ["EH", "ON", "AX", "ZH", "CB"]}, 158 "ZH" => %{rate: 0, routes: ["MO", "OC"]}, 159 "RU" => %{rate: 0, routes: ["ZI", "BH"]}, 160 "FL" => %{rate: 0, routes: ["SX", "ES"]}, 161 "SM" => %{rate: 0, routes: ["JD", "AG"]}, 162 "AA" => %{rate: 0, routes: ["QZ", "UC", "OP", "QX", "EH"]}, 163 "JR" => %{rate: 0, routes: ["ZI", "OC"]}, 164 "QS" => %{rate: 22, routes: ["IH"]}, 165 "AG" => %{rate: 13, routes: ["NW", "GL", "SM"]}, 166 "JD" => %{rate: 0, routes: ["OR", "SM"]}, 167 "QZ" => %{rate: 0, routes: ["AA", "XT"]}, 168 "MG" => %{rate: 0, routes: ["TX", "NW"]}, 169 "UC" => %{rate: 0, routes: ["AA", "BY"]}, 170 "AX" => %{rate: 0, routes: ["UH", "MO"]}, 171 "HM" => %{rate: 0, routes: ["TX", "QH"]}, 172 "LF" => %{rate: 0, routes: ["ZI", "UH"]}, 173 "BH" => %{rate: 0, routes: ["RU", "OR"]}, 174 "OR" => %{rate: 6, routes: ["QH", "BH", "HB", "JD"]}, 175 "GE" => %{rate: 0, routes: ["YB", "OQ"]}, 176 "QX" => %{rate: 0, routes: ["AA", "QB"]}, 177 "IZ" => %{rate: 0, routes: ["OC", "SX"]}, 178 "PG" => %{rate: 0, routes: ["RT", "XT"]}, 179 "NX" => %{rate: 0, routes: ["UH", "OP"]}, 180 "OP" => %{rate: 0, routes: ["NX", "AA"]}, 181 "TA" => %{rate: 0, routes: ["OC", ...]}, 182 "IH" => %{rate: 0, routes: [...]}, 183 "HB" => %{rate: 0, ...}, 184 "PJ" => %{...}, 185 ... 186 }} 187``` 188 189```elixir 190graph = Graph.new(type: :directed) 191 192edges = 193 Enum.flat_map(valves, fn {a, %{routes: routes}} -> 194 for b <- routes, p <- [{a, b, weight: 1}, {b, a, weight: 1}], do: p 195 end) 196 197graph = 198 Graph.add_edges(graph, edges) 199 |> Kino.render() 200 201paths = 202 for v <- Graph.vertices(graph), into: %{} do 203 routes = 204 graph 205 |> Graph.bellman_ford(v) 206 |> Enum.filter(fn {k, _} -> valves[k].rate > 0 and k != v end) 207 |> Map.new() 208 209 {v, routes} 210 end 211``` 212 213<!-- livebook:{"output":true} --> 214 215``` 216#Graph<type: directed, vertices: ["LF", "CB", "AX", "ZI", "ZH", "VZ", "AA", "UH", "OC", "IH", "FL", 217 "JR", "QB", "EH", "QH", "ON", "TA", "PJ", "SX", "YB", "UC", "BH", "MO", "OQ", "HM", "JD", "OR", 218 "NE", "QS", "XT", "IZ", "QZ", "BY", "PG", "NW", "HB", "AG", "QJ", "RT", "TX", "GE", "QX", "XG", 219 "NX", "GL", "RU", "SM", "ES", "MG", 220 "OP"], edges: ["LF" -> "UH", "LF" -> "ZI", "CB" -> "MO", "CB" -> "XG", "AX" -> "UH", "AX" -> "MO", "ZI" -> "BY", "ZI" -> "RU", "ZI" -> "ON", "ZI" -> "LF", "ZI" -> "JR", "ZH" -> "OC", "ZH" -> "MO", "VZ" -> "NE", "AA" -> "UC", "AA" -> "EH", "AA" -> "QX", "AA" -> "OP", "AA" -> "QZ", "UH" -> "LF", "UH" -> "PJ", "UH" -> "AX", "UH" -> "NX", "OC" -> "ZH", "OC" -> "IZ", "OC" -> "TA", "OC" -> "PJ", "OC" -> "JR", "IH" -> "YB", "IH" -> "QS", "FL" -> "SX", "FL" -> "ES", "JR" -> "OC", "JR" -> "ZI", "QB" -> "QX", "QB" -> "ES", "EH" -> "MO", "EH" -> "AA", "QH" -> "OR", "QH" -> "HM", "ON" -> "MO", "ON" -> "ZI", "TA" -> "OC", "TA" -> "NE", "PJ" -> "OC", "PJ" -> "UH", "SX" -> "IZ", "SX" -> "FL", "YB" -> "GE", "YB" -> "IH", "YB" -> "XG", "UC" -> "BY", "UC" -> "AA", "BH" -> "OR", "BH" -> "RU", "MO" -> "ZH", "MO" -> "EH", "MO" -> "ON", "MO" -> "CB", "MO" -> "AX", "OQ" -> "GE", "OQ" -> "TX", "HM" -> "TX", "HM" -> "QH", "JD" -> "OR", "JD" -> "SM", "OR" -> "BH", "OR" -> "HB", "OR" -> "JD", "OR" -> "QH", "NE" -> "TA", "NE" -> "VZ", "QS" -> "IH", "XT" -> "QZ", "XT" -> "PG", "IZ" -> "OC", "IZ" -> "SX", "QZ" -> "AA", "QZ" -> "XT", "BY" -> "UC", "BY" -> "ZI", "PG" -> "RT", "PG" -> "XT", "NW" -> "MG", "NW" -> "AG", "HB" -> "OR", "HB" -> "QJ", "AG" -> "SM", "AG" -> "GL", "AG" -> "NW", "QJ" -> "GL", "QJ" -> "HB", "RT" -> "PG", "TX" -> "OQ", "TX" -> "MG", "TX" -> "HM", "GE" -> "OQ", "GE" -> "YB", "QX" -> "QB", "QX" -> "AA", "XG" -> "YB", "XG" -> "CB", "NX" -> "UH", "NX" -> "OP", "GL" -> "QJ", "GL" -> "AG", "RU" -> "BH", "RU" -> "ZI", "SM" -> "AG", "SM" -> "JD", "ES" -> "QB", "ES" -> "FL", "MG" -> "NW", "MG" -> "TX", "OP" -> "AA", "OP" -> "NX"]> 221``` 222 223<!-- livebook:{"output":true} --> 224 225``` 226%{ 227 "CB" => %{ 228 "AG" => 8, 229 "ES" => 6, 230 "MO" => 1, 231 "OC" => 3, 232 "OR" => 6, 233 "QJ" => 8, 234 "QS" => 4, 235 "RT" => 7, 236 "SX" => 5, 237 "TX" => 5, 238 "UH" => 3, 239 "VZ" => 6, 240 "XT" => 5, 241 "YB" => 2, 242 "ZI" => 3 243 }, 244 "EH" => %{ 245 "AG" => 9, 246 "ES" => 4, 247 "MO" => 1, 248 "OC" => 3, 249 "OR" => 6, 250 "QJ" => 8, 251 "QS" => 6, 252 "RT" => 5, 253 "SX" => 5, 254 "TX" => 7, 255 "UH" => 3, 256 "VZ" => 6, 257 "XT" => 3, 258 "YB" => 4, 259 "ZI" => 3 260 }, 261 "YB" => %{ 262 "AG" => 6, 263 "ES" => 8, 264 "MO" => 3, 265 "OC" => 5, 266 "OR" => 6, 267 "QJ" => 8, 268 "QS" => 2, 269 "RT" => 9, 270 "SX" => 7, 271 "TX" => 3, 272 "UH" => 5, 273 "VZ" => 8, 274 "XT" => 7, 275 "ZI" => 5 276 }, 277 "ON" => %{ 278 "AG" => 7, 279 "ES" => 6, 280 "MO" => 1, 281 "OC" => 3, 282 "OR" => 4, 283 "QJ" => 6, 284 "QS" => 6, 285 "RT" => 7, 286 "SX" => 5, 287 "TX" => 7, 288 "UH" => 3, 289 "VZ" => 6, 290 "XT" => 5, 291 "YB" => 4, 292 "ZI" => 1 293 }, 294 "ES" => %{ 295 "AG" => 12, 296 "MO" => 5, 297 "OC" => 4, 298 "OR" => 9, 299 "QJ" => 11, 300 "QS" => 10, 301 "RT" => 7, 302 "SX" => 2, 303 "TX" => 11, 304 "UH" => 6, 305 "VZ" => 7, 306 "XT" => 5, 307 "YB" => 8, 308 "ZI" => 6 309 }, 310 "XG" => %{ 311 "AG" => 7, 312 "ES" => 7, 313 "MO" => 2, 314 "OC" => 4, 315 "OR" => 7, 316 "QJ" => 9, 317 "QS" => 3, 318 "RT" => 8, 319 "SX" => 6, 320 "TX" => 4, 321 "UH" => 4, 322 "VZ" => 7, 323 "XT" => 6, 324 "YB" => 1, 325 "ZI" => 4 326 }, 327 "TX" => %{ 328 "AG" => 3, 329 "ES" => 11, 330 "MO" => 6, 331 "OC" => 8, 332 "OR" => 3, 333 "QJ" => 5, 334 "QS" => 5, 335 "RT" => 12, 336 "SX" => 10, 337 "UH" => 8, 338 "VZ" => 11, 339 "XT" => 10, 340 "YB" => 3, 341 "ZI" => 6 342 }, 343 "RT" => %{ 344 "AG" => 13, 345 "ES" => 7, 346 "MO" => 6, 347 "OC" => 8, 348 "OR" => 10, 349 "QJ" => 12, 350 "QS" => 11, 351 "SX" => 9, 352 "TX" => 12, 353 "UH" => 7, 354 "VZ" => 11, 355 "XT" => 2, 356 "YB" => 9, 357 "ZI" => 7 358 }, 359 "GL" => %{ 360 "AG" => 1, 361 "ES" => 12, 362 "MO" => 8, 363 "OC" => 8, 364 "OR" => 3, 365 "QJ" => 1, 366 "QS" => 9, 367 "RT" => 13, 368 "SX" => 10, 369 "TX" => 4, 370 "UH" => 8, 371 "VZ" => 11, 372 "XT" => 11, 373 "YB" => 7, 374 "ZI" => 6 375 }, 376 "XT" => %{ 377 "AG" => 11, 378 "ES" => 5, 379 "MO" => 4, 380 "OC" => 6, 381 "OR" => 8, 382 "QJ" => 10, 383 "QS" => 9, 384 "RT" => 2, 385 "SX" => 7, 386 "TX" => 10, 387 "UH" => 5, 388 "VZ" => 9, 389 "YB" => 7, 390 "ZI" => 5 391 }, 392 "BY" => %{ 393 "AG" => 7, 394 "ES" => 5, 395 "MO" => 3, 396 "OC" => 3, 397 "OR" => 4, 398 "QJ" => 6, 399 "QS" => 8, 400 "RT" => 6, 401 "SX" => 5, 402 "TX" => 7, 403 "UH" => 3, 404 "VZ" => 6, 405 "XT" => 4, 406 "YB" => 6, 407 "ZI" => 1 408 }, 409 "QJ" => %{ 410 "AG" => 2, 411 "ES" => 11, 412 "MO" => 7, 413 "OC" => 7, 414 "OR" => 2, 415 "QS" => 10, 416 "RT" => 12, 417 "SX" => 9, 418 "TX" => 5, 419 "UH" => 7, 420 "VZ" => 10, 421 "XT" => 10, 422 "YB" => 8, 423 "ZI" => 5 424 }, 425 "QB" => %{ 426 "AG" => 11, 427 "ES" => 1, 428 "MO" => 4, 429 "OC" => 5, 430 "OR" => 8, 431 "QJ" => 10, 432 "QS" => 9, 433 "RT" => 6, 434 "SX" => 3, 435 "TX" => 10, 436 "UH" => 5, 437 "VZ" => 8, 438 "XT" => 4, 439 "YB" => 7, 440 "ZI" => 5 441 }, 442 "QH" => %{ 443 "AG" => 4, 444 "ES" => 10, 445 "MO" => 6, 446 "OC" => 6, 447 "OR" => 1, 448 "QJ" => 3, 449 "QS" => 7, 450 "RT" => 11, 451 "SX" => 8, 452 "TX" => 2, 453 "UH" => 6, 454 "VZ" => 9, 455 "XT" => 9, 456 "YB" => 5, 457 "ZI" => 4 458 }, 459 "SX" => %{ 460 "AG" => 10, 461 "ES" => 2, 462 "MO" => 4, 463 "OC" => 2, 464 "OR" => 7, 465 "QJ" => 9, 466 "QS" => 9, 467 "RT" => 9, 468 "TX" => 10, 469 "UH" => 4, 470 "VZ" => 5, 471 "XT" => 7, 472 "YB" => 7, 473 "ZI" => 4 474 }, 475 "ZI" => %{ 476 "AG" => 6, 477 "ES" => 6, 478 "MO" => 2, 479 "OC" => 2, 480 "OR" => 3, 481 "QJ" => 5, 482 "QS" => 7, 483 "RT" => 7, 484 "SX" => 4, 485 "TX" => 6, 486 "UH" => 2, 487 "VZ" => 5, 488 "XT" => 5, 489 "YB" => 5 490 }, 491 "OC" => %{ 492 "AG" => 8, 493 "ES" => 4, 494 "MO" => 2, 495 "OR" => 5, 496 "QJ" => 7, 497 "QS" => 7, 498 "RT" => 8, 499 "SX" => 2, 500 "TX" => 8, 501 "UH" => 2, 502 "VZ" => 3, 503 "XT" => 6, 504 "YB" => 5, 505 "ZI" => 2 506 }, 507 "NW" => %{ 508 "AG" => 1, 509 "ES" => 13, 510 "MO" => 8, 511 "OC" => 9, 512 "OR" => 4, 513 "QJ" => 3, 514 "QS" => 7, 515 "RT" => 14, 516 "SX" => 11, 517 "TX" => 2, 518 "UH" => 9, 519 "VZ" => 12, 520 "XT" => 12, 521 "YB" => 5, 522 "ZI" => 7 523 }, 524 "UH" => %{ 525 "AG" => 8, 526 "ES" => 6, 527 "MO" => 2, 528 "OC" => 2, 529 "OR" => 5, 530 "QJ" => 7, 531 "QS" => 7, 532 "RT" => 7, 533 "SX" => 4, 534 "TX" => 8, 535 "VZ" => 5, 536 "XT" => 5, 537 "YB" => 5, 538 "ZI" => 2 539 }, 540 "VZ" => %{ 541 "AG" => 11, 542 "ES" => 7, 543 "MO" => 5, 544 "OC" => 3, 545 "OR" => 8, 546 "QJ" => 10, 547 "QS" => 10, 548 "RT" => 11, 549 "SX" => 5, 550 "TX" => 11, 551 "UH" => 5, 552 "XT" => 9, 553 "YB" => 8, 554 "ZI" => 5 555 }, 556 "MO" => %{ 557 "AG" => 8, 558 "ES" => 5, 559 "OC" => 2, 560 "OR" => 5, 561 "QJ" => 7, 562 "QS" => 5, 563 "RT" => 6, 564 "SX" => 4, 565 "TX" => 6, 566 "UH" => 2, 567 "VZ" => 5, 568 "XT" => 4, 569 "YB" => 3, 570 "ZI" => 2 571 }, 572 "ZH" => %{ 573 "AG" => 9, 574 "ES" => 5, 575 "MO" => 1, 576 "OC" => 1, 577 "OR" => 6, 578 "QJ" => 8, 579 "QS" => 6, 580 "RT" => 7, 581 "SX" => 3, 582 "TX" => 7, 583 "UH" => 3, 584 "VZ" => 4, 585 "XT" => 5, 586 "YB" => 4, 587 "ZI" => 3 588 }, 589 "RU" => %{ 590 "AG" => 5, 591 "ES" => 7, 592 "MO" => 3, 593 "OC" => 3, 594 "OR" => 2, 595 "QJ" => 4, 596 "QS" => 8, 597 "RT" => 8, 598 "SX" => 5, 599 "TX" => 5, 600 "UH" => 3, 601 "VZ" => 6, 602 "XT" => 6, 603 "YB" => 6, 604 "ZI" => 1 605 }, 606 "FL" => %{ 607 "AG" => 11, 608 "ES" => 1, 609 "MO" => 5, 610 "OC" => 3, 611 "OR" => 8, 612 "QJ" => 10, 613 "QS" => 10, 614 "RT" => 8, 615 "SX" => 1, 616 "TX" => 11, 617 "UH" => 5, 618 "VZ" => 6, 619 "XT" => 6, 620 "YB" => 8, 621 "ZI" => 5 622 }, 623 "SM" => %{ 624 "AG" => 1, 625 "ES" => 11, 626 "MO" => 7, 627 "OC" => 7, 628 "OR" => 2, 629 "QJ" => 3, 630 "QS" => 9, 631 "RT" => 12, 632 "SX" => 9, 633 "TX" => 4, 634 "UH" => 7, 635 "VZ" => 10, 636 "XT" => 10, 637 "YB" => 7, 638 "ZI" => 5 639 }, 640 "AA" => %{ 641 "AG" => 9, 642 "ES" => 3, 643 "MO" => 2, 644 "OC" => 4, 645 "OR" => 6, 646 "QJ" => 8, 647 "QS" => 7, 648 "RT" => 4, 649 "SX" => 5, 650 "TX" => 8, 651 "UH" => 3, 652 "VZ" => 7, 653 "XT" => 2, 654 "YB" => 5, 655 "ZI" => 3 656 }, 657 "JR" => %{ 658 "AG" => 7, 659 "ES" => 5, 660 "MO" => 3, 661 "OC" => 1, 662 "OR" => 4, 663 "QJ" => 6, 664 "QS" => 8, 665 "RT" => 8, 666 "SX" => 3, 667 "TX" => 7, 668 "UH" => 3, 669 "VZ" => 4, 670 "XT" => 6, 671 "YB" => 6, 672 "ZI" => 1 673 }, 674 "QS" => %{ 675 "AG" => 8, 676 "ES" => 10, 677 "MO" => 5, 678 "OC" => 7, 679 "OR" => 8, 680 "QJ" => 10, 681 "RT" => 11, 682 "SX" => 9, 683 "TX" => 5, 684 "UH" => 7, 685 "VZ" => 10, 686 "XT" => 9, 687 "YB" => 2, 688 "ZI" => 7 689 }, 690 "AG" => %{ 691 "ES" => 12, 692 "MO" => 8, 693 "OC" => 8, 694 "OR" => 3, 695 "QJ" => 2, 696 "QS" => 8, 697 "RT" => 13, 698 "SX" => 10, 699 "TX" => 3, 700 "UH" => 8, 701 "VZ" => 11, 702 "XT" => 11, 703 "YB" => 6, 704 "ZI" => 6 705 }, 706 "JD" => %{ 707 "AG" => 2, 708 "ES" => 10, 709 "MO" => 6, 710 "OC" => 6, 711 "OR" => 1, 712 "QJ" => 3, 713 "QS" => 9, 714 "RT" => 11, 715 "SX" => 8, 716 "TX" => 4, 717 "UH" => 6, 718 "VZ" => 9, 719 "XT" => 9, 720 "YB" => 7, 721 "ZI" => 4 722 }, 723 "QZ" => %{ 724 "AG" => 10, 725 "ES" => 4, 726 "MO" => 3, 727 "OC" => 5, 728 "OR" => 7, 729 "QJ" => 9, 730 "QS" => 8, 731 "RT" => 3, 732 "SX" => 6, 733 "TX" => 9, 734 "UH" => 4, 735 "VZ" => 8, 736 "XT" => 1, 737 "YB" => 6, 738 "ZI" => 4 739 }, 740 "MG" => %{ 741 "AG" => 2, 742 "ES" => 12, 743 "MO" => 7, 744 "OC" => 9, 745 "OR" => 4, 746 "QJ" => 4, 747 "QS" => 6, 748 "RT" => 13, 749 "SX" => 11, 750 "TX" => 1, 751 "UH" => 9, 752 "VZ" => 12, 753 "XT" => 11, 754 "YB" => 4, 755 "ZI" => 7 756 }, 757 "UC" => %{ 758 "AG" => 8, 759 "ES" => 4, 760 "MO" => 3, 761 "OC" => 4, 762 "OR" => 5, 763 "QJ" => 7, 764 "QS" => 8, 765 "RT" => 5, 766 "SX" => 6, 767 "TX" => 8, 768 "UH" => 4, 769 "VZ" => 7, 770 "XT" => 3, 771 "YB" => 6, 772 "ZI" => 2 773 }, 774 "AX" => %{ 775 "AG" => 9, 776 "ES" => 6, 777 "MO" => 1, 778 "OC" => 3, 779 "OR" => 6, 780 "QJ" => 8, 781 "QS" => 6, 782 "RT" => 7, 783 "SX" => 5, 784 "TX" => 7, 785 "UH" => 1, 786 "VZ" => 6, 787 "XT" => 5, 788 "YB" => 4, 789 "ZI" => 3 790 }, 791 "HM" => %{ 792 "AG" => 4, 793 "ES" => 11, 794 "MO" => 7, 795 "OC" => 7, 796 "OR" => 2, 797 "QJ" => 4, 798 "QS" => 6, 799 "RT" => 12, 800 "SX" => 9, 801 "TX" => 1, 802 "UH" => 7, 803 "VZ" => 10, 804 "XT" => 10, 805 "YB" => 4, 806 "ZI" => 5 807 }, 808 "LF" => %{ 809 "AG" => 7, 810 "ES" => 7, 811 "MO" => 3, 812 "OC" => 3, 813 "OR" => 4, 814 "QJ" => 6, 815 "QS" => 8, 816 "RT" => 8, 817 "SX" => 5, 818 "TX" => 7, 819 "UH" => 1, 820 "VZ" => 6, 821 "XT" => 6, 822 "YB" => 6, 823 ... 824 }, 825 "BH" => %{ 826 "AG" => 4, 827 "ES" => 8, 828 "MO" => 4, 829 "OC" => 4, 830 "OR" => 1, 831 "QJ" => 3, 832 "QS" => 9, 833 "RT" => 9, 834 "SX" => 6, 835 "TX" => 4, 836 "UH" => 4, 837 "VZ" => 7, 838 "XT" => 7, 839 ... 840 }, 841 "OR" => %{ 842 "AG" => 3, 843 "ES" => 9, 844 "MO" => 5, 845 "OC" => 5, 846 "QJ" => 2, 847 "QS" => 8, 848 "RT" => 10, 849 "SX" => 7, 850 "TX" => 3, 851 "UH" => 5, 852 "VZ" => 8, 853 "XT" => 8, 854 ... 855 }, 856 "GE" => %{ 857 "AG" => 5, 858 "ES" => 9, 859 "MO" => 4, 860 "OC" => 6, 861 "OR" => 5, 862 "QJ" => 7, 863 "QS" => 3, 864 "RT" => 10, 865 "SX" => 8, 866 "TX" => 2, 867 "UH" => 6, 868 ... 869 }, 870 "QX" => %{ 871 "AG" => 10, 872 "ES" => 2, 873 "MO" => 3, 874 "OC" => 5, 875 "OR" => 7, 876 "QJ" => 9, 877 "QS" => 8, 878 "RT" => 5, 879 "SX" => 4, 880 "TX" => 9, 881 ... 882 }, 883 "IZ" => %{ 884 "AG" => 9, 885 "ES" => 3, 886 "MO" => 3, 887 "OC" => 1, 888 "OR" => 6, 889 "QJ" => 8, 890 "QS" => 8, 891 "RT" => 9, 892 "SX" => 1, 893 ... 894 }, 895 "PG" => %{ 896 "AG" => 12, 897 "ES" => 6, 898 "MO" => 5, 899 "OC" => 7, 900 "OR" => 9, 901 "QJ" => 11, 902 "QS" => 10, 903 "RT" => 1, 904 ... 905 }, 906 "NX" => %{"AG" => 9, "ES" => 5, "MO" => 3, "OC" => 3, "OR" => 6, "QJ" => 8, "QS" => 8, ...}, 907 "OP" => %{"AG" => 10, "ES" => 4, "MO" => 3, "OC" => 4, "OR" => 7, "QJ" => 9, ...}, 908 "TA" => %{"AG" => 9, "ES" => 5, "MO" => 3, "OC" => 1, "OR" => 6, ...}, 909 "IH" => %{"AG" => 7, "ES" => 9, "MO" => 4, "OC" => 6, ...}, 910 "HB" => %{"AG" => 3, "ES" => 10, "MO" => 6, ...}, 911 "PJ" => %{"AG" => 9, "ES" => 5, ...}, 912 "OQ" => %{"AG" => 4, ...}, 913 "NE" => %{...} 914} 915``` 916 917## Task 1 918 919```elixir 920defmodule Alone do 921 def visit(current, valves, paths, left, opened) when left >= 0 do 922 {left, rate, opened} = 923 case valves[current].rate do 924 0 -> {left, 0, opened} 925 other -> {left - 1, other, Map.put(opened, current, left - 1)} 926 end 927 928 rate = rate * left 929 930 paths[current] 931 |> Enum.map(fn 932 {next, weight} when weight + 1 < left and not is_map_key(opened, next) -> 933 {val, opened} = visit(next, valves, paths, left - weight, opened) 934 {val + rate, opened} 935 936 _ -> 937 {rate, opened} 938 end) 939 |> Enum.max_by(&elem(&1, 0)) 940 end 941end 942``` 943 944<!-- livebook:{"output":true} --> 945 946``` 947{:module, Valves, <<70, 79, 82, 49, 0, 0, 11, ...>>, {:visit, 5}} 948``` 949 950```elixir 951{t, v} = Alone.visit("AA", valves, paths, 30, %{}) 952``` 953 954<!-- livebook:{"output":true} --> 955 956``` 957{1820, %{"AG" => 6, "MO" => 23, "QJ" => 3, "QS" => 16, "TX" => 10, "UH" => 26, "YB" => 19}} 958``` 959 960## Task 2 961 962```elixir 963defmodule Alone do 964 def visit(current, valves, paths, left, opened) when left >= 0 do 965 {left, rate, opened} = 966 case valves[current].rate do 967 0 -> {left, 0, opened} 968 other -> {left - 1, other, Map.put(opened, current, left - 1)} 969 end 970 971 rate = rate * left 972 973 paths[current] 974 |> Enum.map(fn 975 {next, weight} when weight + 1 < left and not is_map_key(opened, next) -> 976 {val, opened} = visit(next, valves, paths, left - weight, opened) 977 {val + rate, opened} 978 979 _ -> 980 {rate, opened} 981 end) 982 |> Enum.max_by(&elem(&1, 0)) 983 end 984end 985```