this repo has no description

Update year 2022

hauleth.dev ef17f468 4d54275b

verified
+2 -8
2022/day01.livemd
···
```elixir
Mix.install([
-
{:kino_aoc, git: "https://github.com/ljgago/kino_aoc"}
+
{:kino_aoc, ">= 0.0.0"}
])
```
-
<!-- livebook:{"output":true} -->
-
-
```
-
:ok
-
```
-
## Setup
-
<!-- livebook:{"attrs":{"day":"1","session_secret":"ADVENT_OF_CODE_SESSION","variable":"puzzle_input","year":"2022"},"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
<!-- livebook:{"attrs":{"day":"1","session_secret":"ADVENT_OF_CODE_SESSION","variable":"puzzle_input","year":"2022"},"chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
```elixir
{:ok, puzzle_input} =
+1 -1
2022/day06.livemd
···
## Section
-
<!-- livebook:{"attrs":{"day":"6","session_secret":"ADVENT_OF_CODE_SESSION","variable":"puzzle_input","year":"2022"},"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
<!-- livebook:{"attrs":{"day":"6","session_secret":"ADVENT_OF_CODE_SESSION","variable":"puzzle_input","year":"2022"},"chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
```elixir
{:ok, puzzle_input} =
+1 -1
2022/day07.livemd
···
## Section
-
<!-- livebook:{"attrs":{"day":"7","session_secret":"ADVENT_OF_CODE_SESSION","variable":"puzzle_input","year":"2022"},"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
<!-- livebook:{"attrs":{"day":"7","session_secret":"ADVENT_OF_CODE_SESSION","variable":"puzzle_input","year":"2022"},"chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
```elixir
{:ok, puzzle_input} =
+1 -1
2022/day08.livemd
···
## Section
-
<!-- livebook:{"attrs":{"day":"8","session_secret":"ADVENT_OF_CODE_SESSION","variable":"puzzle_input","year":"2022"},"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
<!-- livebook:{"attrs":{"day":"8","session_secret":"ADVENT_OF_CODE_SESSION","variable":"puzzle_input","year":"2022"},"chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
```elixir
{:ok, puzzle_input} =
+1 -1
2022/day09.livemd
···
## Setup
-
<!-- livebook:{"attrs":{"day":"9","session_secret":"ADVENT_OF_CODE_SESSION","variable":"puzzle_input","year":"2022"},"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
<!-- livebook:{"attrs":{"day":"9","session_secret":"ADVENT_OF_CODE_SESSION","variable":"puzzle_input","year":"2022"},"chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
```elixir
{:ok, puzzle_input} =
+1 -1
2022/day10.livemd
···
## Section
-
<!-- livebook:{"attrs":{"day":"10","session_secret":"ADVENT_OF_CODE_SESSION","variable":"puzzle_input","year":"2022"},"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
<!-- livebook:{"attrs":{"day":"10","session_secret":"ADVENT_OF_CODE_SESSION","variable":"puzzle_input","year":"2022"},"chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
```elixir
{:ok, puzzle_input} =
+1 -1
2022/day11.livemd
···
## Section
-
<!-- livebook:{"attrs":{"day":"11","session_secret":"ADVENT_OF_CODE_SESSION","variable":"puzzle_input","year":"2022"},"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
<!-- livebook:{"attrs":{"day":"11","session_secret":"ADVENT_OF_CODE_SESSION","variable":"puzzle_input","year":"2022"},"chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
```elixir
{:ok, puzzle_input} =
+1 -1
2022/day12.livemd
···
## Section
-
<!-- livebook:{"attrs":{"day":"12","session_secret":"ADVENT_OF_CODE_SESSION","variable":"puzzle_input","year":"2022"},"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
<!-- livebook:{"attrs":{"day":"12","session_secret":"ADVENT_OF_CODE_SESSION","variable":"puzzle_input","year":"2022"},"chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
```elixir
{:ok, puzzle_input} =
+1 -1
2022/day13.livemd
···
## Section
-
<!-- livebook:{"attrs":{"day":"13","session_secret":"ADVENT_OF_CODE_SESSION","variable":"puzzle_input","year":"2022"},"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
<!-- livebook:{"attrs":{"day":"13","session_secret":"ADVENT_OF_CODE_SESSION","variable":"puzzle_input","year":"2022"},"chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
```elixir
{:ok, puzzle_input} =
+92 -56
2022/day14.livemd
···
],
consolidate_protocols: false
)
+
+
# defimpl Kino.Render, for: Vix.Vips.Image do
+
# alias Vix.Vips.Image, as: VImg
+
+
# def to_livebook(image) do
+
# format = "png"
+
+
# {:ok, image_bin} = VImg.write_to_buffer(image, ".#{format}")
+
# Kino.Output.image(image_bin, "image/#{format}")
+
# end
+
# end
```
<!-- livebook:{"output":true} -->
···
## Setup
-
<!-- livebook:{"attrs":{"day":"14","session_secret":"ADVENT_OF_CODE_SESSION","variable":"puzzle_input","year":"2022"},"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
<!-- livebook:{"attrs":{"day":"14","session_secret":"ADVENT_OF_CODE_SESSION","variable":"puzzle_input","year":"2022"},"chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
```elixir
{:ok, puzzle_input} =
···
```elixir
defmodule Cave do
-
defstruct map: MapSet.new(), occupied: MapSet.new(), width: nil, height: 0, start: {500, 0}
+
defstruct map: %{}, width: nil, height: 0, start: {500, 0}
def parse(input, start \\ {500, 0}) do
map =
input
|> String.split("\n", trim: true)
|> Enum.map(&Cave.parse_line/1)
-
|> Enum.reduce(&MapSet.union/2)
+
|> Enum.reduce(&Map.merge/2)
{width, height} =
-
for {x, y} <- map,
+
for {{x, y}, _} <- map,
reduce: {nil, nil} do
{nil, nil} ->
{x..x, y}
···
{min(min_x, x)..max(max_x, x), max(max_y, y)}
end
-
%__MODULE__{map: map, occupied: map, start: start, width: width, height: height}
-
end
-
-
def add_line(%__MODULE__{} = cave, line) do
-
{width, height} =
-
Enum.reduce(line, {cave.width, cave.height}, fn {x, y}, {x0..x1, h} ->
-
{min(x, x0)..max(x, x1), max(y, h)}
-
end)
-
-
struct(cave,
-
width: width,
-
height: height,
-
map: MapSet.union(cave.map, line),
-
occupied: MapSet.union(cave.occupied, line)
-
)
+
%__MODULE__{map: map, start: start, width: width, height: height}
end
def parse_point(str) do
···
[{x1, y}, {x2, y}] ->
for x <- x1..x2, do: {x, y}
end)
-
|> MapSet.new()
+
|> Map.new(&{&1, :rock})
points
end
def drop_sand(%__MODULE__{} = cave), do: drop_sand(cave, cave.start)
-
def drop_sand(%__MODULE__{height: h, width: x0..x1} = cave, {sx, sy})
-
when sx not in x0..x1 or sy >= h,
-
do: {:fall_out, cave}
+
def drop_sand(%__MODULE__{height: h} = cave, {_, sy} = p)
+
when sy >= h,
+
do: {p, struct(cave, map: Map.put(cave.map, p, :sand))}
-
def drop_sand(%__MODULE__{} = cave, {sx, sy}) do
+
def drop_sand(%__MODULE__{map: map} = cave, {sx, sy} = p) do
cond do
-
{sx, sy + 1} not in cave.occupied -> drop_sand(cave, {sx, sy + 1})
-
{sx - 1, sy + 1} not in cave.occupied -> drop_sand(cave, {sx - 1, sy + 1})
-
{sx + 1, sy + 1} not in cave.occupied -> drop_sand(cave, {sx + 1, sy + 1})
-
true -> {{sx, sy}, struct(cave, occupied: MapSet.put(cave.occupied, {sx, sy}))}
+
not Map.has_key?(map, {sx, sy + 1}) -> drop_sand(cave, {sx, sy + 1})
+
not Map.has_key?(map, {sx - 1, sy + 1}) -> drop_sand(cave, {sx - 1, sy + 1})
+
not Map.has_key?(map, {sx + 1, sy + 1}) -> drop_sand(cave, {sx + 1, sy + 1})
+
true -> {p, struct(cave, map: Map.put(cave.map, p, :sand))}
end
end
-
end
-
defimpl Kino.Render, for: Cave do
-
def to_livebook(%@for{} = cave) do
-
x0..x1 = cave.width
+
def to_image(%__MODULE__{} = cave) do
+
{{{x0, _}, _}, {{x1, _}, _}} = Enum.min_max_by(cave.map, fn {{x, _}, _} -> x end)
{sx, sy} = cave.start
image = Image.new!(x1 - x0 + 3, cave.height + 3)
···
Image.mutate(image, fn im ->
Image.Draw.point(im, sx - x0 + 1, sy + 1, color: :red)
-
for {x, y} <- cave.occupied do
-
Image.Draw.point(im, x - x0 + 1, y + 1, color: :tan)
-
end
-
-
for {x, y} <- cave.map do
-
Image.Draw.point(im, x - x0 + 1, y + 1, color: :white)
-
end
+
cave.map
+
|> Enum.sort()
+
|> Enum.each(fn {{x, y}, type} ->
+
case type do
+
:rock -> Image.Draw.point(im, x - x0 + 1, y + 1, color: :white)
+
:sand -> Image.Draw.point(im, x - x0 + 1, y + 1, color: :tan)
+
end
+
end)
:ok
end)
-
buf =
-
image
-
|> Image.resize!(4, interpolate: :nearest)
-
|> Image.write!(:memory, suffix: ".png")
+
image
+
end
+
end
-
Kino.Output.image(buf, "image/png")
+
defimpl Kino.Render, for: Cave do
+
def to_livebook(%@for{} = cave) do
+
cave
+
|> @for.to_image()
+
|> Image.resize!(4, interpolate: :nearest)
+
|> Kino.Render.to_livebook()
end
end
```
···
<!-- livebook:{"output":true} -->
```
-
{:module, Kino.Render.Cave, <<70, 79, 82, 49, 0, 0, 16, ...>>, {:to_livebook, 1}}
+
{:module, Kino.Render.Cave, <<70, 79, 82, 49, 0, 0, 9, ...>>, {:to_livebook, 1}}
```
```elixir
cave = Cave.parse(puzzle_input)
+
+
floor = cave.height + 1
+
+
cave = struct(cave, height: floor)
```
## Task 1
```elixir
-
Stream.unfold(cave, &Cave.drop_sand/1)
-
|> Enum.take_while(&(&1 != :fall_out))
-
|> length()
+
frame = Kino.Frame.new() |> Kino.render()
+
+
image = Cave.to_image(cave)
+
+
cave
+
|> Stream.unfold(fn cave ->
+
{_, new_cave} = ret = Cave.drop_sand(cave)
+
+
{ret, new_cave}
+
end)
+
|> Enum.reduce_while(0, fn {{_x, y}, cave}, acc ->
+
if y < cave.height do
+
{:cont, acc + 1}
+
else
+
Kino.Frame.render(frame, Image.resize!(Cave.to_image(cave), 4, interpolate: :nearest))
+
{:halt, acc}
+
end
+
end)
```
<!-- livebook:{"output":true} -->
···
## Task 2
```elixir
-
floor_y = cave.height + 2
+
{grains, pyramid} =
+
Stream.unfold(cave, fn cave ->
+
{_, new_cave} = ret = Cave.drop_sand(cave)
+
+
{ret, new_cave}
+
end)
+
|> Enum.reduce_while(0, fn {p, cave}, acc ->
+
if p != {500, 0} do
+
{:cont, acc + 1}
+
else
+
{:halt, {acc + 1, cave}}
+
end
+
end)
+
+
grains
+
```
-
floor = for x <- 0..(cave.width.last * 2), into: MapSet.new(), do: {x, floor_y}
+
<!-- livebook:{"output":true} -->
-
cave = Cave.add_line(cave, floor)
+
```
+
26686
+
```
-
Stream.unfold(cave, &Cave.drop_sand/1)
-
|> Enum.take_while(&(&1 != cave.start))
-
|> length()
-
|> then(&(&1 + 1))
+
```elixir
+
Kino.render(pyramid)
+
+
:ok
```
<!-- livebook:{"output":true} -->
```
-
26686
+
:ok
```
+25 -5
2022/day15.livemd
···
## Section
-
<!-- livebook:{"attrs":{"day":"15","session_secret":"ADVENT_OF_CODE_SESSION","variable":"puzzle_input","year":"2022"},"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
<!-- livebook:{"attrs":{"day":"15","session_secret":"ADVENT_OF_CODE_SESSION","variable":"puzzle_input","year":"2022"},"chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
```elixir
{:ok, puzzle_input} =
···
a
end
+
def continuous?(%__MODULE__{ranges: []}), do: true
+
def continuous?(%__MODULE__{ranges: [_]}), do: true
+
def continuous?(%__MODULE__{ranges: _}), do: false
+
+
def gaps(%__MODULE__{ranges: []} = set), do: set
+
def gaps(%__MODULE__{ranges: [_]}), do: %__MODULE__{ranges: []}
+
def gaps(%__MODULE__{ranges: ranges}) do
gaps =
ranges
···
<!-- livebook:{"output":true} -->
```
-
{:module, RangeSet, <<70, 79, 82, 49, 0, 0, 37, ...>>, {:squash, 1}}
+
{:module, RangeSet, <<70, 79, 82, 49, 0, 0, 39, ...>>, {:squash, 1}}
```
```elixir
···
circles
|> Beacons.covered_at_line(a_y)
+
|> IO.inspect()
|> RangeSet.remove(beacons_at_line)
|> RangeSet.length()
```
···
<!-- livebook:{"output":true} -->
```
+
%RangeSet{ranges: [-101830..5006266]}
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
5108096
```
···
|> Enum.find_value(fn y ->
covered = Beacons.covered_at_line(circles, y)
-
gaps = RangeSet.gaps(covered)
-
-
if not RangeSet.empty?(gaps) do
+
if not RangeSet.continuous?(covered) do
+
gaps = RangeSet.gaps(covered)
{y, RangeSet.to_list(gaps)}
end
end)
+
|> Kino.render()
x * 4_000_000 + y
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{2650264, [2638485]}
```
<!-- livebook:{"output":true} -->
+985
2022/day16.livemd
···
+
<!-- livebook:{"persist_outputs":true} -->
+
+
# Day 16
+
+
```elixir
+
Mix.install([
+
{:kino_aoc, git: "https://github.com/ljgago/kino_aoc"},
+
{:libgraph, github: "hauleth/libgraph", ref: "perf/bellman-ford-implementation"}
+
])
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
:ok
+
```
+
+
## Setup
+
+
<!-- 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"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2022", "16", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:ok,
+
"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"}
+
```
+
+
```elixir
+
# puzzle_input = """
+
# Valve AA has flow rate=0; tunnels lead to valves DD, II, BB
+
# Valve BB has flow rate=13; tunnels lead to valves CC, AA
+
# Valve CC has flow rate=2; tunnels lead to valves DD, BB
+
# Valve DD has flow rate=20; tunnels lead to valves CC, AA, EE
+
# Valve EE has flow rate=3; tunnels lead to valves FF, DD
+
# Valve FF has flow rate=0; tunnels lead to valves EE, GG
+
# Valve GG has flow rate=0; tunnels lead to valves FF, HH
+
# Valve HH has flow rate=22; tunnel leads to valve GG
+
# Valve II has flow rate=0; tunnels lead to valves AA, JJ
+
# Valve JJ has flow rate=21; tunnel leads to valve II
+
# """
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
nil
+
```
+
+
```elixir
+
{{start, _}, valves} =
+
valves =
+
puzzle_input
+
|> String.split("\n", trim: true)
+
|> Kino.render()
+
|> Enum.map(fn line ->
+
%{
+
"name" => name,
+
"rate" => rate,
+
"routes" => routes
+
} =
+
Regex.named_captures(
+
~r/Valve (?<name>..).*rate=(?<rate>\d+);.*valves? (?<routes>.*)$/,
+
line
+
)
+
+
{name, %{rate: String.to_integer(rate), routes: String.split(routes, ~r/,\s*/, trim: true)}}
+
end)
+
|> then(&{hd(&1), Map.new(&1)})
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
["Valve QJ has flow rate=11; tunnels lead to valves HB, GL",
+
"Valve VZ has flow rate=10; tunnel leads to valve NE",
+
"Valve TX has flow rate=19; tunnels lead to valves MG, OQ, HM",
+
"Valve ZI has flow rate=5; tunnels lead to valves BY, ON, RU, LF, JR",
+
"Valve IH has flow rate=0; tunnels lead to valves YB, QS",
+
"Valve QS has flow rate=22; tunnel leads to valve IH",
+
"Valve QB has flow rate=0; tunnels lead to valves QX, ES",
+
"Valve NX has flow rate=0; tunnels lead to valves UH, OP",
+
"Valve PJ has flow rate=0; tunnels lead to valves OC, UH",
+
"Valve OR has flow rate=6; tunnels lead to valves QH, BH, HB, JD",
+
"Valve OC has flow rate=7; tunnels lead to valves IZ, JR, TA, ZH, PJ",
+
"Valve UC has flow rate=0; tunnels lead to valves AA, BY",
+
"Valve QX has flow rate=0; tunnels lead to valves AA, QB",
+
"Valve IZ has flow rate=0; tunnels lead to valves OC, SX",
+
"Valve AG has flow rate=13; tunnels lead to valves NW, GL, SM",
+
"Valve ON has flow rate=0; tunnels lead to valves MO, ZI",
+
"Valve XT has flow rate=18; tunnels lead to valves QZ, PG",
+
"Valve AX has flow rate=0; tunnels lead to valves UH, MO",
+
"Valve JD has flow rate=0; tunnels lead to valves OR, SM",
+
"Valve HM has flow rate=0; tunnels lead to valves TX, QH",
+
"Valve LF has flow rate=0; tunnels lead to valves ZI, UH",
+
"Valve QH has flow rate=0; tunnels lead to valves OR, HM",
+
"Valve RT has flow rate=21; tunnel leads to valve PG",
+
"Valve NE has flow rate=0; tunnels lead to valves VZ, TA",
+
"Valve OQ has flow rate=0; tunnels lead to valves TX, GE",
+
"Valve AA has flow rate=0; tunnels lead to valves QZ, UC, OP, QX, EH",
+
"Valve UH has flow rate=17; tunnels lead to valves PJ, NX, AX, LF",
+
"Valve GE has flow rate=0; tunnels lead to valves YB, OQ",
+
"Valve EH has flow rate=0; tunnels lead to valves AA, MO",
+
"Valve MG has flow rate=0; tunnels lead to valves TX, NW",
+
"Valve YB has flow rate=20; tunnels lead to valves IH, GE, XG",
+
"Valve MO has flow rate=15; tunnels lead to valves EH, ON, AX, ZH, CB",
+
"Valve JR has flow rate=0; tunnels lead to valves ZI, OC",
+
"Valve GL has flow rate=0; tunnels lead to valves AG, QJ",
+
"Valve SM has flow rate=0; tunnels lead to valves JD, AG",
+
"Valve HB has flow rate=0; tunnels lead to valves OR, QJ",
+
"Valve TA has flow rate=0; tunnels lead to valves OC, NE",
+
"Valve PG has flow rate=0; tunnels lead to valves RT, XT",
+
"Valve XG has flow rate=0; tunnels lead to valves CB, YB",
+
"Valve ES has flow rate=9; tunnels lead to valves QB, FL",
+
"Valve BH has flow rate=0; tunnels lead to valves RU, OR",
+
"Valve FL has flow rate=0; tunnels lead to valves SX, ES",
+
"Valve CB has flow rate=0; tunnels lead to valves MO, XG",
+
"Valve QZ has flow rate=0; tunnels lead to valves AA, XT",
+
"Valve BY has flow rate=0; tunnels lead to valves UC, ZI",
+
"Valve ZH has flow rate=0; tunnels lead to valves MO, OC",
+
"Valve OP has flow rate=0; tunnels lead to valves NX, AA",
+
"Valve NW has flow rate=0; tunnels lead to valves MG, AG",
+
"Valve RU has flow rate=0; tunnels lead to valves ZI, BH",
+
"Valve SX has flow rate=16; tunnels lead to valves IZ, FL"]
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{{"QJ", %{rate: 11, routes: ["HB", "GL"]}},
+
%{
+
"CB" => %{rate: 0, routes: ["MO", "XG"]},
+
"EH" => %{rate: 0, routes: ["AA", "MO"]},
+
"YB" => %{rate: 20, routes: ["IH", "GE", "XG"]},
+
"ON" => %{rate: 0, routes: ["MO", "ZI"]},
+
"ES" => %{rate: 9, routes: ["QB", "FL"]},
+
"XG" => %{rate: 0, routes: ["CB", "YB"]},
+
"TX" => %{rate: 19, routes: ["MG", "OQ", "HM"]},
+
"RT" => %{rate: 21, routes: ["PG"]},
+
"GL" => %{rate: 0, routes: ["AG", "QJ"]},
+
"XT" => %{rate: 18, routes: ["QZ", "PG"]},
+
"BY" => %{rate: 0, routes: ["UC", "ZI"]},
+
"QJ" => %{rate: 11, routes: ["HB", "GL"]},
+
"QB" => %{rate: 0, routes: ["QX", "ES"]},
+
"QH" => %{rate: 0, routes: ["OR", "HM"]},
+
"SX" => %{rate: 16, routes: ["IZ", "FL"]},
+
"ZI" => %{rate: 5, routes: ["BY", "ON", "RU", "LF", "JR"]},
+
"OC" => %{rate: 7, routes: ["IZ", "JR", "TA", "ZH", "PJ"]},
+
"NW" => %{rate: 0, routes: ["MG", "AG"]},
+
"UH" => %{rate: 17, routes: ["PJ", "NX", "AX", "LF"]},
+
"VZ" => %{rate: 10, routes: ["NE"]},
+
"MO" => %{rate: 15, routes: ["EH", "ON", "AX", "ZH", "CB"]},
+
"ZH" => %{rate: 0, routes: ["MO", "OC"]},
+
"RU" => %{rate: 0, routes: ["ZI", "BH"]},
+
"FL" => %{rate: 0, routes: ["SX", "ES"]},
+
"SM" => %{rate: 0, routes: ["JD", "AG"]},
+
"AA" => %{rate: 0, routes: ["QZ", "UC", "OP", "QX", "EH"]},
+
"JR" => %{rate: 0, routes: ["ZI", "OC"]},
+
"QS" => %{rate: 22, routes: ["IH"]},
+
"AG" => %{rate: 13, routes: ["NW", "GL", "SM"]},
+
"JD" => %{rate: 0, routes: ["OR", "SM"]},
+
"QZ" => %{rate: 0, routes: ["AA", "XT"]},
+
"MG" => %{rate: 0, routes: ["TX", "NW"]},
+
"UC" => %{rate: 0, routes: ["AA", "BY"]},
+
"AX" => %{rate: 0, routes: ["UH", "MO"]},
+
"HM" => %{rate: 0, routes: ["TX", "QH"]},
+
"LF" => %{rate: 0, routes: ["ZI", "UH"]},
+
"BH" => %{rate: 0, routes: ["RU", "OR"]},
+
"OR" => %{rate: 6, routes: ["QH", "BH", "HB", "JD"]},
+
"GE" => %{rate: 0, routes: ["YB", "OQ"]},
+
"QX" => %{rate: 0, routes: ["AA", "QB"]},
+
"IZ" => %{rate: 0, routes: ["OC", "SX"]},
+
"PG" => %{rate: 0, routes: ["RT", "XT"]},
+
"NX" => %{rate: 0, routes: ["UH", "OP"]},
+
"OP" => %{rate: 0, routes: ["NX", "AA"]},
+
"TA" => %{rate: 0, routes: ["OC", ...]},
+
"IH" => %{rate: 0, routes: [...]},
+
"HB" => %{rate: 0, ...},
+
"PJ" => %{...},
+
...
+
}}
+
```
+
+
```elixir
+
graph = Graph.new(type: :directed)
+
+
edges =
+
Enum.flat_map(valves, fn {a, %{routes: routes}} ->
+
for b <- routes, p <- [{a, b, weight: 1}, {b, a, weight: 1}], do: p
+
end)
+
+
graph =
+
Graph.add_edges(graph, edges)
+
|> Kino.render()
+
+
paths =
+
for v <- Graph.vertices(graph), into: %{} do
+
routes =
+
graph
+
|> Graph.bellman_ford(v)
+
|> Enum.filter(fn {k, _} -> valves[k].rate > 0 and k != v end)
+
|> Map.new()
+
+
{v, routes}
+
end
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
#Graph<type: directed, vertices: ["LF", "CB", "AX", "ZI", "ZH", "VZ", "AA", "UH", "OC", "IH", "FL",
+
"JR", "QB", "EH", "QH", "ON", "TA", "PJ", "SX", "YB", "UC", "BH", "MO", "OQ", "HM", "JD", "OR",
+
"NE", "QS", "XT", "IZ", "QZ", "BY", "PG", "NW", "HB", "AG", "QJ", "RT", "TX", "GE", "QX", "XG",
+
"NX", "GL", "RU", "SM", "ES", "MG",
+
"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"]>
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
%{
+
"CB" => %{
+
"AG" => 8,
+
"ES" => 6,
+
"MO" => 1,
+
"OC" => 3,
+
"OR" => 6,
+
"QJ" => 8,
+
"QS" => 4,
+
"RT" => 7,
+
"SX" => 5,
+
"TX" => 5,
+
"UH" => 3,
+
"VZ" => 6,
+
"XT" => 5,
+
"YB" => 2,
+
"ZI" => 3
+
},
+
"EH" => %{
+
"AG" => 9,
+
"ES" => 4,
+
"MO" => 1,
+
"OC" => 3,
+
"OR" => 6,
+
"QJ" => 8,
+
"QS" => 6,
+
"RT" => 5,
+
"SX" => 5,
+
"TX" => 7,
+
"UH" => 3,
+
"VZ" => 6,
+
"XT" => 3,
+
"YB" => 4,
+
"ZI" => 3
+
},
+
"YB" => %{
+
"AG" => 6,
+
"ES" => 8,
+
"MO" => 3,
+
"OC" => 5,
+
"OR" => 6,
+
"QJ" => 8,
+
"QS" => 2,
+
"RT" => 9,
+
"SX" => 7,
+
"TX" => 3,
+
"UH" => 5,
+
"VZ" => 8,
+
"XT" => 7,
+
"ZI" => 5
+
},
+
"ON" => %{
+
"AG" => 7,
+
"ES" => 6,
+
"MO" => 1,
+
"OC" => 3,
+
"OR" => 4,
+
"QJ" => 6,
+
"QS" => 6,
+
"RT" => 7,
+
"SX" => 5,
+
"TX" => 7,
+
"UH" => 3,
+
"VZ" => 6,
+
"XT" => 5,
+
"YB" => 4,
+
"ZI" => 1
+
},
+
"ES" => %{
+
"AG" => 12,
+
"MO" => 5,
+
"OC" => 4,
+
"OR" => 9,
+
"QJ" => 11,
+
"QS" => 10,
+
"RT" => 7,
+
"SX" => 2,
+
"TX" => 11,
+
"UH" => 6,
+
"VZ" => 7,
+
"XT" => 5,
+
"YB" => 8,
+
"ZI" => 6
+
},
+
"XG" => %{
+
"AG" => 7,
+
"ES" => 7,
+
"MO" => 2,
+
"OC" => 4,
+
"OR" => 7,
+
"QJ" => 9,
+
"QS" => 3,
+
"RT" => 8,
+
"SX" => 6,
+
"TX" => 4,
+
"UH" => 4,
+
"VZ" => 7,
+
"XT" => 6,
+
"YB" => 1,
+
"ZI" => 4
+
},
+
"TX" => %{
+
"AG" => 3,
+
"ES" => 11,
+
"MO" => 6,
+
"OC" => 8,
+
"OR" => 3,
+
"QJ" => 5,
+
"QS" => 5,
+
"RT" => 12,
+
"SX" => 10,
+
"UH" => 8,
+
"VZ" => 11,
+
"XT" => 10,
+
"YB" => 3,
+
"ZI" => 6
+
},
+
"RT" => %{
+
"AG" => 13,
+
"ES" => 7,
+
"MO" => 6,
+
"OC" => 8,
+
"OR" => 10,
+
"QJ" => 12,
+
"QS" => 11,
+
"SX" => 9,
+
"TX" => 12,
+
"UH" => 7,
+
"VZ" => 11,
+
"XT" => 2,
+
"YB" => 9,
+
"ZI" => 7
+
},
+
"GL" => %{
+
"AG" => 1,
+
"ES" => 12,
+
"MO" => 8,
+
"OC" => 8,
+
"OR" => 3,
+
"QJ" => 1,
+
"QS" => 9,
+
"RT" => 13,
+
"SX" => 10,
+
"TX" => 4,
+
"UH" => 8,
+
"VZ" => 11,
+
"XT" => 11,
+
"YB" => 7,
+
"ZI" => 6
+
},
+
"XT" => %{
+
"AG" => 11,
+
"ES" => 5,
+
"MO" => 4,
+
"OC" => 6,
+
"OR" => 8,
+
"QJ" => 10,
+
"QS" => 9,
+
"RT" => 2,
+
"SX" => 7,
+
"TX" => 10,
+
"UH" => 5,
+
"VZ" => 9,
+
"YB" => 7,
+
"ZI" => 5
+
},
+
"BY" => %{
+
"AG" => 7,
+
"ES" => 5,
+
"MO" => 3,
+
"OC" => 3,
+
"OR" => 4,
+
"QJ" => 6,
+
"QS" => 8,
+
"RT" => 6,
+
"SX" => 5,
+
"TX" => 7,
+
"UH" => 3,
+
"VZ" => 6,
+
"XT" => 4,
+
"YB" => 6,
+
"ZI" => 1
+
},
+
"QJ" => %{
+
"AG" => 2,
+
"ES" => 11,
+
"MO" => 7,
+
"OC" => 7,
+
"OR" => 2,
+
"QS" => 10,
+
"RT" => 12,
+
"SX" => 9,
+
"TX" => 5,
+
"UH" => 7,
+
"VZ" => 10,
+
"XT" => 10,
+
"YB" => 8,
+
"ZI" => 5
+
},
+
"QB" => %{
+
"AG" => 11,
+
"ES" => 1,
+
"MO" => 4,
+
"OC" => 5,
+
"OR" => 8,
+
"QJ" => 10,
+
"QS" => 9,
+
"RT" => 6,
+
"SX" => 3,
+
"TX" => 10,
+
"UH" => 5,
+
"VZ" => 8,
+
"XT" => 4,
+
"YB" => 7,
+
"ZI" => 5
+
},
+
"QH" => %{
+
"AG" => 4,
+
"ES" => 10,
+
"MO" => 6,
+
"OC" => 6,
+
"OR" => 1,
+
"QJ" => 3,
+
"QS" => 7,
+
"RT" => 11,
+
"SX" => 8,
+
"TX" => 2,
+
"UH" => 6,
+
"VZ" => 9,
+
"XT" => 9,
+
"YB" => 5,
+
"ZI" => 4
+
},
+
"SX" => %{
+
"AG" => 10,
+
"ES" => 2,
+
"MO" => 4,
+
"OC" => 2,
+
"OR" => 7,
+
"QJ" => 9,
+
"QS" => 9,
+
"RT" => 9,
+
"TX" => 10,
+
"UH" => 4,
+
"VZ" => 5,
+
"XT" => 7,
+
"YB" => 7,
+
"ZI" => 4
+
},
+
"ZI" => %{
+
"AG" => 6,
+
"ES" => 6,
+
"MO" => 2,
+
"OC" => 2,
+
"OR" => 3,
+
"QJ" => 5,
+
"QS" => 7,
+
"RT" => 7,
+
"SX" => 4,
+
"TX" => 6,
+
"UH" => 2,
+
"VZ" => 5,
+
"XT" => 5,
+
"YB" => 5
+
},
+
"OC" => %{
+
"AG" => 8,
+
"ES" => 4,
+
"MO" => 2,
+
"OR" => 5,
+
"QJ" => 7,
+
"QS" => 7,
+
"RT" => 8,
+
"SX" => 2,
+
"TX" => 8,
+
"UH" => 2,
+
"VZ" => 3,
+
"XT" => 6,
+
"YB" => 5,
+
"ZI" => 2
+
},
+
"NW" => %{
+
"AG" => 1,
+
"ES" => 13,
+
"MO" => 8,
+
"OC" => 9,
+
"OR" => 4,
+
"QJ" => 3,
+
"QS" => 7,
+
"RT" => 14,
+
"SX" => 11,
+
"TX" => 2,
+
"UH" => 9,
+
"VZ" => 12,
+
"XT" => 12,
+
"YB" => 5,
+
"ZI" => 7
+
},
+
"UH" => %{
+
"AG" => 8,
+
"ES" => 6,
+
"MO" => 2,
+
"OC" => 2,
+
"OR" => 5,
+
"QJ" => 7,
+
"QS" => 7,
+
"RT" => 7,
+
"SX" => 4,
+
"TX" => 8,
+
"VZ" => 5,
+
"XT" => 5,
+
"YB" => 5,
+
"ZI" => 2
+
},
+
"VZ" => %{
+
"AG" => 11,
+
"ES" => 7,
+
"MO" => 5,
+
"OC" => 3,
+
"OR" => 8,
+
"QJ" => 10,
+
"QS" => 10,
+
"RT" => 11,
+
"SX" => 5,
+
"TX" => 11,
+
"UH" => 5,
+
"XT" => 9,
+
"YB" => 8,
+
"ZI" => 5
+
},
+
"MO" => %{
+
"AG" => 8,
+
"ES" => 5,
+
"OC" => 2,
+
"OR" => 5,
+
"QJ" => 7,
+
"QS" => 5,
+
"RT" => 6,
+
"SX" => 4,
+
"TX" => 6,
+
"UH" => 2,
+
"VZ" => 5,
+
"XT" => 4,
+
"YB" => 3,
+
"ZI" => 2
+
},
+
"ZH" => %{
+
"AG" => 9,
+
"ES" => 5,
+
"MO" => 1,
+
"OC" => 1,
+
"OR" => 6,
+
"QJ" => 8,
+
"QS" => 6,
+
"RT" => 7,
+
"SX" => 3,
+
"TX" => 7,
+
"UH" => 3,
+
"VZ" => 4,
+
"XT" => 5,
+
"YB" => 4,
+
"ZI" => 3
+
},
+
"RU" => %{
+
"AG" => 5,
+
"ES" => 7,
+
"MO" => 3,
+
"OC" => 3,
+
"OR" => 2,
+
"QJ" => 4,
+
"QS" => 8,
+
"RT" => 8,
+
"SX" => 5,
+
"TX" => 5,
+
"UH" => 3,
+
"VZ" => 6,
+
"XT" => 6,
+
"YB" => 6,
+
"ZI" => 1
+
},
+
"FL" => %{
+
"AG" => 11,
+
"ES" => 1,
+
"MO" => 5,
+
"OC" => 3,
+
"OR" => 8,
+
"QJ" => 10,
+
"QS" => 10,
+
"RT" => 8,
+
"SX" => 1,
+
"TX" => 11,
+
"UH" => 5,
+
"VZ" => 6,
+
"XT" => 6,
+
"YB" => 8,
+
"ZI" => 5
+
},
+
"SM" => %{
+
"AG" => 1,
+
"ES" => 11,
+
"MO" => 7,
+
"OC" => 7,
+
"OR" => 2,
+
"QJ" => 3,
+
"QS" => 9,
+
"RT" => 12,
+
"SX" => 9,
+
"TX" => 4,
+
"UH" => 7,
+
"VZ" => 10,
+
"XT" => 10,
+
"YB" => 7,
+
"ZI" => 5
+
},
+
"AA" => %{
+
"AG" => 9,
+
"ES" => 3,
+
"MO" => 2,
+
"OC" => 4,
+
"OR" => 6,
+
"QJ" => 8,
+
"QS" => 7,
+
"RT" => 4,
+
"SX" => 5,
+
"TX" => 8,
+
"UH" => 3,
+
"VZ" => 7,
+
"XT" => 2,
+
"YB" => 5,
+
"ZI" => 3
+
},
+
"JR" => %{
+
"AG" => 7,
+
"ES" => 5,
+
"MO" => 3,
+
"OC" => 1,
+
"OR" => 4,
+
"QJ" => 6,
+
"QS" => 8,
+
"RT" => 8,
+
"SX" => 3,
+
"TX" => 7,
+
"UH" => 3,
+
"VZ" => 4,
+
"XT" => 6,
+
"YB" => 6,
+
"ZI" => 1
+
},
+
"QS" => %{
+
"AG" => 8,
+
"ES" => 10,
+
"MO" => 5,
+
"OC" => 7,
+
"OR" => 8,
+
"QJ" => 10,
+
"RT" => 11,
+
"SX" => 9,
+
"TX" => 5,
+
"UH" => 7,
+
"VZ" => 10,
+
"XT" => 9,
+
"YB" => 2,
+
"ZI" => 7
+
},
+
"AG" => %{
+
"ES" => 12,
+
"MO" => 8,
+
"OC" => 8,
+
"OR" => 3,
+
"QJ" => 2,
+
"QS" => 8,
+
"RT" => 13,
+
"SX" => 10,
+
"TX" => 3,
+
"UH" => 8,
+
"VZ" => 11,
+
"XT" => 11,
+
"YB" => 6,
+
"ZI" => 6
+
},
+
"JD" => %{
+
"AG" => 2,
+
"ES" => 10,
+
"MO" => 6,
+
"OC" => 6,
+
"OR" => 1,
+
"QJ" => 3,
+
"QS" => 9,
+
"RT" => 11,
+
"SX" => 8,
+
"TX" => 4,
+
"UH" => 6,
+
"VZ" => 9,
+
"XT" => 9,
+
"YB" => 7,
+
"ZI" => 4
+
},
+
"QZ" => %{
+
"AG" => 10,
+
"ES" => 4,
+
"MO" => 3,
+
"OC" => 5,
+
"OR" => 7,
+
"QJ" => 9,
+
"QS" => 8,
+
"RT" => 3,
+
"SX" => 6,
+
"TX" => 9,
+
"UH" => 4,
+
"VZ" => 8,
+
"XT" => 1,
+
"YB" => 6,
+
"ZI" => 4
+
},
+
"MG" => %{
+
"AG" => 2,
+
"ES" => 12,
+
"MO" => 7,
+
"OC" => 9,
+
"OR" => 4,
+
"QJ" => 4,
+
"QS" => 6,
+
"RT" => 13,
+
"SX" => 11,
+
"TX" => 1,
+
"UH" => 9,
+
"VZ" => 12,
+
"XT" => 11,
+
"YB" => 4,
+
"ZI" => 7
+
},
+
"UC" => %{
+
"AG" => 8,
+
"ES" => 4,
+
"MO" => 3,
+
"OC" => 4,
+
"OR" => 5,
+
"QJ" => 7,
+
"QS" => 8,
+
"RT" => 5,
+
"SX" => 6,
+
"TX" => 8,
+
"UH" => 4,
+
"VZ" => 7,
+
"XT" => 3,
+
"YB" => 6,
+
"ZI" => 2
+
},
+
"AX" => %{
+
"AG" => 9,
+
"ES" => 6,
+
"MO" => 1,
+
"OC" => 3,
+
"OR" => 6,
+
"QJ" => 8,
+
"QS" => 6,
+
"RT" => 7,
+
"SX" => 5,
+
"TX" => 7,
+
"UH" => 1,
+
"VZ" => 6,
+
"XT" => 5,
+
"YB" => 4,
+
"ZI" => 3
+
},
+
"HM" => %{
+
"AG" => 4,
+
"ES" => 11,
+
"MO" => 7,
+
"OC" => 7,
+
"OR" => 2,
+
"QJ" => 4,
+
"QS" => 6,
+
"RT" => 12,
+
"SX" => 9,
+
"TX" => 1,
+
"UH" => 7,
+
"VZ" => 10,
+
"XT" => 10,
+
"YB" => 4,
+
"ZI" => 5
+
},
+
"LF" => %{
+
"AG" => 7,
+
"ES" => 7,
+
"MO" => 3,
+
"OC" => 3,
+
"OR" => 4,
+
"QJ" => 6,
+
"QS" => 8,
+
"RT" => 8,
+
"SX" => 5,
+
"TX" => 7,
+
"UH" => 1,
+
"VZ" => 6,
+
"XT" => 6,
+
"YB" => 6,
+
...
+
},
+
"BH" => %{
+
"AG" => 4,
+
"ES" => 8,
+
"MO" => 4,
+
"OC" => 4,
+
"OR" => 1,
+
"QJ" => 3,
+
"QS" => 9,
+
"RT" => 9,
+
"SX" => 6,
+
"TX" => 4,
+
"UH" => 4,
+
"VZ" => 7,
+
"XT" => 7,
+
...
+
},
+
"OR" => %{
+
"AG" => 3,
+
"ES" => 9,
+
"MO" => 5,
+
"OC" => 5,
+
"QJ" => 2,
+
"QS" => 8,
+
"RT" => 10,
+
"SX" => 7,
+
"TX" => 3,
+
"UH" => 5,
+
"VZ" => 8,
+
"XT" => 8,
+
...
+
},
+
"GE" => %{
+
"AG" => 5,
+
"ES" => 9,
+
"MO" => 4,
+
"OC" => 6,
+
"OR" => 5,
+
"QJ" => 7,
+
"QS" => 3,
+
"RT" => 10,
+
"SX" => 8,
+
"TX" => 2,
+
"UH" => 6,
+
...
+
},
+
"QX" => %{
+
"AG" => 10,
+
"ES" => 2,
+
"MO" => 3,
+
"OC" => 5,
+
"OR" => 7,
+
"QJ" => 9,
+
"QS" => 8,
+
"RT" => 5,
+
"SX" => 4,
+
"TX" => 9,
+
...
+
},
+
"IZ" => %{
+
"AG" => 9,
+
"ES" => 3,
+
"MO" => 3,
+
"OC" => 1,
+
"OR" => 6,
+
"QJ" => 8,
+
"QS" => 8,
+
"RT" => 9,
+
"SX" => 1,
+
...
+
},
+
"PG" => %{
+
"AG" => 12,
+
"ES" => 6,
+
"MO" => 5,
+
"OC" => 7,
+
"OR" => 9,
+
"QJ" => 11,
+
"QS" => 10,
+
"RT" => 1,
+
...
+
},
+
"NX" => %{"AG" => 9, "ES" => 5, "MO" => 3, "OC" => 3, "OR" => 6, "QJ" => 8, "QS" => 8, ...},
+
"OP" => %{"AG" => 10, "ES" => 4, "MO" => 3, "OC" => 4, "OR" => 7, "QJ" => 9, ...},
+
"TA" => %{"AG" => 9, "ES" => 5, "MO" => 3, "OC" => 1, "OR" => 6, ...},
+
"IH" => %{"AG" => 7, "ES" => 9, "MO" => 4, "OC" => 6, ...},
+
"HB" => %{"AG" => 3, "ES" => 10, "MO" => 6, ...},
+
"PJ" => %{"AG" => 9, "ES" => 5, ...},
+
"OQ" => %{"AG" => 4, ...},
+
"NE" => %{...}
+
}
+
```
+
+
## Task 1
+
+
```elixir
+
defmodule Alone do
+
def visit(current, valves, paths, left, opened) when left >= 0 do
+
{left, rate, opened} =
+
case valves[current].rate do
+
0 -> {left, 0, opened}
+
other -> {left - 1, other, Map.put(opened, current, left - 1)}
+
end
+
+
rate = rate * left
+
+
paths[current]
+
|> Enum.map(fn
+
{next, weight} when weight + 1 < left and not is_map_key(opened, next) ->
+
{val, opened} = visit(next, valves, paths, left - weight, opened)
+
{val + rate, opened}
+
+
_ ->
+
{rate, opened}
+
end)
+
|> Enum.max_by(&elem(&1, 0))
+
end
+
end
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:module, Valves, <<70, 79, 82, 49, 0, 0, 11, ...>>, {:visit, 5}}
+
```
+
+
```elixir
+
{t, v} = Alone.visit("AA", valves, paths, 30, %{})
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{1820, %{"AG" => 6, "MO" => 23, "QJ" => 3, "QS" => 16, "TX" => 10, "UH" => 26, "YB" => 19}}
+
```
+
+
## Task 2
+
+
```elixir
+
defmodule Alone do
+
def visit(current, valves, paths, left, opened) when left >= 0 do
+
{left, rate, opened} =
+
case valves[current].rate do
+
0 -> {left, 0, opened}
+
other -> {left - 1, other, Map.put(opened, current, left - 1)}
+
end
+
+
rate = rate * left
+
+
paths[current]
+
|> Enum.map(fn
+
{next, weight} when weight + 1 < left and not is_map_key(opened, next) ->
+
{val, opened} = visit(next, valves, paths, left - weight, opened)
+
{val + rate, opened}
+
+
_ ->
+
{rate, opened}
+
end)
+
|> Enum.max_by(&elem(&1, 0))
+
end
+
end
+
```
+188
2022/day17.livemd
···
+
<!-- livebook:{"persist_outputs":true} -->
+
+
# Day 17
+
+
```elixir
+
Mix.install([
+
{:kino_aoc, git: "https://github.com/ljgago/kino_aoc"}
+
])
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
* Getting kino_aoc (https://github.com/ljgago/kino_aoc)
+
remote: Enumerating objects: 103, done.
+
remote: Counting objects: 100% (103/103), done.
+
remote: Compressing objects: 100% (68/68), done.
+
remote: Total 103 (delta 40), reused 84 (delta 25), pack-reused 0
+
origin/HEAD set to main
+
Resolving Hex dependencies...
+
Resolution completed in 0.336s
+
New:
+
castore 1.0.3
+
finch 0.16.0
+
hpax 0.1.2
+
jason 1.4.1
+
kino 0.10.0
+
mime 2.0.5
+
mint 1.5.1
+
nimble_options 1.0.2
+
nimble_pool 1.0.0
+
req 0.3.10
+
table 0.1.2
+
telemetry 1.2.1
+
* Getting kino (Hex package)
+
* Getting req (Hex package)
+
* Getting finch (Hex package)
+
* Getting jason (Hex package)
+
* Getting mime (Hex package)
+
* Getting castore (Hex package)
+
* Getting mint (Hex package)
+
* Getting nimble_options (Hex package)
+
* Getting nimble_pool (Hex package)
+
* Getting telemetry (Hex package)
+
* Getting hpax (Hex package)
+
* Getting table (Hex package)
+
==> table
+
Compiling 5 files (.ex)
+
Generated table app
+
==> mime
+
Compiling 1 file (.ex)
+
Generated mime app
+
==> nimble_options
+
Compiling 3 files (.ex)
+
Generated nimble_options app
+
==> kino
+
Compiling 41 files (.ex)
+
Generated kino app
+
===> Analyzing applications...
+
===> Compiling telemetry
+
==> jason
+
Compiling 10 files (.ex)
+
Generated jason app
+
==> hpax
+
Compiling 4 files (.ex)
+
Generated hpax app
+
==> nimble_pool
+
Compiling 2 files (.ex)
+
Generated nimble_pool app
+
==> castore
+
Compiling 1 file (.ex)
+
Generated castore app
+
==> mint
+
Compiling 1 file (.erl)
+
Compiling 19 files (.ex)
+
Generated mint app
+
==> finch
+
Compiling 13 files (.ex)
+
Generated finch app
+
==> req
+
Compiling 5 files (.ex)
+
Generated req app
+
==> kino_aoc
+
Compiling 3 files (.ex)
+
Generated kino_aoc app
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
:ok
+
```
+
+
## Section
+
+
<!-- livebook:{"attrs":{"day":"17","session_secret":"ADVENT_OF_CODE_SESSION","variable":"puzzle_input","year":"2022"},"chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2022", "17", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:ok,
+
">><<<>><<<<>>><>><>>><<<>>>><>>><<><<<>>>><<<><<<><<><<<>>>><<><<>>><<<<>><<>><<<><<<<>><<<<><>>><<<<>>><<<>>>><<<>>>><<<<>>><<>>><<>>>><<<<>>>><<<<>><>>>><<<<>>><<>><>>><>>><<<<>>><<>>><>><<<>>>><<>>>><<<>>><<<>>>><<<<><<<><<>>><>><<<<>><>><<><<<<>>><<>>><<<>>>><<<<>>><<>>>><<<<>><>><<<><<>><<<>>>><<<>><<<<>>>><<<><<<<>>><<><>>><<>><<<>>><<<<>>><<>>>><<<>>><<<<>>><<>>>><<<<>><<>>>><<<>>>><<>>><<><<<>>><<<<>>>><<<<>>><<<>>>><<<<>><<<>>>><>>><><<>>><<<><<>>>><<<>>>><<><<<<>>>><<<><<>><<<<>>>><<>>><>>>><<<<>><<>>><<>>><<>><>><><<<<>>>><<<>><<>>><<><<<<>>>><<<<><<<<>>>><><<>>><><>>><<>>><>>><>>>><<>><><<>><>>><<>>>><<>>>><<<<><<<>>>><>><>>>><<<<><<<><<<>>>><<><<>><<<>>><<<<>>><<<<><<>>><<<>>>><<><<<<>><<<<>><<<><>><>>>><><<<>>><<<<><<<<>><>>><<<>><<<<><<<>>>><<<>>>><<<>><<>><<<<>><<<<>><>>>><<>>>><<<<>>><<>>>><<>>>><>><<<>>>><<<<>>><<<<><>>>><<><<<>><<<<>>>><<<<>><>>>><<<>>>><<<<>>>><<<<>>><<<<>><>>><<<<><>>>><<><>>>><>><<>>>><>>>><<>><<>>><<<>>>><<><<<>>>><<><<>><<<<>>><<<>>><<<<>><<<><<<>>><<><<>>>><<<>>><<>>><<<><<<<>>><>>>><<<>>><<<>>>><<><><<>>>><<>>>><<>>>><<>>><<>><<><<<>>><>>><<<<>>>><>>>><<<>><>><<<<>>><<<<>>><<>>><<<<><<<>>><>>>><<>><<<<>><<<<>><<<<><>><<<<>>>><<>>><>><<<>><<>><<<<>><<>>><<<<>>><<<<>>><<><<<>>><<><<<><<>>>><>><<><<<<><<>><<<>>>><><<<<><><><>>><<<>>><<>>><<<>>>><<><<>><<>><<<><<<<>>>><>>>><<>>>><<<>>>><<>>>><<<>><>><<<>>><<>>>><<><<>>>><<<><<<<>>><<<>>>><<<>>><<<><>>><<>>><<<>>>><<<>>>><<<>>>><<<>><>><<<>>><<<<>>>><><<<>>>><<>>>><><>>><<>>>><<>><<>>>><<<>><<<>>>><<>>>><<<<>><<<>><<<>><<>><<<>>><<><>>><<><<><>>>><<<>>>><<<<>><<>>>><<<<>><><<<>>><<<<>><<>>><<<>><<>><<>><>>>><<><<>>>><>>>><<><><<<><<<<>>>><<<<>><<><<><<>>>><>>><<<><<<<><<>><<<><<>><><<><<<>>>><>>>><<>>>><>><><><<<><<><<>>><<<<><<>><<<>>>><<><<<<>>>><<<<>><><<<<>><<>><>><<<<>>>><<>>>><<<<><<<>><<>>><<<>>><>>><<>>>><<<><<<<><<>>>><<<<>><<<>>>><<<>><<<<><<<>><<<<>><<<>>>><<>>>><><>>><>>><<<>>>><<>>><<<>><>>>><<<>>>><<<<><<<>>><<<<>><<>><<>><<<><<<<>>><><>><<<><<<>>><<<><<<<>>>><><<<<>><<>><>>><<<>>>><<>>><<<>><<<<>>><<<>><<>><<>><<<<><<>>><>><<>>><<><<<><<<>><<<<>>><>><><<<<>>>><<<><<<>><>><<>>>><<<>>>><<<><<<>>><<>>><><>><<<>><>>>><<<<>>>><<<<>>><<<<>>><<<<>><<<<><><<>><>><<>>><<>><<><<<<>>>><<<<>>>><<>>>><<<<>>>><<>>>><>>>><<>><<><<<><><>><<<><<<<>>>><<<<>><<<>>>><<<<>>>><>>>><><<<<>><>>><<<<><<>>>><>><<<<>><<<><<<>>>><<>><<>>><>>>><<><>>>><<<<><<><<<>>>><<<>>>><<><>><<<>><<<>><<<<><<>>><>><<>>><<>>><>>>><<<>>><<>><<><><<>>>><<<>>><<<>><<<>>><<<>>>><<>>><>>>><>>>><>>><<>>>><<<>><<<<>><<<<>><<>>>><><>>>><<>>>><<<><<<<><<>>>><<<<>><<<<>>>><><<<><>><<<<>>>><>>>><<<<>>>><<><>><<<<><<<>>><<<<>><>><>>>><<>>>><>>><>>>><>><<>>><<<><>><>>>><<<>><<<>><<<<><<<<>>><<<>>><<<>>>><>><>>><<<<>><<<><<>>><>>><<><>>>><<<>>>><<<<>>>><><<<>>><<<<>>><>><>>>><<<>><<>>>><>>><<<<>>>><<<>><<<>>>><<<<>><<<>>><<<<><<<<>>>><><<<>>><<<<>>>><<<<>><<>><<<>>><>>><>><<>>><<<>><><<><>><<>><>><<<><<<<>>><<<>><<<><<<>>>><<>>><<<<><<><<<>>><<<<>>><<>><>>><>>><<<><<>>>><<<>><<<<><<<>><<<<>><>><<>><>>>><>>>><<>>><<<<>>><><><><<<>>><<<>><<>>><<<<>>>><>><<<>>>><<>><<<<>><<>><>><<<>>>><>>><<<<>>><>><<>>><<<>><<<<>>>><<<>><<>><>><<<<>><<<><<<>><>><<<><<<>>>><<<<>>><<><<<<><<<<>>>><<<><>><<><>>><<<><<><<<<>>><<>>>><>><<<<>><<<<>>><<>>>><>>><<<>>><<<>>>><<>>><>>>><<<<><>><<>>>><<<>>><>>><>><<<>>>><<><<<>>>><<><<<<>>>><<<<>>>><><<<<>>>><<<>>>><<><<<>>>><<>><>><>>><<<<><<<>>>><<<<>>>><<<><<>>>><<<><>>>><<<<>>>><>>><<<>><<<<><<>>><<>>><<>>><>>><<<><><><<<>>>><<>>>><<<<><>>>><<<>><<>>>><<><<<<><<<<>><><<<<><<>>>><<<>><<<<>><<>><<><<>>>><<><<<><<<<><<<<>>><<<>>>><<<<>>><><<<>>><>>>><>>><<<<>>><<<>>><<<<><<<<><<>><><<<>>><>>><<><<><<>><<<<>>>><<<>><<<><<<<>>><<<<>>><<>><<<<>><>>>><>><<<><>>>><<<>>><<><<>><<<><<<>><<<<>><<<<>><<<<><>>>><<><<<>><<<><<<>><<<<><<>>>><<<>><<<><<<>>><<<><<<<>>>><<>>>><<<>><<<<>>><<><<<<>>>><<<<>>>><<>><<><<>>><<>>>><<>>><<>>><<<>>>><<>>><<><<>>><<<>><<<<>>><<>>><<<>>><<<>>><>>>><<<>>>><<<<>>>><>>>><<<>>>><<<>>>><>>>><>>>><<<><<>><><>><<>><><<<>>>><><>>>><><<<><>>><<<>>><<<>>><<<<>><<<<><<<>>><<>><<<<>>><<<>><<>>>><<><<<<>>><>><<<>>>><<>><<<<>>><<<<>>><>>>><<>" <> ...}
+
```
+
+
```elixir
+
well = [0, 0, 0, 0, 0, 0, 0]
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
[0, 0, 0, 0, 0, 0, 0]
+
```
+
+
```elixir
+
defmodule Tetris do
+
def fit(well, n, :dash) when n in 0..3 do
+
max =
+
well
+
|> Enum.drop(n)
+
|> Enum.take(4)
+
|> Enum.max()
+
+
well
+
|> List.replace_at(n, max + 1)
+
|> List.replace_at(n + 1, max + 1)
+
|> List.replace_at(n + 2, max + 1)
+
|> List.replace_at(n + 3, max + 1)
+
end
+
+
def fit(well, n, :plus) when n in 0..4 do
+
bottom =
+
well
+
|> Enum.drop(n)
+
|> Enum.take(3)
+
|> case do
+
[a, b, c] when b < a and b < c -> max(a, b) - 1
+
[_, b, _] -> b
+
end
+
+
well
+
|> List.replace_at(n, bottom + 2)
+
|> List.replace_at(n + 1, bottom + 3)
+
|> List.replace_at(n + 2, bottom + 2)
+
end
+
+
def fit(well, n, :l), do: well
+
+
def fit(well, n, :i), do: well
+
+
def fit(well, n, :o), do: well
+
end
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
warning: variable "n" is unused (if the variable is not meant to be used, prefix it with an underscore)
+
2022/day17.livemd#cell:yqwk3yzwldnf4hstvs2cj6qm5r3go5yp:32: Tetris.fit/3
+
+
warning: variable "n" is unused (if the variable is not meant to be used, prefix it with an underscore)
+
2022/day17.livemd#cell:yqwk3yzwldnf4hstvs2cj6qm5r3go5yp:34: Tetris.fit/3
+
+
warning: variable "n" is unused (if the variable is not meant to be used, prefix it with an underscore)
+
2022/day17.livemd#cell:yqwk3yzwldnf4hstvs2cj6qm5r3go5yp:36: Tetris.fit/3
+
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:module, Tetris, <<70, 79, 82, 49, 0, 0, 10, ...>>, {:fit, 3}}
+
```
+
+
```elixir
+
Tetris.fit([2, 1, 2, 0, 0, 0, 0], 0, :plus)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
[3, 4, 3, 0, 0, 0, 0]
+
```
+266
2022/day18.livemd
···
+
<!-- livebook:{"persist_outputs":true} -->
+
+
# Day 18
+
+
```elixir
+
Mix.install([
+
{:kino_aoc, git: "https://github.com/ljgago/kino_aoc"}
+
])
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
:ok
+
```
+
+
## Section
+
+
<!-- livebook:{"attrs":{"day":"18","session_secret":"ADVENT_OF_CODE_SESSION","variable":"puzzle_input","year":"2022"},"chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2022", "18", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:ok,
+
"9,2,13\n12,12,4\n3,8,14\n9,3,4\n15,5,7\n9,5,4\n7,3,10\n12,8,2\n8,12,16\n12,16,12\n5,15,8\n16,7,12\n4,5,6\n11,7,2\n10,14,16\n9,3,15\n6,7,3\n14,10,15\n7,12,3\n13,8,3\n9,1,12\n7,15,5\n8,6,16\n17,9,12\n3,13,6\n7,2,10\n9,14,3\n16,12,6\n13,4,15\n17,14,11\n14,4,5\n15,4,14\n3,4,9\n13,12,17\n15,11,3\n12,14,3\n12,5,4\n16,5,12\n14,16,6\n4,3,11\n9,16,13\n10,6,3\n17,9,7\n5,5,14\n14,13,15\n16,12,8\n7,11,2\n14,9,4\n12,11,15\n13,7,4\n4,15,13\n9,13,2\n7,16,9\n17,13,6\n11,0,11\n15,4,11\n4,12,8\n13,3,13\n5,12,17\n16,14,9\n6,5,4\n9,17,8\n6,10,2\n3,10,7\n1,9,7\n5,14,12\n7,12,5\n3,5,10\n5,15,14\n6,3,11\n15,13,13\n7,4,5\n11,7,4\n11,16,12\n2,11,8\n7,15,4\n9,5,17\n12,14,4\n14,4,6\n7,8,2\n11,3,7\n15,13,7\n12,11,2\n11,6,16\n18,10,10\n4,12,5\n11,10,2\n7,17,9\n3,14,9\n7,17,5\n10,8,17\n10,1,11\n11,11,1\n16,8,14\n2,7,10\n7,9,17\n12,12,2\n11,17,11\n15,10,16\n9,1,8\n1,10,12\n6,2,11\n17,11,8\n9,2,11\n13,5,4\n2,9,11\n4,5,9\n8,3,5\n3,14,11\n3,13,12\n10,8,16\n12,14,16\n15,12,13\n5,3,12\n16,9,12\n1,10,10\n17,6,10\n10,18,8\n8,13,17\n13,7,2\n3,12,13\n2,12,5\n6,9,16\n3,6,9\n6,16,6\n0,9,9\n6,17,10\n15,10,14\n2,8,12\n13,3,8\n11,12,17\n9,17,11\n4,6,8\n15,11,2\n4,6,15\n11,4,12\n11,8,1\n7,1,10\n12,11,3\n18,11,12\n8,16,12\n1,9,11\n16,14,14\n15,8,5\n15,5,5\n6,10,17\n13,4,16\n8,12,2\n10,5,15\n4,11,16\n4,10,4\n12,10,3\n10,5,2\n5,15,7\n14,15,7\n16,10,5\n6,3,3\n12,17,10\n4,7,14\n6,4,12\n13,5,11\n7,15,6\n1,8,9\n4,11,15\n14,4,4\n2,13,8\n5,4,5\n4,13,13\n4,14,8\n17,12,11\n7,16,15\n16,13,11\n11,3,12\n17,9,8\n11,6,15\n11,15,16\n6,17,9\n17,6,8\n13,15,15\n10,17,8\n3,5,5\n3,9,14\n17,10,13\n16,9,13\n13,8,16\n12,5,3\n12,15,15\n5,10,14\n16,15,11\n7,2,9\n9,16,12\n2,14,9\n14,17,8\n13,16,8\n7,3,5\n5,3,10\n11,5,16\n17,10,10\n6,7,16\n1,12,10\n6,14,2\n7,2,12\n12,17,9\n17,6,12\n2,13,13\n8,4,3\n16,8,13\n3,15,7\n16,5,13\n16,13,12\n16,12,5\n16,5,9\n4,13,8\n9,13,17\n13,10,15\n4,6,4\n10,11,17\n13,14,5\n9,14,14\n11,2,7\n12,10,2\n12,18,10\n12,6,16\n17,11,6\n8,14,16\n10,15,3\n3,6,5\n7,10,17\n15,5,12\n16,11,14\n8,12,18\n15,13,9\n6,8,3\n15,12,2\n14,13,6\n15,4,10\n11,1,8\n10,1,6\n5,7,16\n9,7,2\n13,3,6\n8,2,7\n14,14,5\n9,3,13\n6,3,8\n8,5,4\n7,4,4\n10,14,15\n10,16,5\n16,11,10\n3,8,11\n4,13,15\n8,13,5\n10,4,5\n15,14,14\n13,12,16\n11,14,3\n11,17,8\n6,5,2\n15,15,13\n5,5,5\n14,9,2\n5,5,9\n3,7,13\n2,15,9\n15,15,7\n7,17,8\n11,8,2\n16,5,7\n9,16,7\n11,4,4\n7,5,15\n10,12,1\n7,4,14\n9,16,6\n15,10,9\n14,7,16\n7,15,15\n15,11,5\n8,4,14\n13,14,10\n10,12,2\n11,15,14\n13,13,3\n4,13,4\n8,8,17\n9,4,3\n13,5,3\n2,10,8\n6,16,9\n4,8,14\n7,2,11\n14,1,10\n17,8,7\n14,9,13\n14,6,6\n5,6,16\n4,13,10\n8,13,16\n16,9,15\n5,8,3\n18,9,10\n13,14,15\n14,4,13\n17,12,10\n17,7,7\n10,17,6\n16,10,14\n6,11,2\n16,10,10\n12,8,16\n12,13,18\n12,2,8\n17,8,9\n12,6,4\n13,17,10\n17,6,6\n15,8,15\n7,17,13\n4,15,11\n10,12,17\n2,7,11\n17,13,10\n5,12,4\n11,3,13\n5,11,4\n14,3,10\n11,4,14\n10,1,13\n5,6,6\n2,10,12\n5,8,15\n13,7,3\n12,7,4\n15,14,7\n5,7,13\n8,6,3\n9,6,16\n16,5,11\n15,13,15\n9,14,17\n15,14,13\n14,5,6\n2,7,6\n13,15,5\n4,11,5\n8,4,6\n14,14,15\n17,5,10\n5,9,3\n11,5,4\n5,9,13\n16,8,15\n11,11,17\n10,3,4\n14,5,16\n6,9,15\n9,14,16\n9,5,5\n5,15,13\n9,11,3\n7,6,4\n12,13,3\n2,13,7\n10,13,17\n10,17,10\n13,3,9\n14,4,8\n18,8,8\n4,12,7\n6,17,12\n9,9,1\n16,8,12\n12,3,6\n6,5,14\n4,14,12\n15,11,13\n5,4,15\n4,15,12\n5,14,5\n10,4,16\n12,6,2\n15,13,4\n8,15,4\n14,5,14\n16,10,12\n6,17,11\n17,15,10\n16,13,10\n16,12,14\n10,14,3\n11,12,1\n4,10,14\n10,2,15\n16,13,14\n6,14,5\n2,9,7\n12,9,2\n8,18,11\n13,12,2\n7,9,3\n8,16,15\n12,3,15\n9,16,11\n16,9,7\n6,15,7\n12,2,13\n5,12,16\n6,12,17\n12,1,10\n11,13,14\n9,8,18\n15,10,17\n7,13,16\n11,2,11\n10,11,2\n13,16,14\n8,15,14\n8,4,13\n7,7,2\n13,10,1\n7,3,12\n12,2,10\n10,17,11\n3,13,9\n5,10,13\n10,10,16\n6,14,6\n7,6,2\n13,12,4\n15,3,13\n4,3,12\n7,10,18\n4,14,7\n15,9,4\n7,16,4\n11,3,6\n5,11,2\n2,9,13\n14,7,4\n14,15,10\n4,8,4\n7,6,16\n15,12,14\n17,7,10\n13,15,4\n16,4,8\n13,3,5\n6,16,8\n3,6,12\n6,16,7\n15,9,15\n4,6,10\n12,12,16\n2,8,10\n3,13,11\n8,5,6\n14,4,12\n10,9,18\n9,6,2\n6,9,3\n12,14,15\n10,5,12\n17,7,12\n7,11,17\n14,12,15\n18,9,8\n10,5,16\n14,9,16\n4,5,11\n5,13,8\n3,4,6\n2,6,11\n6,15,15\n9,5,2\n11,15,15\n7,16,13\n2,9,12\n1,9,10\n9,7,16\n9,11,17\n16,11,6\n14,16,8\n9,3,12\n8,14,4\n17,8,10\n17,5,9\n4,11,12\n3,5,13\n7,15,14\n11,8,17\n13,2,9\n10,17,12\n8,5,2\n16,16,12\n10,6,16\n16,6,7\n9,10,1\n9,16,15\n7,11,18\n4,9,16\n8,2,11\n7,16,11\n8,7,2\n7,9,2\n2,11,5\n6,3,7\n10,7,17\n6,5,16\n4,4,8\n11,9,4\n5,13,13\n14,6,14\n2,8,7\n14,5,5\n13,14,3\n15,14,8\n9,5,3\n16,4,11\n3,7,15\n7,16,12\n14,14,14\n4,9,5\n4,4,10\n2,14,12\n15,2,9\n9,15,4\n16,13,6\n7,7,3\n4,11,6\n1,12,9\n12,10,17\n5,12,14\n16,12,12\n6,6,5\n15,11,11\n11,4,5\n11,13,5\n18,13,9\n17,6,13\n12,4,12\n5,16,9\n10,9,17\n3,14" <> ...}
+
```
+
+
```elixir
+
cubes =
+
puzzle_input
+
|> String.split("\n", trim: true)
+
|> Enum.map(fn line ->
+
line
+
|> String.split(",")
+
|> Enum.map(&String.to_integer/1)
+
|> List.to_tuple()
+
end)
+
|> MapSet.new()
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
MapSet.new([
+
{12, 9, 18},
+
{11, 4, 5},
+
{2, 10, 6},
+
{12, 2, 8},
+
{14, 15, 15},
+
{5, 14, 12},
+
{10, 6, 18},
+
{6, 4, 6},
+
{11, 4, 3},
+
{6, 14, 3},
+
{4, 8, 4},
+
{17, 7, 9},
+
{7, 12, 16},
+
{14, 13, 3},
+
{12, 3, 16},
+
{13, 6, 2},
+
{5, 6, 5},
+
{17, 10, 11},
+
{4, 16, 9},
+
{17, 9, 9},
+
{6, 2, 10},
+
{13, 17, 13},
+
{12, 13, 3},
+
{3, 13, 7},
+
{13, 7, 4},
+
{17, 12, 7},
+
{7, 3, 13},
+
{12, 15, 15},
+
{15, 6, 4},
+
{17, 10, 8},
+
{9, 14, 13},
+
{3, 9, 4},
+
{14, 13, 9},
+
{15, 13, 4},
+
{13, 4, 15},
+
{7, 7, 15},
+
{6, 14, 8},
+
{11, 2, 16},
+
{7, 2, 8},
+
{3, 14, 13},
+
{4, 5, 6},
+
{3, 9, 14},
+
{4, 16, 12},
+
{14, 12, 12},
+
{14, 5, 15},
+
{17, 9, 12},
+
{15, 10, 15},
+
{8, 17, ...},
+
{2, ...},
+
{...},
+
...
+
])
+
```
+
+
## Task 1
+
+
```elixir
+
sides =
+
for {x, y, z} <- cubes,
+
{place, {dx, dy, dz}} <- [
+
x: {-1, 0, 0},
+
y: {0, -1, 0},
+
z: {0, 0, -1},
+
x: {0, 0, 0},
+
y: {0, 0, 0},
+
z: {0, 0, 0}
+
],
+
reduce: MapSet.new() do
+
set ->
+
side = {place, {x + dx, y + dy, z + dz}}
+
+
if side in set do
+
MapSet.delete(set, side)
+
else
+
MapSet.put(set, side)
+
end
+
end
+
+
MapSet.size(sides)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
3636
+
```
+
+
## Task 2
+
+
```elixir
+
max =
+
Enum.reduce(cubes, {0, 0, 0}, fn {x, y, z}, {mx, my, mz} ->
+
{max(x, mx), max(y, my), max(z, mz)}
+
end)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{19, 19, 19}
+
```
+
+
```elixir
+
defmodule Cave do
+
def bfs([], _sides, outer, _visited), do: outer
+
+
def bfs([{x, y, z} = p | queue], sides, outer, visited) do
+
{min, max} = Enum.min_max([x, y, z])
+
+
if p in visited or max > 25 or min < -5 do
+
bfs(queue, sides, outer, visited)
+
else
+
visited = MapSet.put(visited, p)
+
+
{outer, xs1} = check(:x, p, {x + 1, y, z}, sides, outer, visited)
+
{outer, xs2} = check(:x, {x - 1, y, z}, {x - 1, y, z}, sides, outer, visited)
+
{outer, ys1} = check(:y, p, {x, y + 1, z}, sides, outer, visited)
+
{outer, ys2} = check(:y, {x, y - 1, z}, {x, y - 1, z}, sides, outer, visited)
+
{outer, zs1} = check(:z, p, {x, y, z + 1}, sides, outer, visited)
+
{outer, zs2} = check(:z, {x, y, z - 1}, {x, y, z - 1}, sides, outer, visited)
+
+
bfs(queue ++ xs1 ++ xs2 ++ ys1 ++ ys2 ++ zs1 ++ zs2, sides, outer, visited)
+
end
+
end
+
+
defp check(axis, curr, next, sides, outer, visited) do
+
cond do
+
{axis, curr} in sides ->
+
{MapSet.put(outer, {axis, curr}), []}
+
+
next in visited ->
+
{outer, []}
+
+
true ->
+
{outer, [next]}
+
end
+
end
+
end
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:module, Cave, <<70, 79, 82, 49, 0, 0, 14, ...>>, {:check, 6}}
+
```
+
+
```elixir
+
outer = Cave.bfs([{-5, -5, -5}], sides, MapSet.new(), MapSet.new())
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
MapSet.new([
+
x: {10, 19, 11},
+
z: {15, 16, 12},
+
z: {2, 16, 10},
+
z: {5, 13, 2},
+
y: {4, 3, 15},
+
x: {0, 13, 10},
+
x: {17, 12, 6},
+
z: {10, 11, 0},
+
z: {10, 5, 17},
+
z: {4, 7, 2},
+
x: {15, 16, 9},
+
x: {2, 7, 4},
+
z: {2, 8, 5},
+
y: {16, 13, 5},
+
x: {2, 6, 14},
+
x: {18, 12, 11},
+
y: {13, 17, 7},
+
z: {3, 9, 14},
+
y: {11, 3, 16},
+
x: {4, 10, 17},
+
y: {11, 2, 15},
+
z: {13, 4, 3},
+
x: {10, 17, 5},
+
y: {3, 12, 4},
+
y: {11, 18, 10},
+
z: {5, 17, 8},
+
y: {15, 16, 6},
+
y: {3, 3, 7},
+
z: {7, 1, 5},
+
x: {14, 2, 9},
+
y: {18, 5, 8},
+
x: {10, 1, 13},
+
x: {9, 16, 3},
+
x: {2, 15, 8},
+
y: {7, 4, 2},
+
x: {17, 6, 12},
+
x: {0, 9, 7},
+
x: {12, 8, 1},
+
x: {0, 11, 10},
+
z: {10, 16, 3},
+
x: {16, 5, 6},
+
z: {5, 10, 1},
+
z: {7, 4, 15},
+
z: {12, 11, 18},
+
y: {11, 17, 12},
+
z: {3, 5, 4},
+
z: {6, 1, 9},
+
x: {16, 8, ...},
+
z: {14, ...},
+
z: {...},
+
...
+
])
+
```
+
+
```elixir
+
MapSet.size(outer)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
2102
+
```
+230
2022/day19.livemd
···
+
<!-- livebook:{"persist_outputs":true} -->
+
+
# Day 19
+
+
```elixir
+
Mix.install([
+
{:kino_aoc, git: "https://github.com/ljgago/kino_aoc"}
+
])
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
:ok
+
```
+
+
## Section
+
+
<!-- livebook:{"attrs":{"day":"19","session_secret":"ADVENT_OF_CODE_SESSION","variable":"puzzle_input","year":"2022"},"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2022", "19", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:ok,
+
"Blueprint 1: Each ore robot costs 3 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 15 clay. Each geode robot costs 2 ore and 8 obsidian.\nBlueprint 2: Each ore robot costs 2 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 17 clay. Each geode robot costs 3 ore and 10 obsidian.\nBlueprint 3: Each ore robot costs 2 ore. Each clay robot costs 2 ore. Each obsidian robot costs 2 ore and 20 clay. Each geode robot costs 2 ore and 14 obsidian.\nBlueprint 4: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 3 ore and 14 clay. Each geode robot costs 4 ore and 15 obsidian.\nBlueprint 5: Each ore robot costs 2 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 13 clay. Each geode robot costs 3 ore and 15 obsidian.\nBlueprint 6: Each ore robot costs 2 ore. Each clay robot costs 2 ore. Each obsidian robot costs 2 ore and 15 clay. Each geode robot costs 2 ore and 7 obsidian.\nBlueprint 7: Each ore robot costs 3 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 9 clay. Each geode robot costs 3 ore and 7 obsidian.\nBlueprint 8: Each ore robot costs 4 ore. Each clay robot costs 2 ore. Each obsidian robot costs 2 ore and 16 clay. Each geode robot costs 2 ore and 8 obsidian.\nBlueprint 9: Each ore robot costs 2 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 20 clay. Each geode robot costs 4 ore and 18 obsidian.\nBlueprint 10: Each ore robot costs 3 ore. Each clay robot costs 3 ore. Each obsidian robot costs 2 ore and 11 clay. Each geode robot costs 2 ore and 19 obsidian.\nBlueprint 11: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 2 ore and 7 clay. Each geode robot costs 3 ore and 10 obsidian.\nBlueprint 12: Each ore robot costs 2 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 11 clay. Each geode robot costs 2 ore and 16 obsidian.\nBlueprint 13: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 16 clay. Each geode robot costs 3 ore and 15 obsidian.\nBlueprint 14: Each ore robot costs 4 ore. Each clay robot costs 3 ore. Each obsidian robot costs 4 ore and 18 clay. Each geode robot costs 3 ore and 13 obsidian.\nBlueprint 15: Each ore robot costs 2 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 13 clay. Each geode robot costs 2 ore and 20 obsidian.\nBlueprint 16: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 14 clay. Each geode robot costs 4 ore and 10 obsidian.\nBlueprint 17: Each ore robot costs 4 ore. Each clay robot costs 3 ore. Each obsidian robot costs 2 ore and 17 clay. Each geode robot costs 3 ore and 16 obsidian.\nBlueprint 18: Each ore robot costs 2 ore. Each clay robot costs 4 ore. Each obsidian robot costs 3 ore and 20 clay. Each geode robot costs 2 ore and 17 obsidian.\nBlueprint 19: Each ore robot costs 2 ore. Each clay robot costs 4 ore. Each obsidian robot costs 2 ore and 16 clay. Each geode robot costs 4 ore and 12 obsidian.\nBlueprint 20: Each ore robot costs 3 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 16 clay. Each geode robot costs 3 ore and 20 obsidian.\nBlueprint 21: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 18 clay. Each geode robot costs 4 ore and 12 obsidian.\nBlueprint 22: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 3 ore and 13 clay. Each geode robot costs 3 ore and 19 obsidian.\nBlueprint 23: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 18 clay. Each geode robot costs 3 ore and 8 obsidian.\nBlueprint 24: Each ore robot costs 4 ore. Each clay robot costs 3 ore. Each obsidian robot costs 2 ore and 13 clay. Each geode robot costs 2 ore and 9 obsidian.\nBlueprint 25: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 5 clay. Each geode robot costs 3 ore and 15 obsidian.\nBlueprint 26: Each ore robot costs 4 ore. Each clay robot costs " <> ...}
+
```
+
+
```elixir
+
puzzle_input = """
+
Blueprint 1: Each ore robot costs 4 ore. Each clay robot costs 2 ore. Each obsidian robot costs 3 ore and 14 clay. Each geode robot costs 2 ore and 7 obsidian.
+
Blueprint 2: Each ore robot costs 2 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 8 clay. Each geode robot costs 3 ore and 12 obsidian.
+
"""
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
"Blueprint 1: Each ore robot costs 4 ore. Each clay robot costs 2 ore. Each obsidian robot costs 3 ore and 14 clay. Each geode robot costs 2 ore and 7 obsidian.\nBlueprint 2: Each ore robot costs 2 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 8 clay. Each geode robot costs 3 ore and 12 obsidian.\n"
+
```
+
+
```elixir
+
regex =
+
~r/ore robot.*(?<ore_ore>\d+) ore.*clay robot.*(?<clay_ore>\d+) ore.*obsidian robot.*(?<obsidian_ore>\d+) ore and (?<obsidian_clay>\d+) clay.*geode robot.*(?<geode_ore>\d+) ore and (?<geode_obsidian>\d+) obsidian/
+
+
plans =
+
puzzle_input
+
|> String.split("\n", trim: true)
+
|> Kino.render()
+
|> Enum.map(fn line ->
+
blueprint =
+
Regex.named_captures(regex, line)
+
|> Map.new(fn {k, v} ->
+
{String.to_atom(k), String.to_integer(v)}
+
end)
+
+
%{
+
ore: %{ore: blueprint.ore_ore},
+
clay: %{ore: blueprint.clay_ore},
+
obsidian: %{ore: blueprint.obsidian_ore, clay: blueprint.obsidian_clay},
+
geode: %{ore: blueprint.geode_ore, obsidian: blueprint.geode_obsidian},
+
max: %{
+
ore:
+
Enum.max([
+
blueprint.ore_ore,
+
blueprint.clay_ore,
+
blueprint.obsidian_ore,
+
blueprint.geode_ore
+
]),
+
clay: blueprint.obsidian_clay,
+
obsidian: blueprint.geode_obsidian
+
}
+
}
+
end)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
["Blueprint 1: Each ore robot costs 4 ore. Each clay robot costs 2 ore. Each obsidian robot costs 3 ore and 14 clay. Each geode robot costs 2 ore and 7 obsidian.",
+
"Blueprint 2: Each ore robot costs 2 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 8 clay. Each geode robot costs 3 ore and 12 obsidian."]
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
[
+
%{
+
clay: %{ore: 2},
+
geode: %{obsidian: 7, ore: 2},
+
max: %{clay: 14, obsidian: 7, ore: 4},
+
obsidian: %{clay: 14, ore: 3},
+
ore: %{ore: 4}
+
},
+
%{
+
clay: %{ore: 3},
+
geode: %{obsidian: 12, ore: 3},
+
max: %{clay: 8, obsidian: 12, ore: 3},
+
obsidian: %{clay: 8, ore: 3},
+
ore: %{ore: 2}
+
}
+
]
+
```
+
+
```elixir
+
defmodule Blueprint do
+
def produce(plan, time, machines) do
+
produce(plan, time, machines, %{ore: 0, clay: 0, obsidian: 0, geode: 0})
+
end
+
+
def produce(_plan, 0, machines, stash) do
+
%{machines: machines, stash: stash}
+
end
+
+
def produce(plan, time_left, machines, stash) do
+
do_shopping(plan, stash)
+
|> Enum.filter(fn {k, _} -> (machines[k] || 0) < plan.max[k] end)
+
|> Enum.flat_map(fn {machine, new_stash} ->
+
# if machine in [:obsidian, :geode], do: IO.inspect(new_stash)
+
[
+
produce(
+
plan,
+
time_left - 1,
+
add_machine(machine, machines),
+
update_stash(machines, new_stash)
+
)
+
]
+
end)
+
# |> tap(fn list ->
+
# Enum.filter(list, & &1.obsidian > 0)
+
# |> Enum.map(&IO.inspect/1)
+
# end)
+
|> Enum.max_by(& &1.stash.geode)
+
end
+
+
defp add_machine(nil, machines), do: machines
+
defp add_machine(name, machines), do: Map.update(machines, name, 1, &(&1 + 1))
+
+
defp update_stash(machines, stash) do
+
Enum.reduce(machines, stash, fn {k, v}, acc ->
+
Map.update(acc, k, v, &(&1 + v))
+
end)
+
end
+
+
def do_shopping(plan, stash)
+
when stash.ore >= plan.geode.ore and stash.obsidian >= plan.geode.obsidian,
+
do: [{:geode, buy(plan.geode, stash)}]
+
+
def do_shopping(plan, stash)
+
when stash.ore >= plan.obsidian.ore and stash.clay >= plan.obsidian.clay,
+
do: [{:obsidian, buy(plan.obsidian, stash)}, {nil, stash}]
+
+
def do_shopping(plan, stash) do
+
[
+
{nil, stash}
+
| Enum.flat_map([:ore, :clay], fn k ->
+
if stash.ore >= plan[k].ore do
+
[{k, %{stash | ore: stash.ore - plan[k].ore}}]
+
else
+
[]
+
end
+
end)
+
]
+
end
+
+
defp buy(price, stash) do
+
Map.merge(stash, price, fn _k, v1, v2 -> v1 - v2 end)
+
end
+
end
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:module, Blueprint, <<70, 79, 82, 49, 0, 0, 22, ...>>, {:buy, 2}}
+
```
+
+
```elixir
+
plan = hd(plans) |> Kino.inspect()
+
stash = %{clay: 35, geode: 0, obsidian: 0, ore: 4}
+
+
Blueprint.do_shopping(plan, stash)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
%{
+
clay: %{ore: 2},
+
geode: %{obsidian: 7, ore: 2},
+
max: %{clay: 14, obsidian: 7, ore: 4},
+
obsidian: %{clay: 14, ore: 3},
+
ore: %{ore: 4}
+
}
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
[
+
obsidian: %{clay: 21, geode: 0, obsidian: 0, ore: 1},
+
nil: %{clay: 35, geode: 0, obsidian: 0, ore: 4}
+
]
+
```
+
+
```elixir
+
plans
+
# |> Enum.drop(1)
+
|> Enum.take(1)
+
|> Kino.inspect()
+
|> Enum.map(fn plan -> Blueprint.produce(plan, 24, %{ore: 1}) end)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
[
+
%{
+
clay: %{ore: 2},
+
geode: %{obsidian: 7, ore: 2},
+
max: %{clay: 14, obsidian: 7, ore: 4},
+
obsidian: %{clay: 14, ore: 3},
+
ore: %{ore: 4}
+
}
+
]
+
```
+15
2022/day20.livemd
···
+
<!-- livebook:{"persist_outputs":true} -->
+
+
# Day 20
+
+
```elixir
+
Mix.install([
+
{:kino_aoc, git: "https://github.com/ljgago/kino_aoc"}
+
])
+
```
+
+
## Section
+
+
```elixir
+
+
```
+78 -1
2022/day21.livemd
···
<!-- livebook:{"output":true} -->
```
+
* Getting kino_aoc (https://github.com/ljgago/kino_aoc)
+
remote: Enumerating objects: 78, done.
+
remote: Counting objects: 100% (78/78), done.
+
remote: Compressing objects: 100% (50/50), done.
+
remote: Total 78 (delta 25), reused 67 (delta 18), pack-reused 0
+
origin/HEAD set to main
+
Resolving Hex dependencies...
+
Dependency resolution completed:
+
New:
+
castore 0.1.20
+
finch 0.14.0
+
hpax 0.1.2
+
jason 1.4.0
+
kino 0.8.0
+
mime 2.0.3
+
mint 1.4.2
+
nimble_options 0.5.2
+
nimble_pool 0.2.6
+
req 0.3.4
+
table 0.1.2
+
telemetry 1.2.0
+
* Getting kino (Hex package)
+
* Getting req (Hex package)
+
* Getting finch (Hex package)
+
* Getting jason (Hex package)
+
* Getting mime (Hex package)
+
* Getting castore (Hex package)
+
* Getting mint (Hex package)
+
* Getting nimble_options (Hex package)
+
* Getting nimble_pool (Hex package)
+
* Getting telemetry (Hex package)
+
* Getting hpax (Hex package)
+
* Getting table (Hex package)
+
==> table
+
Compiling 5 files (.ex)
+
Generated table app
+
==> mime
+
Compiling 1 file (.ex)
+
Generated mime app
+
==> nimble_options
+
Compiling 3 files (.ex)
+
Generated nimble_options app
+
==> kino
+
Compiling 37 files (.ex)
+
Generated kino app
+
===> Analyzing applications...
+
===> Compiling telemetry
+
==> jason
+
Compiling 10 files (.ex)
+
Generated jason app
+
==> hpax
+
Compiling 4 files (.ex)
+
Generated hpax app
+
==> nimble_pool
+
Compiling 2 files (.ex)
+
Generated nimble_pool app
+
==> castore
+
Compiling 1 file (.ex)
+
Generated castore app
+
==> mint
+
Compiling 1 file (.erl)
+
Compiling 19 files (.ex)
+
Generated mint app
+
==> finch
+
Compiling 13 files (.ex)
+
Generated finch app
+
==> req
+
Compiling 5 files (.ex)
+
Generated req app
+
==> kino_aoc
+
Compiling 3 files (.ex)
+
Generated kino_aoc app
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
:ok
```
## Section
-
<!-- livebook:{"attrs":{"day":"21","session_secret":"ADVENT_OF_CODE_SESSION","variable":"puzzle_input","year":"2022"},"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
<!-- livebook:{"attrs":{"day":"21","session_secret":"ADVENT_OF_CODE_SESSION","variable":"puzzle_input","year":"2022"},"chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
```elixir
{:ok, puzzle_input} =
+15
2022/day22.livemd
···
+
<!-- livebook:{"persist_outputs":true} -->
+
+
# Day 22
+
+
```elixir
+
Mix.install([
+
{:kino_aoc, git: "https://github.com/ljgago/kino_aoc"}
+
])
+
```
+
+
## Section
+
+
```elixir
+
+
```
+15
2022/day23.livemd
···
+
<!-- livebook:{"persist_outputs":true} -->
+
+
# Day 23
+
+
```elixir
+
Mix.install([
+
{:kino_aoc, git: "https://github.com/ljgago/kino_aoc"}
+
])
+
```
+
+
## Section
+
+
```elixir
+
+
```
+15
2022/day24.livemd
···
+
<!-- livebook:{"persist_outputs":true} -->
+
+
# Day 24
+
+
```elixir
+
Mix.install([
+
{:kino_aoc, git: "https://github.com/ljgago/kino_aoc"}
+
])
+
```
+
+
## Section
+
+
```elixir
+
+
```
+15
2022/day25.livemd
···
+
<!-- livebook:{"persist_outputs":true} -->
+
+
# Day 25
+
+
```elixir
+
Mix.install([
+
{:kino_aoc, git: "https://github.com/ljgago/kino_aoc"}
+
])
+
```
+
+
## Section
+
+
```elixir
+
+
```