this repo has no description

Compare changes

Choose any two refs to compare.

+100
2019/1/input.txt
···
+
54172
+
58469
+
92948
+
143402
+
57563
+
54532
+
68042
+
89847
+
70872
+
54069
+
107310
+
146439
+
88851
+
142869
+
71309
+
89613
+
70338
+
87708
+
95305
+
134384
+
128250
+
134991
+
91270
+
127819
+
68650
+
102556
+
129882
+
68688
+
129939
+
137344
+
102624
+
90828
+
86487
+
91712
+
114866
+
75697
+
107599
+
99053
+
87511
+
128128
+
57772
+
69314
+
90771
+
145376
+
100730
+
142675
+
112731
+
83985
+
123565
+
127325
+
86597
+
121772
+
131992
+
148859
+
93348
+
77294
+
119763
+
74636
+
95592
+
79628
+
78861
+
68565
+
88820
+
134291
+
69262
+
128678
+
118216
+
52799
+
92731
+
61600
+
63477
+
64016
+
131872
+
131412
+
146579
+
104400
+
99110
+
63458
+
144393
+
54787
+
148622
+
91323
+
61137
+
106082
+
103644
+
63795
+
126648
+
61489
+
140964
+
110963
+
72696
+
124370
+
110466
+
139317
+
108440
+
148062
+
89992
+
145645
+
70556
+
95739
+19
2019/1/solution.exs
···
+
defmodule Main do
+
def calculate(value), do: max(div(value, 3) - 2, 0)
+
+
def for_fuel(value), do: for_fuel(value, value)
+
+
defp for_fuel(0, total), do: total
+
defp for_fuel(value, total) do
+
current = calculate(value)
+
+
for_fuel(current, total + current)
+
end
+
end
+
+
IO.stream(:stdio, :line)
+
|> Stream.map(&String.to_integer(String.trim(&1)))
+
|> Stream.map(&Main.calculate/1)
+
|> Stream.map(&Main.for_fuel/1)
+
|> Enum.reduce(&+/2)
+
|> IO.inspect()
+1
2019/2/input.txt
···
+
1,0,0,3,1,1,2,3,1,3,4,3,1,5,0,3,2,1,10,19,1,6,19,23,1,10,23,27,2,27,13,31,1,31,6,35,2,6,35,39,1,39,5,43,1,6,43,47,2,6,47,51,1,51,5,55,2,55,9,59,1,6,59,63,1,9,63,67,1,67,10,71,2,9,71,75,1,6,75,79,1,5,79,83,2,83,10,87,1,87,5,91,1,91,9,95,1,6,95,99,2,99,10,103,1,103,5,107,2,107,6,111,1,111,5,115,1,9,115,119,2,119,10,123,1,6,123,127,2,13,127,131,1,131,6,135,1,135,10,139,1,13,139,143,1,143,13,147,1,5,147,151,1,151,2,155,1,155,5,0,99,2,0,14,0
+41
2019/2/solution.exs
···
+
defmodule GravAssist do
+
def calc([op, _, _ | rest], a \\ 12, b \\ 2) do
+
hd(execute([op, a, b | rest]))
+
end
+
+
def execute(bytecode) when is_list(bytecode), do: execute(:array.from_list(bytecode))
+
def execute(bytecode), do: eval(bytecode, 0)
+
+
defp eval(bytecode, ic) do
+
case :array.get(ic, bytecode) do
+
99 -> :array.to_list(bytecode)
+
op when op in 1..2 ->
+
pos_a = :array.get(ic + 1, bytecode)
+
pos_b = :array.get(ic + 2, bytecode)
+
pos_r = :array.get(ic + 3, bytecode)
+
+
result = compute(op, :array.get(pos_a, bytecode), :array.get(pos_b, bytecode))
+
+
new_bc = :array.set(pos_r, result, bytecode)
+
+
eval(new_bc, ic + 4)
+
_ -> :error
+
end
+
end
+
+
defp compute(1, a, b), do: a + b
+
defp compute(2, a, b), do: a * b
+
end
+
+
data =
+
IO.read(:line)
+
|> String.split(",")
+
|> Enum.map(&String.to_integer(String.trim(&1)))
+
+
IO.inspect(GravAssist.calc(data), label: :sol1)
+
+
for(a <- 0..99,
+
b <- 0..99,
+
19690720 == GravAssist.calc(data, a, b),
+
do: {a, b})
+
|> IO.inspect(label: :sol2)
+2
2019/3/input.txt
···
+
R997,D543,L529,D916,R855,D705,L159,U444,R234,U639,L178,D682,L836,U333,R571,D906,L583,U872,L733,U815,L484,D641,R649,U378,L26,U66,L659,D27,R4,U325,L264,D711,L837,D986,L38,U623,L830,D369,L469,D704,L302,U143,L771,U170,R237,U477,L251,D100,R561,D889,R857,D780,R258,D299,L975,D481,L692,D894,R847,D416,R670,D658,L537,U748,R468,D304,L263,D884,R806,D13,R288,U933,R4,U291,L809,D242,R669,D50,R106,D510,R409,U311,R101,D232,R370,D490,L762,D805,L981,D637,L987,U403,R965,U724,L404,D664,L687,U868,L808,D174,L363,D241,L54,D238,R444,U75,R683,U712,L759,D569,R349,D378,L576,U437,R137,D822,R21,D595,L602,U147,R959,U350,R964,U625,L718,U331,L252,D386,L251,U371,R973,D709,R915,D837,L7,U727,L501,D520,L626,U161,L287,D224,L821,U555,L312,U234,L335,D572,L113,U673,L615,D919,R925,U16,R211,U77,R630,U786,R850,D221,R939,U559,R887,U779,L222,D482,L252,D682,L904,U568,R317,D453,R689,D917,R845,U260,R69,U613,R528,D447,L791,D119,L268,U215,L806,U786,R465,D787,L792,D823,R526,D709,L362,D748,L518,U115,L898,U784,R893,U911,R98,U215,R828,D100,R153,U496,L938,D403,R886,D317,L849,D59,R156,D27,L64,D771,R956,U880,R313,D244,L483,D17,R72,U467,L475,D444,R554,D781,R524,D152,L771,U435,L622,D601,R733,D478,L686,D12,L525,D467,L302,D948,L966,U572,L303,U914,R54,D417,R635,D425,R640,D703,R17,D187,L195,U59,R166,D616,L557,U458,L743,D166,R328,D640,R908,D775,L151,D216,L964,D202,L534,D239,R998,U167,L604,D812,L527,U526,L640,U93,L733,D980,R607,D879,L593,D721,R454,U137,R683,D343,L38,D398,L81,U392,R821,U247,L361,D208,R763,D771,L515
+
L1000,D189,L867,U824,L193,D12,R704,U83,R371,D858,L970,D56,R877,D448,R962,U239,R641,D198,L840,D413,R586,D920,R650,U919,R375,D540,L150,U995,R54,D200,R61,D974,R249,U893,R319,U930,R658,U680,R286,D186,R963,U553,L256,U629,L554,U576,R887,U595,R629,D680,L684,U556,L302,U348,R825,D252,L684,U705,L258,D72,R907,U702,L518,U440,R239,U258,R825,U27,L580,D613,R357,D468,R519,U833,L415,D822,L798,U904,R812,U76,R86,U252,R427,U637,L896,U147,L294,U381,R306,U423,L688,D336,R648,U677,L750,D218,L649,D360,R710,D64,R317,U232,R261,D167,L49,D138,L431,D505,L535,U294,L553,U969,L144,U227,R437,D397,R359,U848,L48,D992,R169,D580,L219,D525,R552,U546,R849,D722,R894,D735,L182,U570,R274,D349,R312,U430,R441,U183,R645,D308,L416,U333,L687,U202,L973,D736,R382,U260,L176,D207,R706,U52,L142,D746,L328,D413,R879,D429,L679,D695,L224,D462,R358,D124,L515,D629,L873,D759,L763,U28,R765,D426,L93,U927,L395,U243,L393,D488,L729,U100,R488,D83,R47,U92,L871,D410,R405,D993,R537,D10,L79,D218,L686,D563,L31,U885,L784,D462,L160,U345,R204,U275,R162,U164,R843,D578,R255,D456,L398,U470,L576,D973,L337,D971,R205,U264,R707,U975,L60,U270,R1,U808,R844,D884,L952,D435,L144,D374,R389,D741,R404,D398,R282,D807,L316,U136,L504,U720,R859,D925,L711,U343,L535,D978,R578,U636,L447,D298,R574,U590,L142,D802,L846,D617,L838,U362,R812,U295,L328,U162,L617,D857,L759,D251,L343,U394,R721,U320,R836,U726,L950,D612,R129,U549,L970,D87,L341,D269,L659,U550,R835,D318,L189,U278,R871,D62,R703,U807,L389,U824,R521,D175,L698,U313,L942,D810,L498,U18,R168,D111,R607
+57
2019/3/solution.exs
···
+
defmodule Wires do
+
@directions %{
+
?U => :up,
+
?D => :down,
+
?R => :right,
+
?L => :left
+
}
+
+
@moves %{
+
up: {0, 1},
+
down: {0, -1},
+
right: {1, 0},
+
left: {-1, 0}
+
}
+
+
def load(list) do
+
list
+
|> Enum.map(&parse/1)
+
|> wire()
+
end
+
+
defp parse(<<c, rest::binary>>) do
+
{Map.fetch!(@directions, c), String.to_integer(rest)}
+
end
+
+
defp wire(steps) do
+
steps
+
|> Enum.reduce({[], {0, 0}}, &into_coordinates/2)
+
|> elem(0)
+
|> MapSet.new()
+
end
+
+
defp into_coordinates({_, 0}, {points, curr}), do: {[curr | points], curr}
+
defp into_coordinates({dir, n}, {points, {x, y}}) do
+
{dx, dy} = Map.fetch!(@moves, dir)
+
next = {x + dx, y + dy}
+
+
into_coordinates({dir, n - 1}, {[next | points], next})
+
end
+
end
+
+
w1 =
+
IO.read(:line)
+
|> String.trim()
+
|> String.split(",")
+
|> Wires.load()
+
w2 =
+
IO.read(:line)
+
|> String.trim()
+
|> String.split(",")
+
|> Wires.load()
+
+
MapSet.intersection(w1, w2)
+
|> MapSet.to_list()
+
|> Enum.map(fn {x, y} -> abs(x) + abs(y) end)
+
|> Enum.min()
+
|> IO.inspect()
+87
2020/day01.livemd
···
+
<!-- livebook:{"persist_outputs":true} -->
+
+
# Day 01
+
+
```elixir
+
Mix.install([:kino_aoc])
+
```
+
+
## Section
+
+
<!-- livebook:{"attrs":"eyJhc3NpZ25fdG8iOiJwdXp6bGVfaW5wdXQiLCJkYXkiOiIxIiwic2Vzc2lvbl9zZWNyZXQiOiJBRFZFTlRfT0ZfQ09ERV9TRVNTSU9OIiwieWVhciI6IjIwMjAifQ","chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2020", "1", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:ok,
+
"1706\n1466\n1427\n1744\n1684\n1386\n2001\n1750\n1753\n1770\n1559\n1616\n1408\n1860\n1940\n2002\n1862\n1918\n1456\n1209\n1840\n1462\n1783\n1644\n1901\n1791\n1506\n2005\n1338\n1383\n1420\n1631\n1784\n1897\n1771\n1588\n1955\n1937\n1392\n1396\n1803\n1429\n1407\n1698\n1562\n1913\n1678\n1198\n1398\n1703\n1831\n1489\n1782\n1864\n1708\n1397\n1915\n1953\n1395\n1610\n1549\n1564\n1973\n1931\n2009\n1980\n1800\n1443\n1993\n1900\n1964\n1581\n1904\n1665\n1567\n1057\n1805\n1402\n1878\n1729\n1825\n1682\n1719\n1469\n1004\n1591\n1594\n811\n1523\n1424\n1756\n373\n1442\n1718\n1411\n1892\n1820\n1977\n1871\n1890\n1653\n1372\n1475\n1476\n1422\n2004\n1755\n1676\n639\n1425\n1853\n1712\n1525\n1514\n1455\n1658\n1963\n1579\n1861\n1458\n1474\n1613\n1681\n1586\n1441\n1499\n1865\n1735\n1989\n1952\n792\n1669\n1509\n1481\n1893\n1445\n1834\n1779\n1732\n1826\n1595\n1829\n449\n1920\n1707\n1780\n1935\n1867\n1769\n1107\n919\n1382\n1604\n1875\n1453\n1496\n1946\n1659\n1570\n1692\n1630\n1638\n1922\n1691\n1580\n1880\n1482\n1762\n1775\n1376\n1434\n1856\n1971\n1646\n1951\n1416\n1889\n1773\n1814\n1471\n1488\n1736\n1743\n1459\n1389\n1498\n1663\n1611\n1727\n1699\n1624\n1511\n1767\n1754\n1785\n1491\n1235\n1510\n1500\n1485"}
+
```
+
+
```elixir
+
input =
+
puzzle_input
+
|> String.split("\n", trim: true)
+
|> Enum.map(&String.to_integer/1)
+
|> Enum.sort()
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
[373, 449, 639, 792, 811, 919, 1004, 1057, 1107, 1198, 1209, 1235, 1338, 1372, 1376, 1382, 1383,
+
1386, 1389, 1392, 1395, 1396, 1397, 1398, 1402, 1407, 1408, 1411, 1416, 1420, 1422, 1424, 1425,
+
1427, 1429, 1434, 1441, 1442, 1443, 1445, 1453, 1455, 1456, 1458, 1459, 1462, 1466, 1469, 1471,
+
1474, ...]
+
```
+
+
```elixir
+
defmodule Report do
+
def find([], _, _), do: nil
+
def find(_, _, sum) when sum < 0, do: nil
+
def find([a | _], 1, a), do: [a]
+
+
def find([a | rest], n, sum) do
+
case find(rest, n - 1, sum - a) do
+
nil -> find(rest, n, sum)
+
nums when is_list(nums) -> [a | nums]
+
end
+
end
+
end
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:module, Report, <<70, 79, 82, 49, 0, 0, 8, ...>>, {:find, 3}}
+
```
+
+
## Part 1
+
+
```elixir
+
Report.find(input, 2, 2020) |> Enum.product()
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
980499
+
```
+
+
## Part 2
+
+
```elixir
+
Report.find(input, 3, 2020) |> Enum.product()
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
200637446
+
```
+
+
<!-- livebook:{"offset":2857,"stamp":{"token":"XCP.XnJnYSRQgz2UOQ3-aY4Wm_4ac7Pe55mGzaFCONZvS7KA-jlyVQYcIKjXR6X8BV8b5w148g-6oYynzwJ-it0om0UAWkB3kajGGEYsa5LCmZRmUjW5iuT6zTZ5VoYqHjiwSc0","version":2}} -->
+133
2020/day02.livemd
···
+
<!-- livebook:{"persist_outputs":true} -->
+
+
# Day 02
+
+
```elixir
+
Mix.install([:kino_aoc])
+
```
+
+
## Section
+
+
<!-- livebook:{"attrs":"eyJhc3NpZ25fdG8iOiJwdXp6bGVfaW5wdXQiLCJkYXkiOiIyIiwic2Vzc2lvbl9zZWNyZXQiOiJBRFZFTlRfT0ZfQ09ERV9TRVNTSU9OIiwieWVhciI6IjIwMjAifQ","chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2020", "2", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:ok,
+
"5-10 b: bhbjlkbbbbbbb\n3-4 j: hjvj\n8-9 p: pmljtsttp\n3-4 t: hvtttqhdjmmnbqwbgfs\n4-6 m: mblwtzmvmdjkkmmtsckm\n6-9 f: ffffftfff\n1-3 g: xggg\n3-10 k: rwkhttkxxdpnlkq\n3-11 w: wwmwwwwwwwww\n5-7 f: fffffffff\n1-4 l: lglllbc\n2-5 n: njnnn\n6-8 t: tcjtltttttdttjttbt\n10-20 d: djddddccdbdddddddndd\n2-5 z: gzppzhrhzdthnpcr\n13-14 p: plvppptppppzppbkpk\n11-13 t: jjtjvzfhsrtsmkdhj\n11-12 r: rtrdvrrxrrxrzr\n2-6 x: dxsvxgvk\n7-11 x: hcxxpvxrnmxckkq\n12-17 s: sssssssssssrssssss\n2-4 v: vvpvvvjvvjvvqbvv\n15-18 h: thqhhhgjjqhhnhhznz\n8-11 j: jbmgbtmjtbb\n2-4 d: xxdfvp\n2-7 p: fftlppz\n9-13 d: dfddddddsdddds\n5-7 d: ddddddz\n2-3 h: hfbhhh\n1-4 k: rmkvkkkk\n16-17 w: wwwhwwwwwwwwwwwwq\n5-8 l: gllxllnlqlglrplk\n1-7 p: mhnpspp\n5-13 f: qhwffbtfzmdffztfjs\n2-8 f: fkjhvcbflbwhggtbbcb\n2-3 m: bcmldxmdh\n6-7 p: ppcpppw\n3-10 m: mmmmmmmmmj\n4-12 s: ssjssssssssmsss\n2-5 j: rmjnjtjjjj\n2-3 q: qqdqq\n10-15 v: vvvvvvvvvvvvvvdvvvvv\n1-4 w: wwwc\n4-14 m: mmsmmmvmmmmmqqmmmmm\n7-10 d: ddcdddzdddddd\n4-5 h: hhhhh\n9-17 p: ppppppppqppppppppp\n6-7 m: mqtmnms\n4-5 s: pssss\n2-6 t: tdttttpwttt\n7-8 l: llsxsllzlwl\n7-10 f: fflffffkqffffm\n3-4 f: cdfp\n3-4 z: zzzz\n6-7 s: sbssdvs\n3-4 g: ggdv\n11-16 l: lllllnbsqlfzwrfljkh\n3-4 k: tqkxxfk\n3-17 s: xshmvlmzrjdpnvlssn\n1-16 l: lzzvllgktckllmlltl\n5-6 l: qlltvl\n6-7 p: npvbpcp\n4-6 g: gmgvgn\n12-13 r: rrnlrrwrtvrrrrcrrrv\n11-12 h: hhvxhhhhwjhd\n13-14 p: pdppcsjtppppppvtwpj\n10-14 l: hljjkjxlfwzlllclzq\n18-19 z: zzzzzzzzzzzzzzztzhn\n11-12 p: hpspwrkqbnpp\n16-18 h: hhhhhhghhhhhhhhwhbh\n1-2 p: vpxnqqbgrxprmh\n13-19 m: mmmmmmmmmmmmqmmmmqm\n1-2 n: ncndsnl\n9-10 x: xxxxxxxxxgxxd\n9-12 w: wwwwwwwwwwzwwdfgwwp\n3-5 h: nqhvhzb\n4-5 j: jjjns\n10-12 f: ffffffffffff\n7-10 v: mgvrwvvsjw\n3-5 m: wpmmm\n3-10 s: ffsbvjdslsnshqs\n9-10 z: mgzzbjzqsz\n3-13 d: ddjdddddddddnd\n2-4 l: tqkfhpwvvmc\n1-3 z: zzzzzn\n3-5 l: ctljlckdpnlchrzbc\n6-7 v: hqvcvvv\n11-13 v: vvvvcvvvvvvvvvv\n8-9 t: ztndmlwdb\n5-6 v: fdxxrvwpw\n1-4 n: xnkb\n16-17 v: vvvvvvvvvvvvvvvvnvv\n12-14 b: bbbbbxbbbdbgbcb\n1-7 w: wwwwwwrwwjtwk\n3-10 d: bxnhbhrmgd\n4-5 k: kkknkk\n2-4 n: bndln\n3-10 p: vpkppcppppcplpksp\n9-10 d: fhbzbdzqsdxlhnbt\n11-13 z: zzmzzzzwzpzzz\n12-17 b: hkbcbbhthbrbbdgbl\n11-13 c: cpccnxccxbjtm\n5-6 n: nnrmnfnsnn\n3-8 l: sslkllwljcgl\n1-9 p: fpppzzpppppphtrhppp\n4-11 h: kskbvrqhdjph\n3-9 r: rsrvxnrchtrrrr\n4-5 n: nwbln\n3-4 g: gjgv\n13-14 r: rrrrrrsrtrrrrrrrr\n10-15 m: mmmmmmmmmtmmgmm\n5-6 k: wkpkkqk\n10-11 l: wlbllglkbltblrqlllm\n6-7 d: ddddsrddd\n17-18 v: vvvvvvvvvvvfvgvvsvv\n6-10 n: nngnnnnvnknn\n7-8 t: qdztnrnt\n5-11 d: dfbdxqbmsdd\n1-6 n: znnvqdnx\n7-9 k: kkkkkkkkl\n5-6 m: mmmszmtmmks\n1-5 l: wlllllll\n13-14 m: mcmmmmmlmmmmjmmm\n1-7 k: kklkjvckb\n14-15 d: ddddmddddmddddddd\n18-19 k: kfkkkkkkkkkkkkkkkpkk\n3-4 z: czjzc\n17-18 t: btttttjmltrttxctgt\n1-4 c: cccscqcccc\n9-14 k: tcwcstszkvhjfmrqpkp\n3-8 c: ccccccjcscncp\n10-11 d: dddddddddmdd\n3-5 m: rgmfmkmd\n1-5 k: mfhnk\n4-5 x: cwnxftlt\n1-3 n: flnqmnnhnn\n2-5 f: vwlcnsfd\n4-8 c: cccccccbc\n10-12 v: dhfvlvbvspjldzch\n7-16 f: ffsmffffjffqfpffff\n10-13 n: njtrrnnqntjtn\n13-17 f: frffcfffrjffffdfpff\n5-10 m: mmmmvfmmmmmmmmdm\n5-6 v: vvvvvzvvvvv\n6-12 r: dqrrcrhrhjsrrr\n8-14 z: zzzzzzzlzzzgzsz\n5-9 q: qkwzsvwdg\n12-13 d: vzjfvddgctfdrr\n6-7 f: mgndffb\n2-5 x: nxxmx\n7-9 c: cmxsccccf\n1-7 n: nnnnnnnnnn\n6-8 g: gggglfgp\n2-13 v: kvwxcrfmpfcfdrgv\n5-7 p: tpplpffpccpp\n8-12 m: mmmmmmmmmmmxm\n9-10 v: vvvvvvvvvcv\n4-5 m: mbnmmkknmmwshmkthj\n8-9 t: cltntrtpqwtcsftttf\n8-16 f: ffffrffpffffffffff\n6-8 t: sttcctttdttdwjdndtt\n5-9 k: ckkkkvdkvkk\n1-3 f: ffczfpgmf\n2-4 w: wwlwwd\n1-9 d: lddbhdddmtfdmdzdrdhd\n16-17 h: xfqlbhhpbnclvztzzzx\n2-7 r: rrbntqrrsrkrm\n1-4 r: qwrr\n12-14 b: tvbbzjbbbbbbbn\n5-7 h: hhjvghth\n2-3 d: dndrcx\n8-9 c: ccccscccpc\n5-8 s: srcsszcsp\n13-15 g: gggggggglggggglggggg\n11-13 b: bbbbbfrbfbbgbb\n1-8 b: jbbkqbbbpbbbbbbp\n11-14 n: nnnnnnnnnnmnnnn\n1-4 g: qsggg\n14-15 l: sllslllggllljkdlm\n1-5 s: pvssbspdsshsssssrs\n7-10 c: ccccccmcpgcc\n6-14 m: bcfkpmvmcmmjml\n1-3 n: ncnnnnn\n12-14 j: bjfjxjjpjrjjjxjjk\n10-12 v: vfvvvvvvqjvvvwvwt\n6-13 d: stddxdnjrddhwgdhrfjf\n5-6 w: qcwhnwwk\n2-3 x: mcxfxckptzvw\n12-20 b: lvgvbxsxxlvbhfcxbtzr\n1-2 d: ddbdqd\n5-10 h: mhtnjvhhhs\n2-6 z: ztzzdxzzzqbvg\n2-7 t: ttjkqztr\n3-4 g: bgvggrxrhtlklfj\n4-5 q: qqqvq\n1-3 c: ccpc\n4-6 j: jjrdjj\n8-11 c: ncvshccccccsb\n" <> ...}
+
```
+
+
```elixir
+
data =
+
puzzle_input
+
|> String.split("\n", trim: true)
+
|> Enum.map(fn input ->
+
[spec, pass] = String.split(input, ": ", parts: 2)
+
[range, char] = String.split(spec, " ", parts: 2)
+
+
[min, max] =
+
range
+
|> String.split("-", parts: 2)
+
|> Enum.map(&String.to_integer/1)
+
+
{min..max, char, pass}
+
end)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
[
+
{5..10, "b", "bhbjlkbbbbbbb"},
+
{3..4, "j", "hjvj"},
+
{8..9, "p", "pmljtsttp"},
+
{3..4, "t", "hvtttqhdjmmnbqwbgfs"},
+
{4..6, "m", "mblwtzmvmdjkkmmtsckm"},
+
{6..9, "f", "ffffftfff"},
+
{1..3, "g", "xggg"},
+
{3..10, "k", "rwkhttkxxdpnlkq"},
+
{3..11, "w", "wwmwwwwwwwww"},
+
{5..7, "f", "fffffffff"},
+
{1..4, "l", "lglllbc"},
+
{2..5, "n", "njnnn"},
+
{6..8, "t", "tcjtltttttdttjttbt"},
+
{10..20, "d", "djddddccdbdddddddndd"},
+
{2..5, "z", "gzppzhrhzdthnpcr"},
+
{13..14, "p", "plvppptppppzppbkpk"},
+
{11..13, "t", "jjtjvzfhsrtsmkdhj"},
+
{11..12, "r", "rtrdvrrxrrxrzr"},
+
{2..6, "x", "dxsvxgvk"},
+
{7..11, "x", "hcxxpvxrnmxckkq"},
+
{12..17, "s", "sssssssssssrssssss"},
+
{2..4, "v", "vvpvvvjvvjvvqbvv"},
+
{15..18, "h", "thqhhhgjjqhhnhhznz"},
+
{8..11, "j", "jbmgbtmjtbb"},
+
{2..4, "d", "xxdfvp"},
+
{2..7, "p", "fftlppz"},
+
{9..13, "d", "dfddddddsdddds"},
+
{5..7, "d", "ddddddz"},
+
{2..3, "h", "hfbhhh"},
+
{1..4, "k", "rmkvkkkk"},
+
{16..17, "w", "wwwhwwwwwwwwwwwwq"},
+
{5..8, "l", "gllxllnlqlglrplk"},
+
{1..7, "p", "mhnpspp"},
+
{5..13, "f", "qhwffbtfzmdffztfjs"},
+
{2..8, "f", "fkjhvcbflbwhggtbbcb"},
+
{2..3, "m", "bcmldxmdh"},
+
{6..7, "p", "ppcpppw"},
+
{3..10, "m", "mmmmmmmmmj"},
+
{4..12, "s", "ssjssssssssmsss"},
+
{2..5, "j", "rmjnjtjjjj"},
+
{2..3, "q", "qqdqq"},
+
{10..15, "v", "vvvvvvvvvvvvvvdvvvvv"},
+
{1..4, "w", "wwwc"},
+
{4..14, "m", "mmsmmmvmmmmmqqmmmmm"},
+
{7..10, "d", "ddcdddzdddddd"},
+
{4..5, "h", "hhhhh"},
+
{9..17, "p", "ppppppppqppppppppp"},
+
{6..7, "m", ...},
+
{4..5, ...},
+
{...},
+
...
+
]
+
```
+
+
## Part 1
+
+
```elixir
+
Enum.count(data, fn {range, <<char>>, pass} ->
+
count = for <<^char <- pass>>, reduce: 0, do: (n -> n + 1)
+
+
count in range
+
end)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
439
+
```
+
+
## Part 2
+
+
```elixir
+
Enum.count(data, fn {a..b//1, char, pass} ->
+
char_1 = binary_part(pass, a - 1, 1)
+
char_2 = binary_part(pass, b - 1, 1)
+
+
char_1 != char_2 and char in [char_1, char_2]
+
end)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
584
+
```
+
+
<!-- livebook:{"offset":7223,"stamp":{"token":"XCP.hfrcfr0pT-nj7-j4nWaJo4YFPkw0SkyS5kkbU0031loYsccpQ9B5PfrwwU0eiuPMlC2H5sN-qI3EDIk0RJZEkgYu4EvABNl_2k4g0_4hLnQxFsTtp8-IrIUPuzEQJLdGAJ4","version":2}} -->
+124
2020/day03.livemd
···
+
<!-- livebook:{"persist_outputs":true} -->
+
+
# Day 03
+
+
```elixir
+
Mix.install([:kino_aoc])
+
```
+
+
## Section
+
+
<!-- livebook:{"attrs":"eyJhc3NpZ25fdG8iOiJwdXp6bGVfaW5wdXQiLCJkYXkiOiIzIiwic2Vzc2lvbl9zZWNyZXQiOiJBRFZFTlRfT0ZfQ09ERV9TRVNTSU9OIiwieWVhciI6IjIwMjAifQ","chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2020", "3", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:ok,
+
"....#...##.#.........#....#....\n#.......#...#...#.#............\n#..#..#.#.##....#.#........#...\n........##...................#.\n........#...##...#.#.###.......\n##............#...#.....#.##...\n...........#....###...#.....#..\n.......#......#..##..#.....#...\n..#.#..#....#.........#...#..#.\n.........##......#.....##..##..\n........#.....#....#..##......#\n..#..#.......#..............#..\n.....#.#.......................\n.#.#....#.........#............\n.......#.....#.###.............\n......##......#...........#..#.\n.#...............##...#........\n.....#..##........###.........#\n#...........#..#............#..\n.........#....#..#.#......#....\n.......#.........#..##.........\n.##.....#..................#...\n....#............#.#....#.....#\n..#....#...##....#...#.#...#...\n..........#................#.#.\n#...#.#.#.####..#.#..........#.\n..#...#.##......#...........#..\n..#.....#...#.......#......#..#\n..............#.......#........\n.#..#..........#.....#...#..#.#\n#........#...#......#.......#..\n#..................#...........\n..#...#........#...#..#........\n..............#.....#.....#..#.\n#.#.......#..............##.##.\n....#.#.....##....#...........#\n......#....#...#..#.......#....\n....#..#.#.....#..##.....#....#\n...........#.......#.#.#.......\n#.......#..##........#..#......\n.........#.##..#..............#\n...........#............###.#..\n..#.....#.....##...#.........#.\n....##............##........#..\n.....###..........#......##....\n#...##..#..#..........#........\n....#.....#.......#..#.#...##..\n.#....#........#.#.........#.#.\n##...#.#.....#......#..........\n.....##.....#....#.....###.#..#\n..............#..###..#...#..#.\n....#...#....#.............#.#.\n.#.........#.....#........#.##.\n....#.........#..........#.....\n.......#........#.#.#..........\n#........##....#.........#.....\n..##..........#....#.#...#....#\n#...#.#......#..##..........#.#\n.....#..#...#..#...............\n#...#..............#...........\n.#...#....#..##.....#....#.#...\n.#...#.......#...#..#.##....#..\n#....#........#....#...#.......\n#..#......#.....#.....#..##....\n......#.#....##....##..#...#...\n..#....#.#.###..............#..\n.#.##.......#.#.#..#...#..#....\n..#..........#.#....#..#.#....#\n..........#...#...#..........#.\n..........#.....#.#..#..#....##\n.#.#...##...#...........####...\n........##..#.#..........#.##.#\n#......###...........#...#.....\n..#.#....##.........##....#....\n#....#.##..##..#..#.....#.....#\n.##.....##....##....#.......#..\n#...#.....##....#..........#...\n............#.#.##....#....#...\n....#............#.....#......#\n....................#..........\n..#....................#..#....\n....#.....#........#..##...#...\n#.....#.#....................##\n.#....#.#.#...#..........#....#\n....#...#......#...#.....##...#\n.....#.........................\n.......#..#.#...#...#...#.....#\n...#......#.##.#...#..#...##.#.\n...........................#..#\n..#.#.....#........##..........\n....#...##........#.#.#..#...##\n..##.....#..###.........##.##..\n.#..#.....#...#.............#..\n#..............##...#....##....\n.##......#.#............#......\n.............##...#.#.......#..\n.........#..#..#...............\n........##......#....##........\n...#.........#.#.#.............\n#..........#......#......#..#..\n.............##.#.#..#.#.#...#.\n.....#.........#...............\n..##.#..#.....##..#........#.#.\n.#..........#.#.......#......##\n.#........................#....\n#....#....#...#..#......#......\n........#.......#......#.....#.\n.....#....##..#...###...#....#.\n....#.........#....#......#....\n.............#...#....#.......#\n.....#.........#..#.#..........\n.........#..#........#.#.#.....\n......#.##......#....#.#.##.#..\n.#...#.#...#...#.#......#....##\n.#................#......#.....\n#.#.#...............#..........\n.....#.#.......#...#........#..\n#...#.#.#.##..#...........#..#.\n.............###.........#....#\n.#.....#.......##....##.......#\n....#...#.......#.##.....#.....\n...........##.........#...#....\n..............#.#..#.....#..#..\n#.#...#..#.#.........#......#.#\n#.##.....##....#........#.#.#.#\n##.#.###.........##.......#..#.\n#.....#.....................#..\n.........##........#...........\n" <> ...}
+
```
+
+
```elixir
+
slope =
+
puzzle_input
+
|> String.split("\n", trim: true)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
["....#...##.#.........#....#....", "#.......#...#...#.#............",
+
"#..#..#.#.##....#.#........#...", "........##...................#.",
+
"........#...##...#.#.###.......", "##............#...#.....#.##...",
+
"...........#....###...#.....#..", ".......#......#..##..#.....#...",
+
"..#.#..#....#.........#...#..#.", ".........##......#.....##..##..",
+
"........#.....#....#..##......#", "..#..#.......#..............#..",
+
".....#.#.......................", ".#.#....#.........#............",
+
".......#.....#.###.............", "......##......#...........#..#.",
+
".#...............##...#........", ".....#..##........###.........#",
+
"#...........#..#............#..", ".........#....#..#.#......#....",
+
".......#.........#..##.........", ".##.....#..................#...",
+
"....#............#.#....#.....#", "..#....#...##....#...#.#...#...",
+
"..........#................#.#.", "#...#.#.#.####..#.#..........#.",
+
"..#...#.##......#...........#..", "..#.....#...#.......#......#..#",
+
"..............#.......#........", ".#..#..........#.....#...#..#.#",
+
"#........#...#......#.......#..", "#..................#...........",
+
"..#...#........#...#..#........", "..............#.....#.....#..#.",
+
"#.#.......#..............##.##.", "....#.#.....##....#...........#",
+
"......#....#...#..#.......#....", "....#..#.#.....#..##.....#....#",
+
"...........#.......#.#.#.......", "#.......#..##........#..#......",
+
".........#.##..#..............#", "...........#............###.#..",
+
"..#.....#.....##...#.........#.", "....##............##........#..",
+
".....###..........#......##....", "#...##..#..#..........#........",
+
"....#.....#.......#..#.#...##..", ".#....#........#.#.........#.#.",
+
"##...#.#.....#......#..........", ".....##.....#....#.....###.#..#", ...]
+
```
+
+
```elixir
+
binary_slice("abc", 5, 1)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
""
+
```
+
+
```elixir
+
defmodule Toboggan do
+
def slide(slope, {dx, dy}) do
+
slope
+
|> Enum.take_every(dy)
+
|> Enum.reduce({0, 0}, fn row, {pos, count} ->
+
dc = if binary_part(row, rem(pos, byte_size(row)), 1) == "#", do: 1, else: 0
+
+
{pos + dx, count + dc}
+
end)
+
|> elem(1)
+
end
+
end
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:module, Toboggan, <<70, 79, 82, 49, 0, 0, 9, ...>>, {:slide, 2}}
+
```
+
+
## Part 1
+
+
```elixir
+
Toboggan.slide(slope, {3, 1})
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
254
+
```
+
+
## Part 2
+
+
```elixir
+
[
+
{1, 1},
+
{3, 1},
+
{5, 1},
+
{7, 1},
+
{1, 2}
+
]
+
|> Enum.map(&Toboggan.slide(slope, &1))
+
|> Enum.product()
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
1666768320
+
```
+
+
<!-- livebook:{"offset":7450,"stamp":{"token":"XCP.NoSFu8ULnZhWAsLV6KwdSJblZR21o6kgNjJs3gczqJcYu7u7w_HScRZAL77iGr_ANQuyNyfr_CBU1KjRZ9e7nllBTnLxF6esiGCVXrSCKYPlWFFGN8VONns6BoBdQss9DU8","version":2}} -->
+484
2020/day04.livemd
···
+
<!-- livebook:{"persist_outputs":true} -->
+
+
# Day 04
+
+
```elixir
+
Mix.install([:kino_aoc])
+
```
+
+
## Section
+
+
<!-- livebook:{"attrs":"eyJhc3NpZ25fdG8iOiJwdXp6bGVfaW5wdXQiLCJkYXkiOiI0Iiwic2Vzc2lvbl9zZWNyZXQiOiJBRFZFTlRfT0ZfQ09ERV9TRVNTSU9OIiwieWVhciI6IjIwMjAifQ","chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2020", "4", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:ok,
+
"hcl:#6b5442 ecl:brn iyr:2019\npid:637485594 hgt:171cm\neyr:2021 byr:1986\n\neyr:2025 iyr:1938 byr:2014 hcl:#341e13\nhgt:66cm\npid:70195175\n\nhcl:#efcc98\niyr:2011 ecl:hzl\neyr:2020 hgt:174cm pid:589700330\n\nhcl:#bba027 eyr:2027 cid:54\necl:brn pid:153cm\niyr:2028 hgt:173cm\nbyr:2004\n\nhcl:b45cec\niyr:2011 ecl:oth hgt:185cm eyr:2029 pid:178cm\n\nhgt:185cm iyr:2016 eyr:2029 hcl:#888785 pid:026540921\n\neyr:2025\nhcl:6962f7 byr:2015 ecl:oth iyr:1974\nhgt:191cm\npid:2616015\n\npid:268398556 iyr:2019 ecl:grn\neyr:2027 byr:1951 hcl:#18171d hgt:67cm\n\neyr:2029 hgt:153cm ecl:brn pid:183179186 byr:2013 hcl:#623a2f\niyr:1957\n\ncid:121 iyr:1922 hcl:752fbc pid:79577560 byr:2025\nhgt:61cm eyr:1971\n\niyr:2016\neyr:2024 hcl:#18171d hgt:184cm\necl:hzl byr:1992 pid:751161201\n\neyr:2021 ecl:blu byr:1938 iyr:2016 hcl:#b6652a pid:313406514 hgt:191cm\n\nhcl:#623a2f eyr:2021\necl:brn\npid:145249653 hgt:167cm iyr:2019 byr:1991\n\niyr:2022 pid:175cm\nbyr:2021 eyr:2027 ecl:#f615b1\nhgt:172in hcl:#ceb3a1\n\nhgt:173in\necl:#0cba5e pid:1885981567 iyr:1968\nbyr:1952\neyr:1942\n\necl:oth eyr:2023 hgt:65cm pid:521737908 byr:1971 hcl:z iyr:2017\n\nbyr:1936\nhcl:#cfa07d\necl:brn iyr:2011 pid:589047874\neyr:2025\n\nhcl:#fffffd\npid:912552538\ncid:159 hgt:160cm iyr:2012\neyr:2023 ecl:hzl\nbyr:1946\n\niyr:2015\necl:amb hgt:72in\ncid:59 pid:782818257 hcl:#18171d eyr:2026\nbyr:1952\n\nhgt:173cm iyr:2018 cid:96 ecl:amb byr:1986 pid:783160698 eyr:2026\nhcl:#602927\n\nhcl:#a97842 cid:199 pid:912273414 eyr:2030\nhgt:171cm ecl:hzl iyr:2011 byr:1960\n\necl:amb hgt:156cm\niyr:2013\nhcl:#ceb3a1\ncid:116 pid:567057004 byr:1942\neyr:2029\n\necl:#cddc40\npid:045090966 cid:254\nhgt:75in hcl:#733820 eyr:2026 byr:1956\niyr:2015\n\npid:156cm\neyr:2040\nhgt:176cm ecl:#02e67d hcl:b7c0e6\niyr:1959 cid:129 byr:2022\n\nhgt:160cm byr:1933\necl:blu eyr:2029 iyr:2012 hcl:#888785 pid:028571975\n\niyr:2017\nhcl:#390f37 hgt:171cm ecl:brn byr:1931 pid:015365720 eyr:2030\n\niyr:2014 pid:697057757\neyr:2026 hgt:188cm\necl:gry byr:1926\n\npid:484310015 hcl:#fffffd hgt:150cm iyr:2018\ncid:53 ecl:gry eyr:2021 byr:1957\n\nhgt:156cm\neyr:2026 byr:1963\npid:063272603 ecl:brn iyr:2011\nhcl:#888785\n\nbyr:1955 pid:310518398 hgt:191cm iyr:2018\necl:oth eyr:2023 cid:132 hcl:#888785\n\nbyr:1938 hcl:#623a2f eyr:2023\niyr:2010\nhgt:165cm\npid:170304863\ncid:290 ecl:amb\n\neyr:2026\npid:021468065 hgt:164cm\nbyr:1996 iyr:2016 hcl:#18171d\necl:brn\n\nbyr:2027 ecl:oth pid:8258823391 hgt:153in hcl:#733820 eyr:1948\n\nbyr:2026 ecl:#cd275a iyr:2012 eyr:2036 pid:5917499975\n\nbyr:2004\ncid:151\nhcl:99ecb1\neyr:2033 pid:871137711 iyr:1997\nhgt:184cm ecl:oth\n\nbyr:2011\nhcl:z ecl:#eee1d2 hgt:59cm eyr:1925 iyr:2030 pid:#02ee78\n\npid:742658992\nhcl:#888785\nbyr:1995\neyr:2024 hgt:162cm iyr:2013 cid:169 ecl:gry\n\nhgt:152cm byr:1946\neyr:2027 iyr:2018\npid:352799678\nhcl:#238da0\necl:amb\ncid:71\n\nhcl:#623a2f pid:723616064 eyr:2021\nhgt:172cm\nbyr:1926 iyr:2013\necl:grn\n\niyr:2019 hgt:94 byr:2028 eyr:1986\npid:#ee7f00\n\necl:amb\neyr:2027 pid:188153423 byr:1957 hcl:#d67ae1\niyr:2011 hgt:183cm\n\nbyr:1950 ecl:#e2495d iyr:2010 hgt:166cm eyr:2034 pid:151457075\n\neyr:1981\nbyr:2016 iyr:2029 pid:153cm ecl:#55c2a4 hcl:z\nhgt:76cm\n\nhgt:184cm ecl:amb eyr:2021\nhcl:#623a2f\npid:414607669 iyr:1960 byr:2002\n\neyr:2027 iyr:2020 hgt:179cm byr:1991\npid:969568248\necl:blu\n\nhgt:175cm pid:536803427 hcl:#a97842 iyr:2012\necl:grn byr:1950 eyr:2027\n\neyr:2028 hgt:60in hcl:#733820 iyr:2018 ecl:oth pid:871909483\nbyr:1930\n\nhgt:155cm iyr:2020 byr:1960 eyr:2021\npid:515710074 ecl:amb hcl:#341e13\n\nbyr:1922 hcl:z iyr:1977 ecl:brn\neyr:2023 hgt:119 pid:865700639\n\necl:gry hcl:959fcd pid:#633ac1\nbyr:2011 hgt:68in\neyr:2020\n\niyr:1972 hcl:z cid:149 byr:2020\nhgt:166in pid:4548657 eyr:1960\necl:#cc987c\n\neyr:2023 hcl:#b6652a iyr:2015\nhgt:187in pid:547953710 byr:1979 ecl:grn\n\niyr:2018\npid:508691429 ecl:oth eyr:2025 hgt:187cm cid:270\nhcl:#888785 byr:1977\n\nhgt:168cm eyr:2032 byr:2020\necl:gry iyr:1982\nhcl:z pid:648015564\n\nhcl:#fffffd pid:911858643 iyr:2016 ecl:gry eyr:2030 byr:1992 hgt:156cm\n\npid:241562994 eyr:2026 ecl:grn hgt:164cm\nhcl:#c0946f byr:1945 iyr:2015 cid:296\n\nbyr:1976 pid:269322775 ecl:hzl\nhgt:162cm hcl:#b6652a\neyr:2022 cid:335 iyr:2012\n\neyr:2028\nhgt:106\npid:268626219 hcl:#a97842\niyr:2011\necl:grn byr:" <> ...}
+
```
+
+
```elixir
+
passports =
+
puzzle_input
+
|> String.split("\n\n", trim: true)
+
|> Enum.map(fn passport ->
+
passport
+
|> String.split(~r/\s/, trim: true)
+
|> Map.new(fn <<key::3-binary, ":", data::binary>> ->
+
{key, data}
+
end)
+
end)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
[
+
%{
+
"byr" => "1986",
+
"ecl" => "brn",
+
"eyr" => "2021",
+
"hcl" => "#6b5442",
+
"hgt" => "171cm",
+
"iyr" => "2019",
+
"pid" => "637485594"
+
},
+
%{
+
"byr" => "2014",
+
"eyr" => "2025",
+
"hcl" => "#341e13",
+
"hgt" => "66cm",
+
"iyr" => "1938",
+
"pid" => "70195175"
+
},
+
%{
+
"ecl" => "hzl",
+
"eyr" => "2020",
+
"hcl" => "#efcc98",
+
"hgt" => "174cm",
+
"iyr" => "2011",
+
"pid" => "589700330"
+
},
+
%{
+
"byr" => "2004",
+
"cid" => "54",
+
"ecl" => "brn",
+
"eyr" => "2027",
+
"hcl" => "#bba027",
+
"hgt" => "173cm",
+
"iyr" => "2028",
+
"pid" => "153cm"
+
},
+
%{
+
"ecl" => "oth",
+
"eyr" => "2029",
+
"hcl" => "b45cec",
+
"hgt" => "185cm",
+
"iyr" => "2011",
+
"pid" => "178cm"
+
},
+
%{"eyr" => "2029", "hcl" => "#888785", "hgt" => "185cm", "iyr" => "2016", "pid" => "026540921"},
+
%{
+
"byr" => "2015",
+
"ecl" => "oth",
+
"eyr" => "2025",
+
"hcl" => "6962f7",
+
"hgt" => "191cm",
+
"iyr" => "1974",
+
"pid" => "2616015"
+
},
+
%{
+
"byr" => "1951",
+
"ecl" => "grn",
+
"eyr" => "2027",
+
"hcl" => "#18171d",
+
"hgt" => "67cm",
+
"iyr" => "2019",
+
"pid" => "268398556"
+
},
+
%{
+
"byr" => "2013",
+
"ecl" => "brn",
+
"eyr" => "2029",
+
"hcl" => "#623a2f",
+
"hgt" => "153cm",
+
"iyr" => "1957",
+
"pid" => "183179186"
+
},
+
%{
+
"byr" => "2025",
+
"cid" => "121",
+
"eyr" => "1971",
+
"hcl" => "752fbc",
+
"hgt" => "61cm",
+
"iyr" => "1922",
+
"pid" => "79577560"
+
},
+
%{
+
"byr" => "1992",
+
"ecl" => "hzl",
+
"eyr" => "2024",
+
"hcl" => "#18171d",
+
"hgt" => "184cm",
+
"iyr" => "2016",
+
"pid" => "751161201"
+
},
+
%{
+
"byr" => "1938",
+
"ecl" => "blu",
+
"eyr" => "2021",
+
"hcl" => "#b6652a",
+
"hgt" => "191cm",
+
"iyr" => "2016",
+
"pid" => "313406514"
+
},
+
%{
+
"byr" => "1991",
+
"ecl" => "brn",
+
"eyr" => "2021",
+
"hcl" => "#623a2f",
+
"hgt" => "167cm",
+
"iyr" => "2019",
+
"pid" => "145249653"
+
},
+
%{
+
"byr" => "2021",
+
"ecl" => "#f615b1",
+
"eyr" => "2027",
+
"hcl" => "#ceb3a1",
+
"hgt" => "172in",
+
"iyr" => "2022",
+
"pid" => "175cm"
+
},
+
%{
+
"byr" => "1952",
+
"ecl" => "#0cba5e",
+
"eyr" => "1942",
+
"hgt" => "173in",
+
"iyr" => "1968",
+
"pid" => "1885981567"
+
},
+
%{
+
"byr" => "1971",
+
"ecl" => "oth",
+
"eyr" => "2023",
+
"hcl" => "z",
+
"hgt" => "65cm",
+
"iyr" => "2017",
+
"pid" => "521737908"
+
},
+
%{
+
"byr" => "1936",
+
"ecl" => "brn",
+
"eyr" => "2025",
+
"hcl" => "#cfa07d",
+
"iyr" => "2011",
+
"pid" => "589047874"
+
},
+
%{
+
"byr" => "1946",
+
"cid" => "159",
+
"ecl" => "hzl",
+
"eyr" => "2023",
+
"hcl" => "#fffffd",
+
"hgt" => "160cm",
+
"iyr" => "2012",
+
"pid" => "912552538"
+
},
+
%{
+
"byr" => "1952",
+
"cid" => "59",
+
"ecl" => "amb",
+
"eyr" => "2026",
+
"hcl" => "#18171d",
+
"hgt" => "72in",
+
"iyr" => "2015",
+
"pid" => "782818257"
+
},
+
%{
+
"byr" => "1986",
+
"cid" => "96",
+
"ecl" => "amb",
+
"eyr" => "2026",
+
"hcl" => "#602927",
+
"hgt" => "173cm",
+
"iyr" => "2018",
+
"pid" => "783160698"
+
},
+
%{
+
"byr" => "1960",
+
"cid" => "199",
+
"ecl" => "hzl",
+
"eyr" => "2030",
+
"hcl" => "#a97842",
+
"hgt" => "171cm",
+
"iyr" => "2011",
+
"pid" => "912273414"
+
},
+
%{
+
"byr" => "1942",
+
"cid" => "116",
+
"ecl" => "amb",
+
"eyr" => "2029",
+
"hcl" => "#ceb3a1",
+
"hgt" => "156cm",
+
"iyr" => "2013",
+
"pid" => "567057004"
+
},
+
%{
+
"byr" => "1956",
+
"cid" => "254",
+
"ecl" => "#cddc40",
+
"eyr" => "2026",
+
"hcl" => "#733820",
+
"hgt" => "75in",
+
"iyr" => "2015",
+
"pid" => "045090966"
+
},
+
%{
+
"byr" => "2022",
+
"cid" => "129",
+
"ecl" => "#02e67d",
+
"eyr" => "2040",
+
"hcl" => "b7c0e6",
+
"hgt" => "176cm",
+
"iyr" => "1959",
+
"pid" => "156cm"
+
},
+
%{
+
"byr" => "1933",
+
"ecl" => "blu",
+
"eyr" => "2029",
+
"hcl" => "#888785",
+
"hgt" => "160cm",
+
"iyr" => "2012",
+
"pid" => "028571975"
+
},
+
%{
+
"byr" => "1931",
+
"ecl" => "brn",
+
"eyr" => "2030",
+
"hcl" => "#390f37",
+
"hgt" => "171cm",
+
"iyr" => "2017",
+
"pid" => "015365720"
+
},
+
%{
+
"byr" => "1926",
+
"ecl" => "gry",
+
"eyr" => "2026",
+
"hgt" => "188cm",
+
"iyr" => "2014",
+
"pid" => "697057757"
+
},
+
%{
+
"byr" => "1957",
+
"cid" => "53",
+
"ecl" => "gry",
+
"eyr" => "2021",
+
"hcl" => "#fffffd",
+
"hgt" => "150cm",
+
"iyr" => "2018",
+
"pid" => "484310015"
+
},
+
%{
+
"byr" => "1963",
+
"ecl" => "brn",
+
"eyr" => "2026",
+
"hcl" => "#888785",
+
"hgt" => "156cm",
+
"iyr" => "2011",
+
"pid" => "063272603"
+
},
+
%{
+
"byr" => "1955",
+
"cid" => "132",
+
"ecl" => "oth",
+
"eyr" => "2023",
+
"hcl" => "#888785",
+
"hgt" => "191cm",
+
"iyr" => "2018",
+
"pid" => "310518398"
+
},
+
%{
+
"byr" => "1938",
+
"cid" => "290",
+
"ecl" => "amb",
+
"eyr" => "2023",
+
"hcl" => "#623a2f",
+
"hgt" => "165cm",
+
"iyr" => "2010",
+
"pid" => "170304863"
+
},
+
%{
+
"byr" => "1996",
+
"ecl" => "brn",
+
"eyr" => "2026",
+
"hcl" => "#18171d",
+
"hgt" => "164cm",
+
"iyr" => "2016",
+
"pid" => "021468065"
+
},
+
%{
+
"byr" => "2027",
+
"ecl" => "oth",
+
"eyr" => "1948",
+
"hcl" => "#733820",
+
"hgt" => "153in",
+
"pid" => "8258823391"
+
},
+
%{"byr" => "2026", "ecl" => "#cd275a", "eyr" => "2036", "iyr" => "2012", "pid" => "5917499975"},
+
%{
+
"byr" => "2004",
+
"cid" => "151",
+
"ecl" => "oth",
+
"eyr" => "2033",
+
"hcl" => "99ecb1",
+
"hgt" => "184cm",
+
"iyr" => "1997",
+
"pid" => "871137711"
+
},
+
%{
+
"byr" => "2011",
+
"ecl" => "#eee1d2",
+
"eyr" => "1925",
+
"hcl" => "z",
+
"hgt" => "59cm",
+
"iyr" => "2030",
+
"pid" => "#02ee78"
+
},
+
%{
+
"byr" => "1995",
+
"cid" => "169",
+
"ecl" => "gry",
+
"eyr" => "2024",
+
"hcl" => "#888785",
+
"hgt" => "162cm",
+
"iyr" => "2013",
+
"pid" => "742658992"
+
},
+
%{
+
"byr" => "1946",
+
"cid" => "71",
+
"ecl" => "amb",
+
"eyr" => "2027",
+
"hcl" => "#238da0",
+
"hgt" => "152cm",
+
"iyr" => "2018",
+
"pid" => "352799678"
+
},
+
%{
+
"byr" => "1926",
+
"ecl" => "grn",
+
"eyr" => "2021",
+
"hcl" => "#623a2f",
+
"hgt" => "172cm",
+
"iyr" => "2013",
+
"pid" => "723616064"
+
},
+
%{"byr" => "2028", "eyr" => "1986", "hgt" => "94", "iyr" => "2019", "pid" => "#ee7f00"},
+
%{
+
"byr" => "1957",
+
"ecl" => "amb",
+
"eyr" => "2027",
+
"hcl" => "#d67ae1",
+
"hgt" => "183cm",
+
"iyr" => "2011",
+
"pid" => "188153423"
+
},
+
%{
+
"byr" => "1950",
+
"ecl" => "#e2495d",
+
"eyr" => "2034",
+
"hgt" => "166cm",
+
"iyr" => "2010",
+
"pid" => "151457075"
+
},
+
%{
+
"byr" => "2016",
+
"ecl" => "#55c2a4",
+
"eyr" => "1981",
+
"hcl" => "z",
+
"hgt" => "76cm",
+
"iyr" => "2029",
+
"pid" => "153cm"
+
},
+
%{
+
"byr" => "2002",
+
"ecl" => "amb",
+
"eyr" => "2021",
+
"hcl" => "#623a2f",
+
"hgt" => "184cm",
+
"iyr" => "1960",
+
...
+
},
+
%{"byr" => "1991", "ecl" => "blu", "eyr" => "2027", "hgt" => "179cm", "iyr" => "2020", ...},
+
%{"byr" => "1950", "ecl" => "grn", "eyr" => "2027", "hcl" => "#a97842", ...},
+
%{"byr" => "1930", "ecl" => "oth", "eyr" => "2028", ...},
+
%{"byr" => "1960", "ecl" => "amb", ...},
+
%{"byr" => "1922", ...},
+
%{...},
+
...
+
]
+
```
+
+
## Part 1
+
+
```elixir
+
Enum.count(passports, fn passport ->
+
required = ~w[byr iyr eyr hgt hcl ecl pid]
+
keys = Map.keys(passport)
+
+
Enum.all?(required, & &1 in keys)
+
end)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
196
+
```
+
+
## Part 2
+
+
```elixir
+
defmodule Part2 do
+
def valid?(passport) do
+
[
+
year(passport["byr"]) in 1920..2002,
+
year(passport["iyr"]) in 2010..2020,
+
year(passport["eyr"]) in 2020..2030,
+
case hgt(passport["hgt"]) do
+
{cm, "cm"} -> cm in 150..193
+
{i, "in"} -> i in 59..79
+
_ -> false
+
end,
+
Map.get(passport, "hcl", "") =~ ~r/^#[0-9a-f]{6}$/,
+
passport["ecl"] in ~w[amb blu brn gry grn hzl oth],
+
Map.get(passport, "pid", "") =~ ~r/^\d{9}$/
+
]
+
|> Enum.all?()
+
end
+
+
defp year(nil), do: false
+
defp year(y), do: elem(Integer.parse(y), 0)
+
+
defp hgt(nil), do: false
+
defp hgt(h), do: Integer.parse(h)
+
end
+
+
Enum.count(passports, &Part2.valid?/1)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
114
+
```
+
+
<!-- livebook:{"offset":13532,"stamp":{"token":"XCP.TTqFDnEDh1KcybgE2cRzHx79CkCBOfAe1WwEG3cX7vDTkxtUF55KF32ZCFPKqMdo3PkrQc384TMNDJTmch-aqQHkit7xUcJ8qMXwA33agDM5wcdBmkMyp1XHIbZz4GZrr3w","version":2}} -->
+105
2020/day05.livemd
···
+
<!-- livebook:{"persist_outputs":true} -->
+
+
# Day 05
+
+
```elixir
+
Mix.install([:kino_aoc])
+
```
+
+
## Section
+
+
<!-- livebook:{"attrs":"eyJhc3NpZ25fdG8iOiJwdXp6bGVfaW5wdXQiLCJkYXkiOiI1Iiwic2Vzc2lvbl9zZWNyZXQiOiJBRFZFTlRfT0ZfQ09ERV9TRVNTSU9OIiwieWVhciI6IjIwMjAifQ","chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2020", "5", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:ok,
+
"FFBBFFFLRL\nFFBBFBBRRL\nFBBBFFBLRL\nBBFBFFBLRR\nBFBBBFFLLL\nBFBBBBBLLR\nFBFBFBFLLR\nBFBFBBFLLR\nFBBFBFBLLL\nBBBFBFBRLL\nBFBBBFBLRL\nFBBFFFBLLR\nBFFBFBFLRL\nFBBBBFBRLR\nFFBBBBBRRL\nFBBFBFFLRL\nFBBBBBBLLR\nFBBFBBBRRL\nFBBFFBFRLL\nFBFBBBBRRR\nBFFBFBFRRL\nBFBFBBBLLR\nFFFFBFBLRL\nFBFFBFFLRL\nFFBFBBBRRR\nFFBFFFFLRR\nFBBBFFFLLR\nFFFFFBFLLL\nBFFFFFFLRL\nFBBBBBFRLR\nBBBFFBBRRR\nFFFFBBBRLL\nFBFFBBBRLR\nBFBBBFFRRL\nBBFBBFBLRL\nBFBFBFFRRR\nBBFBFFFLLL\nFBFBFBFRRR\nBFBFBFFRRL\nBBFBBFBRRL\nFFBBFBFLRL\nFBFFFFFRLR\nFBBFFFBLLL\nFBBBBFFRLL\nFFBBBBBLLL\nBFFBBFFRLR\nFFFBBFBRRR\nFBBBFFFRLL\nFFFBFBFLRL\nBFFBBFFLRL\nBFBBBBBLRL\nBFFFFFBRRR\nFFFBBFBLRL\nFBBBFBFRLL\nFBBFBFBLRR\nBBFBBFFLRR\nFBFFBBFLLL\nFFFFFBBRLL\nFFBBFFBRLR\nBBFFFFFLLL\nBFFFFBFLRR\nFBFBBFFRRL\nBFBFFBBLLR\nFBBBFBBRLR\nBBBFBFFRLL\nBBFFBBFRLR\nFFBFFBBRLR\nFFBBBFBRLR\nBBBFFFBLRR\nBBFBFBFLRR\nBFBBBBBRLR\nBFFFFFBLLR\nFBFFBFFRLL\nBBBFFBBRLR\nFFBBBFBRRR\nBFBBBFBRLR\nFBFFFBBLRL\nFFFBFFFRLL\nBBFFBFFLLL\nBFFBBFFRRR\nFFBFBFBRRL\nFFBBBFBRRL\nFBBFFBBRLR\nFBFFBBFRLR\nBFBFFBBRRR\nBBFBFBBRLR\nFFBFFFFRRL\nBBFFBFFLLR\nFBBFBFBRRR\nBFBFBBBRRL\nFBFBFFBRRL\nFFFBBFFRLL\nBFBFFFFRRR\nFBBFFBFLLR\nFFBFBFFRLL\nFBFFBFBLLL\nFBFBFFFLRL\nBBFFFFFRRR\nFBFFBBFLRR\nFBFFFBFLRL\nFBBBFBBRRL\nBFFBFFFRLR\nFFBBBBFLLR\nBFFFFBFLRL\nBFFBFFBRRR\nFFBFBFBLRL\nBBFFFBBRLL\nFFBFBBFRRR\nFFFBFBFRRL\nFBFFBFBRRR\nFBBBBFBRRL\nFBFFFFFLLR\nFFBFFFFLLR\nFBBBBFFRLR\nBBBFFBBLRR\nBBBFFBFLRR\nFBBFBBBLRR\nFBBFBBFRRL\nFFFBFFBLLL\nFBFFFFBLLL\nBBFFFFBLLL\nFBFFFBFLRR\nFFBFBFFLRR\nBBFBFFFRLL\nFFFBBBFRLR\nFFBFFBBRLL\nBBBFBFFRRL\nBFFBBBBLRR\nBFFFFFFLLL\nBBBFFFBLLL\nFBBBBBFRLL\nFBBFBBBLLR\nBBFBFFFRRR\nBBFFFBBLLL\nFBBFFBFLRL\nBBFBFFFLRR\nBFBFFBFRLL\nBFFFBFBLLR\nBBBFBFBLLL\nBBBFFBFRLR\nFBFFBFBRLR\nBFBBFFFLLL\nBBFFFFBLRR\nBBFFFBBRRL\nBBBFBFFLLL\nBFBFFBFLLL\nFBBBBFFLLR\nFFBFFFFRLR\nFFBBBFBRLL\nBFFFFFFRRL\nBFBFFBBLRL\nBBFBBBFRLL\nBFFFBFFLLR\nBBFBFFBRLL\nBFBBFFFRLL\nBBFBBFBRLR\nFFFBBFBRLR\nBFFFBBFLRL\nFFBFFBFRLL\nFFFBFFBLRL\nBFBBBFFRLR\nBBBFFBBLRL\nBFFBBBBRRL\nFFBBFFFRLL\nBFBFFBFLRL\nBFFBBBBRRR\nBBFBFBFRRL\nBBBFFBFRRL\nBFFFBFBLRL\nFFFBFBFRLR\nFBFFBBBLRR\nFFFFBBBLLL\nBBBFBBFLLR\nBFFBFBFRRR\nBFBFFFBRRR\nBBFBBBBLLR\nFFBBBBBLRL\nFFBFFBFLRR\nFFBBBFBLRR\nBBFBBFBRRR\nFFFFFFBRRR\nBFBFBFBRRL\nBBFFBBBLRR\nBBFBFFFRLR\nFBBFBFBLLR\nBFBBFFBRLL\nFFFFBFBLLR\nBFBFFBBRLR\nFBFFFBFRRR\nBFFBFFFRLL\nFBBBFFFRRR\nFFFBBBFLLL\nFBBBBBBRRL\nFBBFFBBLLR\nBBBFBFFLRR\nBFBBFBFLRR\nFFFBBBBRRR\nBFFFBBFRLR\nFBFFBBFLLR\nFBFFFFFRRL\nBBBFBBFLLL\nBBBFFFFRLR\nFFFFBBBRRR\nFBBBFBBLLL\nBFFBFFBLLL\nFBFBBFBRLR\nFFBFFBBLLR\nFFFFBFFLRR\nFBBFFBFLLL\nFBFBBFBRRR\nBBBFBFBLLR\nBBFFBFBLLL\nFFBFFBFRLR\nFBBBFBBLRR\nBBFBBFBLLL\nFFBFFBFRRR\nFBBBBFFLRL\nBFBBFBFLLR\nFBFBBBFRLR\nBFBBFFBLLR\nFFFBBBFLLR\nFFFBBBFRRL\nBFFFBFBRLR\nBBBFBBFLRR\nBBFBBFFLLR\nBBFBBBBRLR\nFBBFFFFLRR\nFBFBBFFRLL\nFFBFFFFRRR\nFFFBBFFRRL\nFFFBBFBRRL\nFFFBFBFLLR\nFFBBBBFRRR\nBFFFFBBRRL\nBFFFFBFRRR\nBFBBBFBLRR\nFFBBFFFRRL\nFBBBBBBRRR\nBBFBFFBLLR\nFBFFFFBRLL\nBFBBFBFLLL\nFBFFFBBRLL\nFBBBFFBLLR\nBBFBBBFRLR\nFBFBBFBLRR\nFFFFFBFLLR\nFBFBBBFLRL\nFFBFFFBRRR\nFFFBBFFLRL\nBBBFFFFLLR\nBFBFFFFRRL\nFBFBFBBLLR\nFBBBFBFRRL\nBBFBBBBRRL\nBFBBFBFLRL\nBFFBBFFLLR\nBFBFFBBRLL\nFBFFBFFRLR\nFBFBFBFLRR\nBFBFBBFRRR\nFBBBBFBLRL\nFFBBBFFRRR\nFFBBFFBRLL\nFFBBBBBRLL\nFBFFFBFRRL\nFFFBBBFLRL\nBBBFBFFRRR\nFFFBFFFRRR\nFBFFBFFLLL\nFFBBFFBRRL\nBFFBFFBRRL\nFFBBBFFRLR\nBBBFFFFRRR\nBBFBFBBRRR\nFBFBBBBLRR\nBFBFBFBLLL\nFFBBFFBLLR\nBFFFBBBRLR\nBFBBFBBRLR\nBFFFFBBLLR\nFBFBFBBRLR\nBFFBBBFLLR\nFBFFBFBLRL\nBFBFBBBRLL\nBFBBBFFLRL\nFFFBFFFLRR\nBFFBBFBRLL\nFFBBBBFRLL\nBBFFFBBLLR\nFBFBFBFRLR\nBBBFFFBRLR\nBFFFFFBRLR\nBBBFFFFLLL\nFFFBBFBRLL\nBFFFFFBRRL\nFBFFBBBRRL\nFBFBFBBLLL\nFBFBBFBRRL\nFBBFBBBRRR\nBFBFFBBRRL\nFBBBBFBLLL\nFBBBBBBRLR\nBBFFFBFRRL\nFFFFBFBLLL\nFFFFBBFLRR\nFFFFBFFLRL\nBFFFBBFRLL\nBBFFFFBRRR\nBFBFFFFRLL\nBFFFFBFLLR\nBBBFFBBRRL\nBBFBBFBLLR\nBFFFFBFRLR\nFBBBFBFLLR\nFFFFFBBLRR\nBFBFFFFLRR\nFBFBBFFLRL\nFBFFFBBRRR\nBBFBBBFLRL\nBFBBBFFLLR\nBFBFBBFRRL\nFBFFFFBLRL\nFBBFBFFRLR\nBFBFBBBLRR\nBFBFBBFLRL\nBBFFBFFRLL\nFBFFBBBLRL\nBFBFBFFLLR\nFFFBFFBLLR\nFFFBFBBRRR\nBBFBFFFLLR\nFBBBFBFRLR\nFBFFBBBLLL\nFFBFBBFLRR\nFBFBFFFLLL\nBBFFFFFLRL\nFBFBBFBLRL\nBBFFFBFLLR\nBBFBBBBRRR\nBFBBBFFRRR\nFFFBFFBRLL\nFBBBFFFRLR\nBBBFBFBLRL\nFBFFFFBRLR\nBFFFFFBLLL\nFBFFFFBLLR\nBFBBFFBLRR\nBFBFBBBRRR\nBBBFBFBRRR\nFFFBBFFRRR\nFBBBFFFLRR\nBBFBFFFRRL\nBFBFBBFRLR\nBFFFBFBRLL\nFBFFFFFLLL\nFFFBBBBLRL\nFFFBBFFLLL\nFBFFFFBRRR\nFFBFBFBRLR\nBFBFFFBLRR\nBFFFBFBLLL\nFBBFBFFRLL\nFBFBFFFRLL\nFBBBFFBRRR\nFBBBFFBRLL\nFFBBFBBLLL\nFBBBBFBRRR\nBFBBBFBLLR\nFBBBBBFLLR\nFFBBFBFLRR\nBFFBBFBLLR\nFBFFFFBLRR\nBFFB" <> ...}
+
```
+
+
```elixir
+
seats =
+
puzzle_input
+
|> String.split("\n", trim: true)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
["FFBBFFFLRL", "FFBBFBBRRL", "FBBBFFBLRL", "BBFBFFBLRR", "BFBBBFFLLL", "BFBBBBBLLR", "FBFBFBFLLR",
+
"BFBFBBFLLR", "FBBFBFBLLL", "BBBFBFBRLL", "BFBBBFBLRL", "FBBFFFBLLR", "BFFBFBFLRL", "FBBBBFBRLR",
+
"FFBBBBBRRL", "FBBFBFFLRL", "FBBBBBBLLR", "FBBFBBBRRL", "FBBFFBFRLL", "FBFBBBBRRR", "BFFBFBFRRL",
+
"BFBFBBBLLR", "FFFFBFBLRL", "FBFFBFFLRL", "FFBFBBBRRR", "FFBFFFFLRR", "FBBBFFFLLR", "FFFFFBFLLL",
+
"BFFFFFFLRL", "FBBBBBFRLR", "BBBFFBBRRR", "FFFFBBBRLL", "FBFFBBBRLR", "BFBBBFFRRL", "BBFBBFBLRL",
+
"BFBFBFFRRR", "BBFBFFFLLL", "FBFBFBFRRR", "BFBFBFFRRL", "BBFBBFBRRL", "FFBBFBFLRL", "FBFFFFFRLR",
+
"FBBFFFBLLL", "FBBBBFFRLL", "FFBBBBBLLL", "BFFBBFFRLR", "FFFBBFBRRR", "FBBBFFFRLL", "FFFBFBFLRL",
+
"BFFBBFFLRL", ...]
+
```
+
+
```elixir
+
defmodule Plane do
+
def lookup(<<>>, _directions, pos, 1), do: pos
+
+
def lookup(<<curr>> <> rest, d, first, dist) do
+
dist = div(dist, 2)
+
+
{nf, nl} =
+
if curr == d do
+
{first, dist}
+
else
+
{first + dist, dist}
+
end
+
+
lookup(rest, d, nf, nl)
+
end
+
+
def seat_no(id) do
+
{row, col} = String.split_at(id, 7)
+
+
lookup(row, ?F, 0, 128) * 8 + lookup(col, ?L, 0, 8)
+
end
+
end
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:module, Plane, <<70, 79, 82, 49, 0, 0, 9, ...>>, {:seat_no, 1}}
+
```
+
+
## Part 1
+
+
```elixir
+
seats
+
|> Enum.map(&Plane.seat_no/1)
+
|> Enum.max()
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
947
+
```
+
+
## Part 2
+
+
```elixir
+
seats
+
|> Enum.sort()
+
|> Enum.map(&Plane.seat_no/1)
+
|> Enum.chunk_every(2, 1)
+
|> Enum.find_value(fn [a, b] -> if b == a + 2, do: a + 1 end)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
636
+
```
+
+
<!-- livebook:{"offset":6707,"stamp":{"token":"XCP.jyVZ5mT4Eh93IIpxW_8l2Aemq91Tmk8CIwY-V3Z73RF3Qd7Yjct-IMJBfvB57vM_l06YF1tv55dZ73nE8aLIHN4OMmL-3l-vRTpT0Qs7Ks6Oc5tQDm2ynrANEp8xknTW7O4","version":2}} -->
+38 -11
2021/day01.livemd
···
# Day 1
+
```elixir
+
Mix.install([
+
{:kino_aoc, ">= 0.0.0"}
+
])
+
```
+
## Load input
+
<!-- livebook:{"attrs":{"assign_to":"puzzle_input","day":"1","session_secret":"ADVENT_OF_CODE_SESSION","year":"2021"},"chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2021", "1", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:ok,
+
"173\n178\n179\n187\n196\n199\n200\n201\n210\n209\n210\n211\n221\n223\n235\n236\n237\n238\n242\n249\n247\n246\n256\n257\n258\n257\n258\n265\n293\n303\n304\n317\n322\n330\n336\n337\n340\n339\n350\n351\n352\n353\n349\n353\n342\n339\n341\n342\n348\n349\n350\n355\n362\n392\n388\n393\n404\n402\n401\n402\n405\n410\n411\n424\n425\n432\n434\n433\n435\n441\n420\n439\n461\n463\n464\n468\n469\n473\n485\n494\n493\n489\n490\n491\n497\n490\n491\n493\n519\n520\n553\n554\n560\n565\n574\n586\n599\n600\n601\n604\n578\n574\n578\n597\n598\n597\n607\n606\n608\n616\n613\n615\n618\n617\n619\n626\n638\n639\n650\n682\n686\n693\n696\n709\n715\n745\n747\n750\n751\n753\n760\n763\n764\n772\n776\n779\n791\n794\n795\n800\n799\n808\n814\n825\n826\n831\n830\n837\n853\n854\n863\n872\n873\n881\n885\n895\n896\n897\n895\n905\n909\n912\n916\n921\n919\n927\n929\n935\n936\n937\n948\n947\n948\n922\n926\n932\n931\n938\n958\n975\n977\n982\n985\n986\n987\n988\n1007\n1005\n1007\n1008\n1010\n1013\n1015\n1016\n1019\n1025\n1026\n1027\n1029\n1039\n1047\n1054\n1055\n1063\n1066\n1087\n1095\n1096\n1097\n1093\n1114\n1123\n1131\n1137\n1142\n1140\n1154\n1157\n1158\n1159\n1160\n1170\n1174\n1182\n1184\n1191\n1200\n1211\n1214\n1231\n1241\n1250\n1246\n1260\n1287\n1311\n1313\n1318\n1327\n1325\n1324\n1325\n1326\n1339\n1350\n1355\n1358\n1368\n1380\n1422\n1423\n1442\n1466\n1450\n1451\n1457\n1464\n1474\n1490\n1494\n1507\n1508\n1509\n1511\n1524\n1521\n1528\n1529\n1533\n1538\n1542\n1544\n1543\n1560\n1579\n1585\n1589\n1591\n1598\n1599\n1600\n1610\n1614\n1615\n1629\n1624\n1629\n1632\n1627\n1641\n1638\n1639\n1641\n1644\n1645\n1646\n1647\n1659\n1661\n1658\n1661\n1664\n1665\n1669\n1671\n1673\n1674\n1675\n1672\n1677\n1687\n1688\n1696\n1697\n1711\n1715\n1720\n1721\n1724\n1725\n1726\n1731\n1740\n1737\n1746\n1745\n1758\n1760\n1758\n1771\n1777\n1773\n1777\n1778\n1788\n1794\n1804\n1809\n1814\n1837\n1839\n1838\n1837\n1842\n1851\n1857\n1843\n1844\n1845\n1860\n1863\n1888\n1887\n1888\n1889\n1897\n1895\n1903\n1906\n1907\n1913\n1917\n1916\n1917\n1926\n1927\n1935\n1933\n1934\n1939\n1940\n1942\n1944\n1941\n1946\n1967\n1969\n1975\n1976\n1979\n1981\n1982\n1987\n1981\n1982\n1981\n1982\n1992\n2027\n2028\n2029\n2036\n2037\n2038\n2042\n2044\n2048\n2047\n2054\n2055\n2062\n2065\n2066\n2091\n2103\n2093\n2094\n2089\n2091\n2093\n2098\n2108\n2086\n2087\n2118\n2123\n2127\n2132\n2148\n2149\n2147\n2148\n2149\n2150\n2152\n2151\n2152\n2149\n2156\n2167\n2177\n2179\n2180\n2159\n2167\n2158\n2156\n2174\n2169\n2170\n2180\n2183\n2187\n2191\n2192\n2200\n2202\n2206\n2240\n2251\n2247\n2259\n2273\n2274\n2276\n2255\n2256\n2263\n2265\n2269\n2270\n2272\n2273\n2275\n2276\n2281\n2290\n2292\n2293\n2287\n2291\n2289\n2287\n2290\n2306\n2307\n2310\n2315\n2329\n2337\n2370\n2375\n2373\n2376\n2362\n2397\n2400\n2401\n2419\n2429\n2435\n2438\n2450\n2451\n2481\n2482\n2487\n2491\n2492\n2496\n2501\n2502\n2499\n2501\n2467\n2469\n2468\n2470\n2473\n2480\n2481\n2488\n2500\n2506\n2509\n2512\n2513\n2515\n2516\n2512\n2506\n2511\n2513\n2514\n2519\n2547\n2580\n2584\n2585\n2582\n2599\n2600\n2599\n2600\n2599\n2600\n2613\n2612\n2610\n2612\n2608\n2615\n2622\n2610\n2613\n2608\n2619\n2640\n2620\n2612\n2608\n2609\n2625\n2626\n2634\n2638\n2670\n2674\n2675\n2674\n2678\n2685\n2686\n2678\n2692\n2693\n2716\n2718\n2705\n2709\n2713\n2714\n2715\n2722\n2712\n2714\n2719\n2720\n2740\n2741\n2734\n2738\n2764\n2765\n2768\n2773\n2777\n2810\n2789\n2808\n2807\n2813\n2828\n2841\n2853\n2854\n2842\n2843\n2846\n2848\n2860\n2861\n2862\n2864\n2865\n2866\n2880\n2851\n2853\n2858\n2865\n2866\n2873\n2885\n2886\n2887\n2893\n2914\n2916\n2924\n2925\n2927\n2929\n2949\n2967\n2968\n2976\n2965\n2983\n2985\n2984\n2991\n2993\n3007\n3005\n3012\n3015\n3019\n3025\n3030\n3034\n3043\n3044\n3085\n3094\n3124\n3139\n3146\n3147\n3176\n3196\n3199\n3200\n3246\n3251\n3254\n3286\n3280\n3287\n3289\n3288\n3290\n3294\n3306\n3307\n3309\n3312\n3327\n3325\n3334\n3333\n3335\n3357\n3374\n3380\n3392\n3393\n3406\n3416\n3417\n3431\n3418\n3439\n3452\n3468\n3469\n3474\n3490\n3489\n3490\n3491\n3513\n3512\n3513\n3514\n3515\n3516\n3517\n3513\n3514\n3508\n3520\n3522\n3521\n3520\n3531\n3533\n3545\n3546\n3554\n3558\n3559\n3560\n3565\n3578\n3570\n3573\n3574\n3580\n3592\n3593\n3594\n3595\n3596\n3617\n3625\n3624\n3626\n3629\n3635\n3634\n3640\n3661\n3668\n3671\n3674\n3675\n3679\n3688\n3692\n3698\n3700\n3696\n3697\n3701\n3707\n3697\n3699\n3703\n3702\n3700\n3711\n3714\n3715\n3716\n3722\n3741\n3751\n3752\n3759\n3782\n3785\n3786\n3787\n3799\n3807\n3810\n3809\n3816\n3794\n3796\n3800\n3804\n3810\n3812\n3813\n3821\n3822\n3840\n3851\n3866\n3867\n3875\n3895\n3913\n3905\n3917\n3918\n3913\n3921\n3927\n3931\n3936\n3957\n3956\n3958\n3959\n3980\n3979\n3986\n3997\n3988\n3989\n3990\n3994\n3995\n3999\n3993\n4024\n4022\n4018\n4019\n4031\n4032\n4033\n4043\n4045\n4047\n4048\n4058\n4067\n4077\n4069\n4070\n4080\n4087\n4113\n4118\n4123\n4128\n4132\n4144\n4149\n4152\n4131\n4160\n4175\n4176\n4177\n4176\n4179\n4191\n4196\n4201\n4202\n4205\n4214\n4216\n4217\n4210\n4212\n4216\n4217\n4220\n4219\n4220\n42" <> ...}
+
```
+
```elixir
stream =
-
File.stream!("day1.txt")
+
puzzle_input
+
|> String.split()
|> Stream.map(&String.to_integer(String.trim(&1)))
```
-
```output
+
<!-- livebook:{"output":true} -->
+
+
```
#Stream<[
-
enum: %File.Stream{
-
line_or_bytes: :line,
-
modes: [:raw, :read_ahead, :binary],
-
path: "day1.txt",
-
raw: true
-
},
-
funs: [#Function<47.58486609/1 in Stream.map/2>]
+
enum: ["173", "178", "179", "187", "196", "199", "200", "201", "210", "209", "210", "211", "221",
+
"223", "235", "236", "237", "238", "242", "249", "247", "246", "256", "257", "258", "257", "258",
+
"265", "293", "303", "304", "317", "322", "330", "336", "337", "340", "339", "350", "351", "352",
+
"353", "349", "353", "342", "339", "341", "342", "348", ...],
+
funs: [#Function<48.53678557/1 in Stream.map/2>]
]>
```
···
|> Enum.count(fn [a, b] -> a < b end)
```
-
```output
+
<!-- livebook:{"output":true} -->
+
+
```
1688
```
···
|> Enum.count(fn [a, _, _, b] -> a < b end)
```
-
```output
+
<!-- livebook:{"output":true} -->
+
+
```
1728
```
+
+
<!-- livebook:{"offset":6811,"stamp":{"token":"XCP.FvhtdtxXYvRknZpAwd7ATOS4B7IljsyPdpscD9AizNpEm35rzHOr6FxLlc7D5RuBsoDcHmWO_rDJI7khm9nmL4U_ebmCGJuAd_tnVXrljSHKDRHzwzLMZ_v6kJy6nqkgIA","version":2}} -->
+12 -4
2021/day17.livemd
···
[a: a, b: b]
```
-
```output
+
<!-- livebook:{"output":true} -->
+
+
```
target area: x=288..330, y=-96..-50
```
-
```output
+
<!-- livebook:{"output":true} -->
+
+
```
[a: %{x: 288, y: -96}, b: %{x: 330, y: -50}]
```
···
{v_y, v_y * (v_y + 1) / 2}
```
-
```output
+
<!-- livebook:{"output":true} -->
+
+
```
{95, 4560.0}
```
···
MapSet.size(pairs)
```
-
```output
+
<!-- livebook:{"output":true} -->
+
+
```
3344
```
+15 -5
2021/day18.livemd
···
|> Enum.map(&elem(Code.eval_string(&1), 0))
```
-
```output
+
<!-- livebook:{"output":true} -->
+
+
```
[
[[[6, [8, 3]], [2, 0]], [[[9, 5], [9, 1]], 3]],
[[[9, [2, 2]], [5, 4]], [[[2, 2], [9, 6]], '\a\a']],
···
end
```
-
```output
+
<!-- livebook:{"output":true} -->
+
+
```
{:module, Day18, <<70, 79, 82, 49, 0, 0, 12, ...>>, {:magnitude, 1}}
```
···
|> Day18.magnitude()
```
-
```output
+
<!-- livebook:{"output":true} -->
+
+
```
[[[[7, 7], [7, 8]], [[8, 7], [0, 7]]], [[[6, 6], [6, 7]], 6]]
```
-
```output
+
<!-- livebook:{"output":true} -->
+
+
```
3411
```
···
end
```
-
```output
+
<!-- livebook:{"output":true} -->
+
+
```
4680
```
+8 -17
2021/day19.livemd
···
end)
end)
-
IO.inspect(time / 1_000_000)
+
# IO.inspect(time / 1_000_000)
current = Day19.pairs(set)
···
{:halt, {set, scanners}}
{joinable, later} ->
-
IO.inspect({length(joinable), length(later)}, label: i)
+
# IO.inspect({length(joinable), length(later)}, label: i)
{:cont, {set, joinable, later, scanners}}
end
end
···
<!-- livebook:{"output":true} -->
```
-
0.005503
-
1: {5, 25}
-
0.029354
-
2: {5, 20}
-
0.067284
-
3: {7, 13}
-
0.195126
-
4: {6, 7}
-
0.292686
-
5: {5, 2}
-
0.374403
-
6: {1, 1}
-
0.074645
-
7: {1, 0}
-
0.090199
+
warning: variable "i" is unused (if the variable is not meant to be used, prefix it with an underscore)
+
2021/day19.livemd#cell:w7cczzbdb2mrwtou27usauoozuqydf3v:9
+
+
warning: variable "time" is unused (if the variable is not meant to be used, prefix it with an underscore)
+
2021/day19.livemd#cell:w7cczzbdb2mrwtou27usauoozuqydf3v:10
+
```
<!-- livebook:{"output":true} -->
+9 -3
2021/day20.livemd
···
img = Day20.Image.new(board)
```
-
```output
+
<!-- livebook:{"output":true} -->
+
+
```
#Image<{100x100}
โ–ˆ โ–ˆ โ–ˆ โ–ˆโ–ˆ โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ โ–ˆโ–ˆ โ–ˆ โ–ˆ โ–ˆโ–ˆโ–ˆ โ–ˆ โ–ˆโ–ˆ โ–ˆโ–ˆ โ–ˆ โ–ˆโ–ˆโ–ˆ โ–ˆ โ–ˆโ–ˆ โ–ˆ โ–ˆ โ–ˆ โ–ˆโ–ˆ โ–ˆโ–ˆโ–ˆ โ–ˆ โ–ˆโ–ˆ โ–ˆโ–ˆ โ–ˆ โ–ˆโ–ˆ โ–ˆ
···
|> Day20.Image.lighted()
```
-
```output
+
<!-- livebook:{"output":true} -->
+
+
```
5179
```
···
|> Day20.Image.lighted()
```
-
```output
+
<!-- livebook:{"output":true} -->
+
+
```
16112
```
+12 -4
2021/day21.livemd
···
{p1, p2}
```
-
```output
+
<!-- livebook:{"output":true} -->
+
+
```
{3, 5}
```
···
rounds * 3 * loser
```
-
```output
+
<!-- livebook:{"output":true} -->
+
+
```
720750
```
···
end
```
-
```output
+
<!-- livebook:{"output":true} -->
+
+
```
{:module, Day21.Task2, <<70, 79, 82, 49, 0, 0, 12, ...>>, {:round, 3}}
```
···
Day21.Task2.play(p1, p2)
```
-
```output
+
<!-- livebook:{"output":true} -->
+
+
```
275067741811212
```
+12 -4
2021/day22.livemd
···
end)
```
-
```output
+
<!-- livebook:{"output":true} -->
+
+
```
[
on: %{x: -40..7, y: -3..49, z: -48..6},
on: %{x: -38..10, y: -11..37, z: -30..19},
···
end
```
-
```output
+
<!-- livebook:{"output":true} -->
+
+
```
{:module, Day22, <<70, 79, 82, 49, 0, 0, 18, ...>>, {:split, 2}}
```
···
|> Day22.volume()
```
-
```output
+
<!-- livebook:{"output":true} -->
+
+
```
556501
```
···
|> Day22.volume()
```
-
```output
+
<!-- livebook:{"output":true} -->
+
+
```
1217140271559773
```
+12 -4
2021/day23.livemd
···
|> Map.new()
```
-
```output
+
<!-- livebook:{"output":true} -->
+
+
```
%{a: [:d, :b], b: [:d, :a], c: [:c, :b], d: [:c, :a]}
```
···
end
```
-
```output
+
<!-- livebook:{"output":true} -->
+
+
```
warning: variable "depth" is unused (if the variable is not meant to be used, prefix it with an underscore)
day23.livemd#cell:58: Day23.room_to_hall/3
···
```
-
```output
+
<!-- livebook:{"output":true} -->
+
+
```
{:module, Day23, <<70, 79, 82, 49, 0, 0, 23, ...>>, {:cost, 4}}
```
···
Day23.process(input)
```
-
```output
+
<!-- livebook:{"output":true} -->
+
+
```
:inf
```
+397 -9
2021/day24.livemd
···
end
end
-
def evaluate(ops, input), do: evaluate(ops, Integer.digits(input), %{w: 0, x: 0, y: 0, z: 0})
+
def evaluate(ops, input), do: evaluate(ops, to_digits(input), %{w: 0, x: 0, y: 0, z: 0})
defp evaluate([], _, regs), do: regs
-
-
defp evaluate([:nop | rest], input, regs), do: evaluate(rest, input, regs)
defp evaluate([{:inp, reg} | rest], [v | input], regs),
do: evaluate(rest, input, %{regs | reg => v})
···
defp get(imm, _regs) when is_integer(imm), do: imm
defp get(reg, regs) when is_atom(reg), do: Map.get(regs, reg, 0)
+
+
defp to_digits(int) when is_integer(int), do: Integer.digits(int)
+
defp to_digits(digits) when is_list(digits), do: digits
end
input =
-
File.stream!("day24.txt")
+
File.stream!("#{__DIR__}/day24.txt")
|> Stream.map(&String.trim/1)
|> Enum.map(&Day24.parse/1)
|> IO.inspect(limit: :infinity)
···
```
```elixir
-
44..52 |> Enum.map(&rem(&1, 26))
+
digits =
+
Enum.chunk_while(
+
input,
+
[],
+
fn
+
{:inp, _} = inp, [] -> {:cont, [inp]}
+
{:inp, _} = inp, acc -> {:cont, Enum.reverse(acc), [inp]}
+
other, acc -> {:cont, [other | acc]}
+
end,
+
fn acc -> {:cont, Enum.reverse(acc), []} end
+
)
```
<!-- livebook:{"output":true} -->
```
-
[18, 19, 20, 21, 22, 23, 24, 25, 0]
+
[
+
[
+
{:inp, :w},
+
{:mul, :x, 0},
+
{:add, :x, :z},
+
{:mod, :x, 26},
+
{:div, :z, 1},
+
{:add, :x, 11},
+
{:eql, :x, :w},
+
{:eql, :x, 0},
+
{:mul, :y, 0},
+
{:add, :y, 25},
+
{:mul, :y, :x},
+
{:add, :y, 1},
+
{:mul, :z, :y},
+
{:mul, :y, 0},
+
{:add, :y, :w},
+
{:add, :y, 16},
+
{:mul, :y, :x},
+
{:add, :z, :y}
+
],
+
[
+
{:inp, :w},
+
{:mul, :x, 0},
+
{:add, :x, :z},
+
{:mod, :x, 26},
+
{:div, :z, 1},
+
{:add, :x, 12},
+
{:eql, :x, :w},
+
{:eql, :x, 0},
+
{:mul, :y, 0},
+
{:add, :y, 25},
+
{:mul, :y, :x},
+
{:add, :y, 1},
+
{:mul, :z, :y},
+
{:mul, :y, 0},
+
{:add, :y, :w},
+
{:add, :y, 11},
+
{:mul, :y, :x},
+
{:add, :z, :y}
+
],
+
[
+
{:inp, :w},
+
{:mul, :x, 0},
+
{:add, :x, :z},
+
{:mod, :x, 26},
+
{:div, :z, 1},
+
{:add, :x, 13},
+
{:eql, :x, :w},
+
{:eql, :x, 0},
+
{:mul, :y, 0},
+
{:add, :y, 25},
+
{:mul, :y, :x},
+
{:add, :y, 1},
+
{:mul, :z, :y},
+
{:mul, :y, 0},
+
{:add, :y, :w},
+
{:add, :y, 12},
+
{:mul, :y, :x},
+
{:add, :z, :y}
+
],
+
[
+
{:inp, :w},
+
{:mul, :x, 0},
+
{:add, :x, :z},
+
{:mod, :x, 26},
+
{:div, :z, 26},
+
{:add, :x, -5},
+
{:eql, :x, :w},
+
{:eql, :x, 0},
+
{:mul, :y, 0},
+
{:add, :y, 25},
+
{:mul, :y, :x},
+
{:add, :y, 1},
+
{:mul, :z, :y},
+
{:mul, :y, 0},
+
{:add, :y, :w},
+
{:add, :y, 12},
+
{:mul, :y, :x},
+
{:add, :z, :y}
+
],
+
[
+
{:inp, :w},
+
{:mul, :x, 0},
+
{:add, :x, :z},
+
{:mod, :x, 26},
+
{:div, :z, 26},
+
{:add, :x, -3},
+
{:eql, :x, :w},
+
{:eql, :x, 0},
+
{:mul, :y, 0},
+
{:add, :y, 25},
+
{:mul, :y, :x},
+
{:add, :y, 1},
+
{:mul, :z, :y},
+
{:mul, :y, 0},
+
{:add, :y, :w},
+
{:add, :y, 12},
+
{:mul, :y, :x},
+
{:add, :z, :y}
+
],
+
[
+
{:inp, :w},
+
{:mul, :x, 0},
+
{:add, :x, :z},
+
{:mod, :x, 26},
+
{:div, :z, 1},
+
{:add, :x, 14},
+
{:eql, :x, :w},
+
{:eql, :x, 0},
+
{:mul, :y, 0},
+
{:add, :y, 25},
+
{:mul, :y, :x},
+
{:add, :y, 1},
+
{:mul, :z, :y},
+
{:mul, :y, 0},
+
{:add, :y, :w},
+
{:add, :y, 2},
+
{:mul, :y, :x},
+
{:add, :z, :y}
+
],
+
[
+
{:inp, :w},
+
{:mul, :x, 0},
+
{:add, :x, :z},
+
{:mod, :x, 26},
+
{:div, :z, 1},
+
{:add, :x, 15},
+
{:eql, :x, :w},
+
{:eql, :x, 0},
+
{:mul, :y, 0},
+
{:add, :y, 25},
+
{:mul, :y, :x},
+
{:add, :y, 1},
+
{:mul, :z, :y},
+
{:mul, :y, 0},
+
{:add, :y, :w},
+
{:add, :y, 11},
+
{:mul, :y, :x},
+
{:add, :z, :y}
+
],
+
[
+
{:inp, :w},
+
{:mul, :x, 0},
+
{:add, :x, :z},
+
{:mod, :x, 26},
+
{:div, :z, 26},
+
{:add, :x, -16},
+
{:eql, :x, :w},
+
{:eql, :x, 0},
+
{:mul, :y, 0},
+
{:add, :y, 25},
+
{:mul, :y, :x},
+
{:add, :y, 1},
+
{:mul, :z, :y},
+
{:mul, :y, 0},
+
{:add, :y, :w},
+
{:add, :y, 4},
+
{:mul, :y, :x},
+
{:add, :z, :y}
+
],
+
[
+
{:inp, :w},
+
{:mul, :x, 0},
+
{:add, :x, :z},
+
{:mod, :x, 26},
+
{:div, :z, 1},
+
{:add, :x, 14},
+
{:eql, :x, :w},
+
{:eql, :x, 0},
+
{:mul, :y, 0},
+
{:add, :y, 25},
+
{:mul, :y, :x},
+
{:add, :y, 1},
+
{:mul, :z, :y},
+
{:mul, :y, 0},
+
{:add, :y, :w},
+
{:add, :y, 12},
+
{:mul, :y, :x},
+
{:add, :z, :y}
+
],
+
[
+
{:inp, :w},
+
{:mul, :x, 0},
+
{:add, :x, :z},
+
{:mod, :x, 26},
+
{:div, :z, 1},
+
{:add, :x, 15},
+
{:eql, :x, :w},
+
{:eql, :x, 0},
+
{:mul, :y, 0},
+
{:add, :y, 25},
+
{:mul, :y, :x},
+
{:add, :y, 1},
+
{:mul, :z, :y},
+
{:mul, :y, 0},
+
{:add, :y, :w},
+
{:add, :y, 9},
+
{:mul, :y, :x},
+
{:add, :z, :y}
+
],
+
[
+
{:inp, :w},
+
{:mul, :x, 0},
+
{:add, :x, :z},
+
{:mod, :x, 26},
+
{:div, :z, 26},
+
{:add, :x, -7},
+
{:eql, :x, :w},
+
{:eql, :x, 0},
+
{:mul, :y, 0},
+
{:add, :y, 25},
+
{:mul, :y, :x},
+
{:add, :y, 1},
+
{:mul, :z, :y},
+
{:mul, :y, 0},
+
{:add, :y, :w},
+
{:add, :y, 10},
+
{:mul, :y, :x},
+
{:add, :z, :y}
+
],
+
[
+
{:inp, :w},
+
{:mul, :x, 0},
+
{:add, :x, :z},
+
{:mod, :x, 26},
+
{:div, :z, 26},
+
{:add, :x, -11},
+
{:eql, :x, :w},
+
{:eql, :x, 0},
+
{:mul, :y, 0},
+
{:add, :y, 25},
+
{:mul, :y, :x},
+
{:add, :y, 1},
+
{:mul, :z, :y},
+
{:mul, :y, 0},
+
{:add, :y, :w},
+
{:add, :y, 11},
+
{:mul, :y, :x},
+
{:add, :z, :y}
+
],
+
[
+
{:inp, :w},
+
{:mul, :x, 0},
+
{:add, :x, :z},
+
{:mod, :x, 26},
+
{:div, :z, 26},
+
{:add, :x, -6},
+
{:eql, :x, :w},
+
{:eql, :x, 0},
+
{:mul, :y, 0},
+
{:add, :y, 25},
+
{:mul, :y, :x},
+
{:add, :y, 1},
+
{:mul, :z, :y},
+
{:mul, :y, 0},
+
{:add, :y, :w},
+
{:add, :y, 6},
+
{:mul, :y, :x},
+
{:add, :z, :y}
+
],
+
[
+
{:inp, :w},
+
{:mul, :x, 0},
+
{:add, :x, :z},
+
{:mod, :x, 26},
+
{:div, :z, 26},
+
{:add, :x, -11},
+
{:eql, :x, :w},
+
{:eql, :x, 0},
+
{:mul, :y, 0},
+
{:add, :y, 25},
+
{:mul, :y, :x},
+
{:add, :y, 1},
+
{:mul, :z, :y},
+
{:mul, :y, 0},
+
{:add, :y, :w},
+
{:add, :y, 15},
+
{:mul, :y, :x},
+
{:add, :z, :y}
+
]
+
]
```
```elixir
-
IO.inspect(Day24.evaluate(input, 11_111_111_111_161))
+
List.myers_difference(hd(digits), Enum.at(digits, 4))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
[
+
eq: [{:inp, :w}, {:mul, :x, 0}, {:add, :x, :z}, {:mod, :x, 26}],
+
del: [{:div, :z, 1}, {:add, :x, 11}],
+
ins: [{:div, :z, 26}, {:add, :x, -3}],
+
eq: [
+
{:eql, :x, :w},
+
{:eql, :x, 0},
+
{:mul, :y, 0},
+
{:add, :y, 25},
+
{:mul, :y, :x},
+
{:add, :y, 1},
+
{:mul, :z, :y},
+
{:mul, :y, 0},
+
{:add, :y, :w}
+
],
+
del: [{:add, :y, 16}],
+
ins: [{:add, :y, 12}],
+
eq: [{:mul, :y, :x}, {:add, :z, :y}]
+
]
+
```
+
+
```elixir
+
params =
+
Enum.map(digits, fn sub ->
+
[5, 15]
+
|> Enum.map(&Enum.at(sub, &1))
+
|> Enum.map(&elem(&1, 2))
+
end)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
[
+
[11, 16],
+
~c"\f\v",
+
~c"\r\f",
+
[-5, 12],
+
[-3, 12],
+
[14, 2],
+
[15, 11],
+
[-16, 4],
+
[14, 12],
+
[15, 9],
+
[-7, 10],
+
[-11, 11],
+
[-6, 6],
+
[-11, 15]
+
]
+
```
+
+
```elixir
+
defmodule ALU do
+
def solve(params, range) do
+
params |> solve(0, [], range) |> Enum.reverse() |> Integer.undigits()
+
end
+
+
defp solve([], _z, acc, _range), do: acc
+
+
defp solve([[a, b] | rest], z, acc, range) when a > 0 do
+
Enum.find_value(range, fn w ->
+
solve(rest, 26 * z + w + b, [w | acc], range)
+
end)
+
end
+
+
defp solve([[a, _] | rest], z, acc, range) when a < 0 do
+
value = rem(z, 26) + a
+
+
if value in range do
+
solve(rest, div(z, 26), [value | acc], range)
+
end
+
end
+
end
```
<!-- livebook:{"output":true} -->
```
-
%{w: 1, x: 1, y: 16, z: 207697766}
+
{:module, ALU, <<70, 79, 82, 49, 0, 0, 10, ...>>, {:solve, 4}}
+
```
+
+
## Part 1
+
+
```elixir
+
ALU.solve(params, 9..1//-1)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
41299994879959
+
```
+
+
## Part 2
+
+
```elixir
+
ALU.solve(params, 1..9)
```
<!-- livebook:{"output":true} -->
```
-
%{w: 1, x: 1, y: 16, z: 207697766}
+
11189561113216
```
+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} =
+4 -12
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} =
···
def run(%__MODULE__{} = mb, rounds, calming) do
1..rounds
-
|> Enum.reduce(mb, fn r, mb ->
+
|> Enum.reduce(mb, fn _, mb ->
# IO.inspect(r, label: :round)
round(mb, calming)
end)
···
|> Enum.map(& &1.passes)
|> Enum.sort(:desc)
|> Enum.take(2)
-
|> Enum.reduce(&*/2)
+
|> Enum.product()
end
defp round(%__MODULE__{} = mb, calming) do
···
<!-- livebook:{"output":true} -->
```
-
warning: variable "r" is unused (if the variable is not meant to be used, prefix it with an underscore)
-
2022/day11.livemd#cell:wtmu5fny2ud5f5f6xet6khgysonm2y3n:17: MonkeyBusiness.run/3
-
-
```
-
-
<!-- livebook:{"output":true} -->
-
-
```
-
{:module, MonkeyBusiness, <<70, 79, 82, 49, 0, 0, 21, ...>>, {:lcm, 2}}
+
{:module, MonkeyBusiness, <<70, 79, 82, 49, 0, 0, 20, ...>>, {:lcm, 2}}
```
## Task 1
+115 -21
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} =
···
```
warning: variable "graph" is unused (there is a variable with the same name in the context, use the pin operator (^) to match on it or prefix this variable with underscore if it is not meant to be used)
-
2022/day12.livemd#cell:7urrvoyk6ltuxa4kdqc63nncfh37x2fn:30
+
2022/day12.livemd#cell:6nz6sdhe57lxfvshc57dctj7qaalwwz3:42
```
···
<!-- livebook:{"output":true} -->
```
-
[32256290, 409066827, 186924390, 1502865800, 887663648, 2543466388, 697356458, 1070575781,
-
1659702078, 4000784021, 1947564743, 2361038489, 3904452243, 3615669650, 270460033, 1281654811,
-
3153535741, 2393890474, 3946102901, 2210758189, 2982223724, 2654353783, 2656280720, 3935389969,
-
2818948768, 4279780723, 3595206681, 3496428192, 2269119594, 2583881244, 3997991000, 520325395,
-
457672928, 1453390554, 3289433936, 2574402082, 1560492086, 3242480874, 389839366, 4176230802,
-
1147783117, 2469841095, 2034019869, 438932546, 1799582666, 1100008137, 467060197, 162439868,
-
3928107970, 800548913, ...]
+
[
+
{59, 38},
+
{38, 5},
+
{76, 17},
+
{66, 36},
+
{54, 26},
+
{10, 18},
+
{3, 21},
+
{42, 40},
+
{73, 32},
+
{43, 36},
+
{2, 9},
+
{80, 31},
+
{20, 12},
+
{63, 11},
+
{5, 15},
+
{76, 4},
+
{136, 4},
+
{3, 9},
+
{90, 11},
+
{85, 39},
+
{24, 29},
+
{91, 28},
+
{55, 27},
+
{108, 10},
+
{84, 4},
+
{9, 9},
+
{161, 38},
+
{3, 33},
+
{68, 22},
+
{143, 3},
+
{49, 8},
+
{70, 26},
+
{39, 25},
+
{18, 13},
+
{88, 0},
+
{32, 21},
+
{96, 3},
+
{84, 40},
+
{53, 1},
+
{88, 30},
+
{120, 10},
+
{36, 4},
+
{115, 13},
+
{112, 3},
+
{42, 0},
+
{4, 17},
+
{35, 12},
+
{114, 19},
+
{20, ...},
+
{...},
+
...
+
]
```
```elixir
···
if has_negative_cycle?(distances, weights) do
nil
else
-
Map.new(distances, fn {k, v} -> {Map.fetch!(vertices, k), v} end)
+
Map.new(distances, fn {k, v} -> {Map.fetch!(vs, k), v} end)
end
end
···
<!-- livebook:{"output":true} -->
```
-
{:module, BellmanFord, <<70, 79, 82, 49, 0, 0, 19, ...>>, {:has_negative_cycle?, 2}}
+
{:module, BellmanFord, <<70, 79, 82, 49, 0, 0, 18, ...>>, {:has_negative_cycle?, 2}}
```
```elixir
-
min_paths =
+
paths =
tgraph
# |> Graph.bellman_ford(stop)
|> BellmanFord.call(stop)
-
|> Map.take(lowest)
-
|> Map.values()
```
<!-- livebook:{"output":true} -->
```
-
[:infinity, :infinity, :infinity, 454, :infinity, :infinity, :infinity, :infinity, :infinity,
-
:infinity, :infinity, :infinity, :infinity, :infinity, :infinity, :infinity, :infinity, :infinity,
-
:infinity, :infinity, :infinity, :infinity, :infinity, :infinity, :infinity, :infinity, :infinity,
-
:infinity, :infinity, :infinity, :infinity, :infinity, :infinity, :infinity, :infinity, :infinity,
-
:infinity, :infinity, :infinity, :infinity, :infinity, :infinity, :infinity, :infinity, :infinity,
-
:infinity, :infinity, :infinity, :infinity, :infinity, ...]
+
%{
+
{76, 13} => :infinity,
+
{38, 2} => :infinity,
+
{1, 26} => 430,
+
{140, 11} => 100,
+
{32, 15} => 388,
+
{89, 14} => 328,
+
{35, 30} => 392,
+
{156, 9} => :infinity,
+
{4, 5} => 454,
+
{74, 12} => :infinity,
+
{11, 39} => 425,
+
{131, 5} => 323,
+
{22, 38} => 413,
+
{29, 25} => 403,
+
{86, 10} => :infinity,
+
{83, 36} => 366,
+
{29, 26} => 402,
+
{47, 27} => :infinity,
+
{9, 34} => 426,
+
{137, 16} => 12,
+
{90, 0} => :infinity,
+
{103, 39} => 289,
+
{126, 13} => :infinity,
+
{47, 38} => :infinity,
+
{128, 35} => 268,
+
{20, 3} => 412,
+
{145, 20} => 24,
+
{143, 39} => 247,
+
{79, 17} => 335,
+
{75, 0} => :infinity,
+
{150, 18} => 167,
+
{147, 10} => 178,
+
{148, 26} => 75,
+
{76, 2} => :infinity,
+
{138, 9} => 104,
+
{58, 33} => 372,
+
{150, 5} => 296,
+
{54, 31} => 374,
+
{22, 37} => 412,
+
{75, 36} => :infinity,
+
{91, 35} => :infinity,
+
{143, 4} => :infinity,
+
{121, 27} => 283,
+
{91, 38} => :infinity,
+
{159, 26} => 268,
+
{131, 24} => 124,
+
{58, 10} => 367,
+
{111, 14} => :infinity,
+
{75, ...} => 345,
+
{...} => 411,
+
...
+
}
```
```elixir
-
Enum.min(min_paths)
+
paths
+
|> Map.take(lowest)
+
|> Map.values()
+
|> Enum.min()
```
<!-- livebook:{"output":true} -->
+499
2022/day13.livemd
···
+
<!-- livebook:{"persist_outputs":true} -->
+
+
# Day 13
+
+
```elixir
+
Mix.install([
+
{:kino_aoc, git: "https://github.com/ljgago/kino_aoc"}
+
])
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
:ok
+
```
+
+
## Section
+
+
<!-- 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} =
+
KinoAOC.download_puzzle("2022", "13", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:ok,
+
"[[[2],3,[],[]]]\n[[6,9,1,3,[[2,9],4,8,[9,2,1]]],[],[[3],3]]\n\n[[7,[10,[3,2,6],10,[10],[4,8,7,4,7]]],[9,8,8,7]]\n[[3,9],[2,2,[6,[1,8],[10,7,8]],[[1,9,8],[],[],[2,4,2],[3]]],[8,[],[[7]]]]\n\n[[2,[6,1,0]],[],[]]\n[[[9],[[1,4],[1,10,9,2,6],6,2],4,[[10,9,3,8],6]],[[10,[]],[[1,8],6,6,7,0],[[1,9],0,4,[3],[8,8,8,10]]],[],[8,6,3,[5]],[[10],[[6,4,2,0],6,1,8,0],0,[[9],[3,4,0,5],[10]]]]\n\n[[2,7],[1,[4,[9,9,6]],0]]\n[[[[5,2]],10,5]]\n\n[[4,2,[2,[6]],5],[],[[[8],[6,10]],4,5,[[10,0],[10,1,9,10]]]]\n[[[[3,10,2,9,10],8,[4,5,5],1],[1,4,[6,4,9],[],8]],[10,2],[[0,[4,3,1,5],[2,6,2,1,6],6,[1,1]],7]]\n\n[[[5,2,[7,9,3,2,7],4,[1,3,0,7]]],[[],[[0,0,10],[7],[10,3,0,9]]],[[8,7,6,4],10,[[1,1,0,9,2],[],[6]]],[1,[],4,10,[]],[8,0,5]]\n[[[[10,6,4],[7,2]],7,[[8,9,7,6,5],2,8]],[],[[6,8,8,[7,6,1]]],[[7,5,[6],[2,7,10,4,6],[6,7,9]],[[2,0,2,3,6],[4,1,6,7,0]],[0,0,7,2,1],[[8,7],6,[4],6,1]],[[],[],[[],[9,5,4,8,3]],2]]\n\n[[[5,[4,10,6,9],2,[4,10,9,6,4],[5,2,9,5]]],[],[[1],[[10,6,6,5,10]],6,1]]\n[[[[2,8,6],8,6,4],[[1],8,9]],[10,[],[[2,5],[10],[5,1,6,3]]],[3,[]]]\n\n[[[[10,5,5,5,4]],8],[6,[[6,7,8],[3,2,5,4,6],3,5],1,[[5,7],10,8],[9,7]],[[[],[1,5,3,9],2,10]],[],[]]\n[[[7,10,6,[2],8]],[2,[],[10,[0,2,6]]]]\n\n[[[10,9,[],3]],[[10],[7,[5,8],9]],[[0],[[4,5,1],[5]],[[]],4,[[9],4,1]]]\n[[[[],8,[1,6]],[7]],[],[[7,[6,8],0,5,0],[2,6],[[6,4,7,1]],9]]\n\n[[[],[[5],[6,9]]],[]]\n[[5],[],[[8,[5],2],[2,0,[7],[8,2,1]],[1,[4,9,3],[8,1,3,1,4],[]],6,2]]\n\n[[[[5,3,10,4,10],[5,7],[5,9,2,5,1]]],[[[1],[2],8],10,9,4,[[5,5,7,4],1,[8,9,8]]],[2,[2,8],[7,7,7,0,4]]]\n[[9,4,[5],[]],[3,2,[5],[]],[[[],[4,8],10],8,[]],[7,[[7],7],[[1,4,6,4,7]],[]],[]]\n\n[[9],[[3,4,9,8],10,1],[9,[[8,2],2,2,[1,5]]],[[[1],[6]],2],[4,7,[3],[6,6],6]]\n[[[3,[5,0]],[[3],[5,5,10,0],[],[5,8,7]],3]]\n\n[[1,[1]],[],[10,[3,[5,8],9,[2,1,9],[7,4]],6,[[1],[4,10]],[5,[5,2]]],[[5,9],[8],6]]\n[[8,7,[0,[],10],[6]],[1],[[[9,6,9,7,8],9,[8,8,10,1,0],3,0],[2,2,[10,2],0,7]]]\n\n[[[[10,4,6,3],[1,6,2]],[],7]]\n[[8,1],[5,[[],[8,9,10,1]],5]]\n\n[[],[[4,0,[3,4,4,10,1]],2,[[3,3,3,5,3],3,8],5,10],[6]]\n[[[2,4,6,[9,3],[]]],[4,[1,[8,10,3,5,2],[10,3,9],8,[7,7,3,8,4]],[4,3],10]]\n\n[[3,[8,7,[6,1,5,7]],[9,[],[0,10],[2,1,2,4]],[[2,1,7,2],0,9,8,9],[[3,1,0],10]]]\n[[3,[6,9,4],[[2,1,10],8],10],[5,7,3,[[3,8]]],[6,[8,3,3,8],7,10,5]]\n\n[[[3,3,1],0,8,[3,[7,10,0,6],[7,9,10,7,10],4,1]],[[[],[],9],[9,5,[3,2,7,8],[7]],[[10,3],3],[8,5,[5,6,2,7,0]]],[10,6],[[9,[1]],9,[[1]]]]\n[[[[4],0,6,[8,3,7,6,2],5],10,[2,[0,5],[8,10,10,10,8],1,[2,2]]],[[[4,9,1,6]],[[9,1,3,10,0],7]],[1,7,4,4,[]],[]]\n\n[[4,[1]]]\n[[[[6,2,10,9,10],10],[[7,7,0,7,10],1,7,8],[9,[2,7,0,4]],10]]\n\n[[9],[[4,[8],[4,6,6],10]],[[3],[7,8,7,7]],[[[10,7,3,2,2]],[[],[],4,1,[6,4,10,10]],7,5,[7,5,0,10,[1,5,7]]]]\n[[[[8,8,9,8],[],[9,3,3]]],[8,[2],5,7,8]]\n\n[[[],[[],9,[0,4]]],[],[],[0,[1,[1]],[6,5,[3,10,1,0,6]],2,6]]\n[[6,[[4,4],1,[6]],[[5,5],[],4],7]]\n\n[[],[6,[[8],[7,3,3,6],3,8,[]]],[[0],[],6,[5,10,2,2]],[[0,3,0],2,[[9],2],3],[9,[9],7,2,[6,[],[0,9],1,[0]]]]\n[[3,[2,[10,3,0,6],0],1,9],[2,[[6]],[],[[1,1],7,[5,6,4,2],7,8],[0,[5,8,4],[]]]]\n\n[[5,7,[[7,7,6],7,5,[3,3,10,5]],3,6]]\n[[[[0,5,7]],0,[[8,7,9,1,5]],4],[[],[7,1,[10,9,7,3]],1,2,0],[[[]],[5,9],[10,2,[8,6,7,4],[]]]]\n\n[[9,[]],[[[8,2],[6,4,9,4,9],2],[4,6,9,9],2],[[],4,[[6,2,6],[4,4,9,0],[9,9,6],[2],9],[],1],[[[3,9,0],4],6,[]],[[],4]]\n[[[],[]]]\n\n[[0],[[[9,7,7],[3]]],[4,4],[],[6,5,[8,5,[3],[3,2,10,10,8],[6]]]]\n[[[3,[3,9,9],9,[0],10]],[],[[],[],[]],[[0,[5,6,3,3,4]],3,7],[[[0,4,5,2,0],10],9,9,[[0,1],6,3]]]\n\n[[6,2],[[]],[1,5,9,[[0,8,3,5,0],[8,8,10],4,9,3],[2,[8,9],[9,8,5,0,3]]]]\n[[2,1,5,5,9],[4,7],[[[9],[4,0,4,0],3,[]],3,[2],2,5]]\n\n[[[[]],[7,2],[0,[4,1],3],10],[[9],3],[[],9,[5,[2]],5],[0,[[3],[],[9,7,5],3,2],[5],[5]]]\n[[[[9,9],3,8,3],[10,[1,6,7,6,0],3,6,[10,10]],5],[],[1,[9,9,5,3],[2,[5,5,3,8,8],3,[1,7],0]]]\n\n[[],[[7,6],[[3],[],3,[0,9],[1]],0,[6]],[6,[[10,8,5,4],3]],[]]\n[[[[],[0,1,9],1,[3],7],0,[2,[2,4,1,0,9]],[[6,3,3,3,5]],[4]],[],[],[1,[],[],5,[[],1,1,[3]]]]\n\n[[3],[[[],5,[3,1,7,2],[10,10,5],[9,4,4,7,2]]],[8,[],8,[[2]],8]]\n[[],[[3,[0,6,7]],7,7],[2,6,[2,[],[]],[],[[1,9,2,6,9],[6],[9,6,3,1],4,[]]],[6,9,[[8,10,8,5,7],[6],[3]],5],[[[5,4,6],1,[1,10,9,2,2]],[[9,8,10],9,3,[2,4,1,10,0],[4]],6,7]]\n\n[[10,5],[],[[[4,3,5],[10],[10]]," <> ...}
+
```
+
+
```elixir
+
signals =
+
puzzle_input
+
|> String.split("\n\n", trim: true)
+
|> Enum.map(fn chunk ->
+
chunk
+
|> String.split("\n", trim: true)
+
|> Enum.map(&Code.string_to_quoted!/1)
+
end)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
[
+
[[[[2], 3, [], []]], [[6, 9, 1, 3, [[2, 9], 4, 8, [9, 2, 1]]], [], [[3], 3]]],
+
[
+
[[7, [10, [3, 2, 6], 10, '\n', [4, 8, 7, 4, 7]]], '\t\b\b\a'],
+
[[3, 9], [2, 2, [6, [1, 8], '\n\a\b'], [[1, 9, 8], [], [], [2, 4, 2], [3]]], [8, [], ['\a']]]
+
],
+
[
+
[[2, [6, 1, 0]], [], []],
+
[
+
['\t', [[1, 4], [1, 10, 9, 2, 6], 6, 2], 4, [[10, 9, 3, 8], 6]],
+
[[10, []], [[1, 8], 6, 6, 7, 0], [[1, 9], 0, 4, [3], '\b\b\b\n']],
+
[],
+
[8, 6, 3, [5]],
+
['\n', [[6, 4, 2, 0], 6, 1, 8, 0], 0, ['\t', [3, 4, 0, 5], '\n']]
+
]
+
],
+
[[[2, 7], [1, [4, [9, 9, 6]], 0]], [[[[5, 2]], 10, 5]]],
+
[
+
[[4, 2, [2, [6]], 5], [], [['\b', [6, 10]], 4, 5, [[10, 0], [10, 1, 9, 10]]]],
+
[
+
[[[3, 10, 2, 9, 10], 8, [4, 5, 5], 1], [1, 4, [6, 4, 9], [], 8]],
+
[10, 2],
+
[[0, [4, 3, 1, 5], [2, 6, 2, 1, 6], 6, [1, 1]], 7]
+
]
+
],
+
[
+
[
+
[[5, 2, [7, 9, 3, 2, 7], 4, [1, 3, 0, 7]]],
+
[[], [[0, 0, 10], '\a', [10, 3, 0, 9]]],
+
[[8, 7, 6, 4], 10, [[1, 1, 0, 9, 2], [], [6]]],
+
[1, [], 4, 10, []],
+
[8, 0, 5]
+
],
+
[
+
[[[10, 6, 4], [7, 2]], 7, [[8, 9, 7, 6, 5], 2, 8]],
+
[],
+
[[6, 8, 8, [7, 6, 1]]],
+
[
+
[7, 5, [6], [2, 7, 10, 4, 6], [6, 7, 9]],
+
[[2, 0, 2, 3, 6], [4, 1, 6, 7, 0]],
+
[0, 0, 7, 2, 1],
+
['\b\a', 6, [4], 6, 1]
+
],
+
[[], [], [[], [9, 5, 4, 8, 3]], 2]
+
]
+
],
+
[
+
[[[5, [4, 10, 6, 9], 2, [4, 10, 9, 6, 4], [5, 2, 9, 5]]], [], [[1], [[10, 6, 6, 5, 10]], 6, 1]],
+
[[[[2, 8, 6], 8, 6, 4], [[1], 8, 9]], [10, [], [[2, 5], '\n', [5, 1, 6, 3]]], [3, []]]
+
],
+
[
+
[
+
[[[10, 5, 5, 5, 4]], 8],
+
[6, [[6, 7, 8], [3, 2, 5, 4, 6], 3, 5], 1, [[5, 7], 10, 8], '\t\a'],
+
[[[], [1, 5, 3, 9], 2, 10]],
+
[],
+
[]
+
],
+
[[[7, 10, 6, [2], 8]], [2, [], [10, [0, 2, 6]]]]
+
],
+
[
+
[[[10, 9, [], 3]], ['\n', [7, [5, 8], 9]], [[0], [[4, 5, 1], [5]], [[]], 4, ['\t', 4, 1]]],
+
[[[[], 8, [1, 6]], '\a'], [], [[7, [6, 8], 0, 5, 0], [2, 6], [[6, 4, 7, 1]], 9]]
+
],
+
[
+
[[[], [[5], [6, 9]]], []],
+
[[5], [], [[8, [5], 2], [2, 0, '\a', [8, 2, 1]], [1, [4, 9, 3], [8, 1, 3, 1, 4], []], 6, 2]]
+
],
+
[
+
[
+
[[[5, 3, 10, 4, 10], [5, 7], [5, 9, 2, 5, 1]]],
+
[[[1], [2], 8], 10, 9, 4, [[5, 5, 7, 4], 1, '\b\t\b']],
+
[2, [2, 8], [7, 7, 7, 0, 4]]
+
],
+
[
+
[9, 4, [5], []],
+
[3, 2, [5], []],
+
[[[], [4, 8], 10], 8, []],
+
[7, ['\a', 7], [[1, 4, 6, 4, 7]], []],
+
[]
+
]
+
],
+
[
+
[
+
'\t',
+
[[3, 4, 9, 8], 10, 1],
+
[9, [[8, 2], 2, 2, [1, 5]]],
+
[[[1], [6]], 2],
+
[4, 7, [3], [6, 6], 6]
+
],
+
[[[3, [5, 0]], [[3], [5, 5, 10, 0], [], [5, 8, 7]], 3]]
+
],
+
[
+
[
+
[1, [1]],
+
[],
+
[10, [3, [5, 8], 9, [2, 1, 9], [7, 4]], 6, [[1], [4, 10]], [5, [5, 2]]],
+
[[5, 9], '\b', 6]
+
],
+
[
+
[8, 7, [0, [], 10], [6]],
+
[1],
+
[[[9, 6, 9, 7, 8], 9, [8, 8, 10, 1, 0], 3, 0], [2, 2, [10, 2], 0, 7]]
+
]
+
],
+
[[[[[10, 4, 6, 3], [1, 6, 2]], [], 7]], [[8, 1], [5, [[], [8, 9, 10, 1]], 5]]],
+
[
+
[[], [[4, 0, [3, 4, 4, 10, 1]], 2, [[3, 3, 3, 5, 3], 3, 8], 5, 10], [6]],
+
[
+
[[2, 4, 6, [9, 3], []]],
+
[4, [1, [8, 10, 3, 5, 2], [10, 3, 9], 8, [7, 7, 3, 8, 4]], [4, 3], 10]
+
]
+
],
+
[
+
[
+
[
+
3,
+
[8, 7, [6, 1, 5, 7]],
+
[9, [], [0, 10], [2, 1, 2, 4]],
+
[[2, 1, 7, 2], 0, 9, 8, 9],
+
[[3, 1, 0], 10]
+
]
+
],
+
[[3, [6, 9, 4], [[2, 1, 10], 8], 10], [5, 7, 3, [[3, 8]]], [6, [8, 3, 3, 8], 7, 10, 5]]
+
],
+
[
+
[
+
[[3, 3, 1], 0, 8, [3, [7, 10, 0, 6], '\a\t\n\a\n', 4, 1]],
+
[[[], [], 9], [9, 5, [3, 2, 7, 8], '\a'], [[10, 3], 3], [8, 5, [5, 6, 2, 7, 0]]],
+
[10, 6],
+
[[9, [1]], 9, [[1]]]
+
],
+
[
+
[[[4], 0, 6, [8, 3, 7, 6, 2], 5], 10, [2, [0, 5], '\b\n\n\n\b', 1, [2, 2]]],
+
[[[4, 9, 1, 6]], [[9, 1, 3, 10, 0], 7]],
+
[1, 7, 4, 4, []],
+
[]
+
]
+
],
+
[[[4, [1]]], [[[[6, 2, 10, 9, 10], 10], [[7, 7, 0, 7, 10], 1, 7, 8], [9, [2, 7, 0, 4]], 10]]],
+
[
+
[
+
'\t',
+
[[4, '\b', [4, 6, 6], 10]],
+
[[3], '\a\b\a\a'],
+
[[[10, 7, 3, 2, 2]], [[], [], 4, 1, [6, 4, 10, 10]], 7, 5, [7, 5, 0, 10, [1, 5, 7]]]
+
],
+
[[['\b\b\t\b', [], [9, 3, 3]]], [8, [2], 5, 7, 8]]
+
],
+
[
+
[[[], [[], 9, [0, 4]]], [], [], [0, [1, [1]], [6, 5, [3, 10, 1, 0, 6]], 2, 6]],
+
[[6, [[4, 4], 1, [6]], [[5, 5], [], 4], 7]]
+
],
+
[
+
[
+
[],
+
[6, ['\b', [7, 3, 3, 6], 3, 8, []]],
+
[[0], [], 6, [5, 10, 2, 2]],
+
[[0, 3, 0], 2, ['\t', 2], 3],
+
[9, '\t', 7, 2, [6, [], [0, 9], 1, [0]]]
+
],
+
[
+
[3, [2, [10, 3, 0, 6], 0], 1, 9],
+
[2, [[6]], [], [[1, 1], 7, [5, 6, 4, 2], 7, 8], [0, [5, 8, 4], []]]
+
]
+
],
+
[
+
[[5, 7, [[7, 7, 6], 7, 5, [3, 3, 10, 5]], 3, 6]],
+
[
+
[[[0, 5, 7]], 0, [[8, 7, 9, 1, 5]], 4],
+
[[], [7, 1, [10, 9, 7, 3]], 1, 2, 0],
+
[[[]], [5, 9], [10, 2, [8, 6, 7, 4], []]]
+
]
+
],
+
[
+
[
+
[9, []],
+
[[[8, 2], [6, 4, 9, 4, 9], 2], [4, 6, 9, 9], 2],
+
[[], 4, [[6, 2, 6], [4, 4, 9, 0], [9, 9, 6], [2], 9], [], 1],
+
[[[3, 9, 0], 4], 6, []],
+
[[], 4]
+
],
+
[[[], []]]
+
],
+
[
+
[[0], [['\t\a\a', [3]]], [4, 4], [], [6, 5, [8, 5, [3], [3, 2, 10, 10, 8], [6]]]],
+
[
+
[[3, [3, 9, 9], 9, [0], 10]],
+
[],
+
[[], [], []],
+
[[0, [5, 6, 3, 3, 4]], 3, 7],
+
[[[0, 4, 5, 2, 0], 10], 9, 9, [[0, 1], 6, 3]]
+
]
+
],
+
[
+
[[6, 2], [[]], [1, 5, 9, [[0, 8, 3, 5, 0], '\b\b\n', 4, 9, 3], [2, '\b\t', [9, 8, 5, 0, 3]]]],
+
[[2, 1, 5, 5, 9], [4, 7], [['\t', [4, 0, 4, 0], 3, []], 3, [2], 2, 5]]
+
],
+
[
+
[
+
[[[]], [7, 2], [0, [4, 1], 3], 10],
+
['\t', 3],
+
[[], 9, [5, [2]], 5],
+
[0, [[3], [], [9, 7, 5], 3, 2], [5], [5]]
+
],
+
[
+
[['\t\t', 3, 8, 3], [10, [1, 6, 7, 6, 0], 3, 6, '\n\n'], 5],
+
[],
+
[1, [9, 9, 5, 3], [2, [5, 5, 3, 8, 8], 3, [1, 7], 0]]
+
]
+
],
+
[
+
[[], [[7, 6], [[3], [], 3, [0, 9], [1]], 0, [6]], [6, [[10, 8, 5, 4], 3]], []],
+
[
+
[[[], [0, 1, 9], 1, [3], 7], 0, [2, [2, 4, 1, 0, 9]], [[6, 3, 3, 3, 5]], [4]],
+
[],
+
[],
+
[1, [], [], 5, [[], 1, 1, [3]]]
+
]
+
],
+
[
+
[[3], [[[], 5, [3, 1, 7, 2], [10, 10, 5], [9, 4, 4, 7, 2]]], [8, [], 8, [[2]], 8]],
+
[
+
[],
+
[[3, [0, 6, 7]], 7, 7],
+
[2, 6, [2, [], []], [], [[1, 9, 2, 6, 9], [6], [9, 6, 3, 1], 4, []]],
+
[6, 9, [[8, 10, 8, 5, 7], [6], [3]], 5],
+
[[[5, 4, 6], 1, [1, 10, 9, 2, 2]], ['\t\b\n', 9, 3, [2, 4, 1, 10, 0], [4]], 6, 7]
+
]
+
],
+
[
+
[[10, 5], [], [[[4, 3, 5], '\n', '\n'], 10, 8, 2, []], [[]], [5, 0]],
+
[
+
[[], 6, [5, 10]],
+
[[4, 3, [9, 1, 10, 0, 10], [6]], [[0, 2, 6, 5]], 7, [2, 7, [], 7, [7, 8, 3, 2]]],
+
[[7, [5, 4, 8, 4], 0, 4, '\b'], 3]
+
]
+
],
+
[
+
[
+
[[[10, 2, 1], [3], 3], [[3, 6], [3, 10, 2, 8], [], 6], 8, [[], 8, 8]],
+
[[[2, 5, 0, 9], 10], [[8, 8, 0, 2], [6], '\b'], ['\n', [5, 7, 8]], 10],
+
[[6], 9],
+
[[[], [4, 2, 9, 3, 10], 0, [2], 9]]
+
],
+
[
+
[[[0, 6, 6, 2], [6, 9, 6, 6, 1]], [[], 5], 6, 0],
+
[[[4, 9, 1, 3, 0]], 7, 3, 2],
+
[8, [], 10, ['\t', [3, 8], 0, [8, 1, 10]]],
+
[[[5, 8], [1, 6, 0, 6]]],
+
[
+
[1, 8, 8, [4, 1, 10, 3]],
+
[[8, 1, 4, 6, 1], [], [6, 0, 1, 8], 0],
+
7,
+
6,
+
[2, [2, 4, 4, 9, 0], 10, []]
+
]
+
]
+
],
+
[
+
[
+
[[[5], 1, [], 1, 1], [[3, 10, 6, 4], 2, [6, 8, 2], 7], [7, [7, 0, 8, 10, 8], 1], 10, 1],
+
[
+
['\t\a', 10, '\a', 8],
+
[8, [9, 10, 6, 10], 0, [1, 10]],
+
[[], [10, 3, 4], [8, 3, 0, 7, 7], [6, 8], 3],
+
1
+
],
+
[
+
4,
+
[[], [0, 2, 1, 6], [], 10, [9, 10, 5, 9, 0]],
+
[6, [5], [6, 10, 0, 5, 7], [2, 6, 0, 8], []]
+
]
+
],
+
['\t\b']
+
],
+
[
+
[
+
[0, []],
+
[[5], 10, 5, [[4, 10, 8]]],
+
[[], [[], [8, 1, 7], 2], [[4]], 4],
+
[[], []],
+
[7, [2, 6], 9, [3, [2, 4, 4, 3], 7]]
+
],
+
[[7, 3, 7, [2, 6, [0, 1, 10, 3], '\a'], 10], [], []]
+
],
+
[[[5, 10, 1, [[0, 4, 4, 3], [7, 4, 8, 2, 8], 0]]], [[], [10, [], [[8, 10, 9, 7, 0], 0, 7, 9]]]],
+
[
+
[[8, [7, [5]]], [7, 9, [8, 9, [5, 3], 1, 10]]],
+
[[6, 2, [[7, 4, 6], 1, 6, [3]]], [5, 6, 4, [[3, 3, 5, 3]]], [7, []], '\t', [4]]
+
],
+
[
+
[[0, [[1], 10, 3, 8, 9], 6]],
+
[
+
[[6, 1], 0, 5],
+
[7, ['\t\t', 3], []],
+
[[5, 4, [0, 10, 4, 9]], 10, 5, [[9, 5, 2, 8, 8], 8, 2, [1, 9, ...]]]
+
]
+
],
+
[
+
[
+
'\t',
+
[[[], [1, 9, 9, 0, 6], [9, 1, 7, 5, 0]], 4, 5, 3],
+
[[], [[9, 9, 10, 3], 2, [], 6, 0]],
+
[]
+
],
+
[[[], 2, 7], [[1, 7, [4, 2], 8], 10]]
+
],
+
[
+
[[3, 9, 5, 7, 8], [], [6, 9], [9, [], 7]],
+
[
+
[['\n', 8, 0, [3, 7, 5, 5]]],
+
[0, [5, 1, [10, 1, 1], [6]]],
+
[[[2, 8, 6], [1, 4, 6], [5, 1], [6, 3]]],
+
[[0, 7, 0], [6, [8, 2, 0, ...], '\b\t', [7, ...]], [7, 2, 7, [...], ...]],
+
[[[], [], [3, 4, ...], '\b'], 5, 4]
+
]
+
],
+
[
+
[
+
[10, 5],
+
[],
+
[[[3, 10], 1, [6, 4, 0], 5, 4], 6, [[], 4, [0], [7, ...]], '\n', 5],
+
[1, [[9, 0]]],
+
[9, 1, 4, 4, 4]
+
],
+
[
+
[0, 6, [[0, 6, 9]]],
+
[],
+
[3, [9, 5, [4, 7, ...], [2, ...], [...]], 9, 3, [[9, ...]]],
+
[[2, 0], [5, [10, 2], [0, ...]], 0, [[4, ...], [...], ...]]
+
]
+
],
+
[
+
[
+
[9, 9, 5, 0, 10],
+
[],
+
[[6], 1],
+
[9, 6, [], [[6, ...], [], ...]],
+
[6, [2, [4, ...], [...]], [4, [...], ...], 0, []]
+
],
+
[[], [5, 9, 5, [[1, 3, ...], 4, 10, ...], [3]], []]
+
],
+
[
+
[
+
[1, 1],
+
[7, ['\t\b', []], 5],
+
[['\a\b\a', 8, [6, 0], [2, ...], [...]], 9, 10],
+
[[8, 7, [6, ...]], [[2, 3], 2, 7, ...], []],
+
'\a'
+
],
+
[
+
[[[0, 8, 8, 4, 6], '\a\a\n\t', 10, [8, 9, ...], 4], [[8, 7, 6, 7]], [5, 8, []]],
+
[],
+
[[0, 0, 1]],
+
[],
+
[8, [], 4]
+
]
+
],
+
[
+
[
+
[3, [[], [], [10, 5, ...]], 8, 1, [[1, ...], [...], ...]],
+
[9, 7, [10, 5]],
+
[[[], [5, 0, ...], 7], '\b\b'],
+
[5, [1, 8, ...]]
+
],
+
[[[[3, 8, 4], [], [1, 3, ...], 8], 1, [5, [4, ...], '\b'], [[5, ...], 3, ...]]]
+
],
+
[
+
[[3, [9, [4, 4], [6], 6], 9, 10, 5], [], [[0, 0, [...]], 0], [8, [5, ...], 0, ...], []],
+
[[10, [], '\a', [[...]]], [], [[[8, ...], 1, ...]]]
+
],
+
[
+
[
+
[[[8, 6, 1], 5, [1, ...], [...], ...], [0, 6, [], ...], 9, [[...]], 1],
+
[1, 3, 1],
+
[['\n\t\a\b', 8, ...], [9, ...], [...], ...]
+
],
+
[[[], 2, 10, [...], ...], [7, 2, 4, ...], [[[], ...]]]
+
],
+
[
+
[[], [10, [4, ...], [...], ...], [[5, ...], [], ...], [[...]]],
+
[[['\n'], [8, ...], [...]], [6], [], [...]]
+
],
+
[[0, 3, 2, 5], [0, 3, 2, ...]],
+
[[[[2, ...], 9, ...], [[...], ...], [...], ...], [[9, ...], [...]]],
+
[[[[...], ...], [...]], [[...], ...]],
+
[[[...], ...], [...]],
+
[[...], ...],
+
[...],
+
...
+
]
+
```
+
+
```elixir
+
defmodule Signal do
+
def compare(a, a), do: :eq
+
def compare(a, b) when is_integer(a) and is_integer(b) and a < b, do: :lt
+
def compare([], [_ | _]), do: :lt
+
def compare([a | as], [b | bs]), do: with(:eq <- compare(a, b), do: compare(as, bs))
+
+
def compare(a, b)
+
when is_integer(a) and is_list(b)
+
when is_list(a) and is_integer(b),
+
do: compare(List.wrap(a), List.wrap(b))
+
+
def compare(_, _), do: :gt
+
end
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:module, Signal, <<70, 79, 82, 49, 0, 0, 8, ...>>, {:compare, 2}}
+
```
+
+
## Task 1
+
+
```elixir
+
signals
+
|> Enum.with_index(1)
+
|> Enum.filter(fn {[a, b], _idx} -> Signal.compare(a, b) != :gt end)
+
|> Enum.map(&elem(&1, 1))
+
|> Enum.sum()
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
6656
+
```
+
+
## Task 2
+
+
```elixir
+
div1 = [[2]]
+
div2 = [[6]]
+
+
signals
+
|> Enum.concat([[div1], [div2]])
+
|> Enum.concat()
+
|> Enum.sort(Signal)
+
|> Enum.with_index(1)
+
|> Enum.filter(fn {packet, _idx} -> packet in [div1, div2] end)
+
|> Enum.map(&elem(&1, 1))
+
|> Enum.product()
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
19716
+
```
+225
2022/day14.livemd
···
+
<!-- livebook:{"persist_outputs":true} -->
+
+
# Day 14
+
+
```elixir
+
Mix.install(
+
[
+
{:kino_aoc, git: "https://github.com/ljgago/kino_aoc"},
+
:image
+
],
+
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} -->
+
+
```
+
:ok
+
```
+
+
## Setup
+
+
<!-- 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} =
+
KinoAOC.download_puzzle("2022", "14", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:ok,
+
"492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26\n481,92 -> 481,96 -> 476,96 -> 476,99 -> 487,99 -> 487,96 -> 485,96 -> 485,92\n460,73 -> 460,70 -> 460,73 -> 462,73 -> 462,69 -> 462,73 -> 464,73 -> 464,65 -> 464,73 -> 466,73 -> 466,65 -> 466,73 -> 468,73 -> 468,64 -> 468,73 -> 470,73 -> 470,68 -> 470,73 -> 472,73 -> 472,68 -> 472,73\n470,76 -> 470,80 -> 466,80 -> 466,84 -> 481,84 -> 481,80 -> 474,80 -> 474,76\n492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26\n495,155 -> 499,155\n460,73 -> 460,70 -> 460,73 -> 462,73 -> 462,69 -> 462,73 -> 464,73 -> 464,65 -> 464,73 -> 466,73 -> 466,65 -> 466,73 -> 468,73 -> 468,64 -> 468,73 -> 470,73 -> 470,68 -> 470,73 -> 472,73 -> 472,68 -> 472,73\n500,138 -> 505,138\n484,39 -> 484,38 -> 484,39 -> 486,39 -> 486,33 -> 486,39 -> 488,39 -> 488,30 -> 488,39 -> 490,39 -> 490,35 -> 490,39 -> 492,39 -> 492,38 -> 492,39 -> 494,39 -> 494,30 -> 494,39 -> 496,39 -> 496,36 -> 496,39\n481,92 -> 481,96 -> 476,96 -> 476,99 -> 487,99 -> 487,96 -> 485,96 -> 485,92\n492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26\n460,73 -> 460,70 -> 460,73 -> 462,73 -> 462,69 -> 462,73 -> 464,73 -> 464,65 -> 464,73 -> 466,73 -> 466,65 -> 466,73 -> 468,73 -> 468,64 -> 468,73 -> 470,73 -> 470,68 -> 470,73 -> 472,73 -> 472,68 -> 472,73\n492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26\n460,73 -> 460,70 -> 460,73 -> 462,73 -> 462,69 -> 462,73 -> 464,73 -> 464,65 -> 464,73 -> 466,73 -> 466,65 -> 466,73 -> 468,73 -> 468,64 -> 468,73 -> 470,73 -> 470,68 -> 470,73 -> 472,73 -> 472,68 -> 472,73\n492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26\n489,115 -> 489,119 -> 481,119 -> 481,126 -> 494,126 -> 494,119 -> 493,119 -> 493,115\n492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26\n485,112 -> 485,102 -> 485,112 -> 487,112 -> 487,111 -> 487,112 -> 489,112 -> 489,105 -> 489,112\n481,92 -> 481,96 -> 476,96 -> 476,99 -> 487,99 -> 487,96 -> 485,96 -> 485,92\n484,39 -> 484,38 -> 484,39 -> 486,39 -> 486,33 -> 486,39 -> 488,39 -> 488,30 -> 488,39 -> 490,39 -> 490,35 -> 490,39 -> 492,39 -> 492,38 -> 492,39 -> 494,39 -> 494,30 -> 494,39 -> 496,39 -> 496,36 -> 496,39\n470,49 -> 470,53 -> 468,53 -> 468,60 -> 477,60 -> 477,53 -> 476,53 -> 476,49\n483,160 -> 487,160\n492,26 -> 492,17 -> 492,26 -> 494,26 -> 494,16 -> 494,26 -> 496,26 -> 496,22 -> 496,26 -> 498,26 -> 498,17 -> 498,26 -> 500,26 -> 500,20 -> 500,26 -> 502,26 -> 502,25 -> 502,26 -> 504,26 -> 504,23 -> 504,26 -> 506,26 -> 506,21 -> 506,26 -> 508,26 -> 508,16 -> 508,26 -> 510,26 -> 510,24 -> 510,26\n460,73 -> 460,70 -> 460,73 -> 462,73 -> 462,69 -> 462,73 -> 464,73 -> 464,65 -> 464,73 -> 466,73 -> 466,65 -> 466,73 -> 468,73 -> 468,64 -> 468,73 -> 47" <> ...}
+
```
+
+
```elixir
+
defmodule Cave do
+
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(&Map.merge/2)
+
+
{width, height} =
+
for {{x, y}, _} <- map,
+
reduce: {nil, nil} do
+
{nil, nil} ->
+
{x..x, y}
+
+
{min_x..max_x, max_y} ->
+
{min(min_x, x)..max(max_x, x), max(max_y, y)}
+
end
+
+
%__MODULE__{map: map, start: start, width: width, height: height}
+
end
+
+
def parse_point(str) do
+
[x, y] = String.split(str, ",")
+
+
{String.to_integer(x), String.to_integer(y)}
+
end
+
+
def parse_line(line) do
+
points =
+
line
+
|> String.split(" -> ")
+
|> Enum.map(&parse_point/1)
+
|> Enum.chunk_every(2, 1, :discard)
+
|> Enum.flat_map(fn
+
[{x, y1}, {x, y2}] ->
+
for y <- y1..y2, do: {x, y}
+
+
[{x1, y}, {x2, y}] ->
+
for x <- x1..x2, do: {x, y}
+
end)
+
|> Map.new(&{&1, :rock})
+
+
points
+
end
+
+
def drop_sand(%__MODULE__{} = cave), do: drop_sand(cave, cave.start)
+
+
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__{map: map} = cave, {sx, sy} = p) do
+
cond do
+
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
+
+
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)
+
+
{:ok, image} =
+
Image.mutate(image, fn im ->
+
Image.Draw.point(im, sx - x0 + 1, sy + 1, color: :red)
+
+
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)
+
+
image
+
end
+
end
+
+
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, 9, ...>>, {:to_livebook, 1}}
+
```
+
+
```elixir
+
cave = Cave.parse(puzzle_input)
+
+
floor = cave.height + 1
+
+
cave = struct(cave, height: floor)
+
```
+
+
## Task 1
+
+
```elixir
+
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} -->
+
+
```
+
768
+
```
+
+
## Task 2
+
+
```elixir
+
{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
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
26686
+
```
+
+
```elixir
+
Kino.render(pyramid)
+
+
:ok
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
:ok
+
```
+330
2022/day15.livemd
···
+
<!-- livebook:{"persist_outputs":true} -->
+
+
# Day 15
+
+
```elixir
+
Mix.install([
+
{:kino_aoc, git: "https://github.com/ljgago/kino_aoc"}
+
])
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
:ok
+
```
+
+
## Section
+
+
<!-- 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} =
+
KinoAOC.download_puzzle("2022", "15", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:ok,
+
"Sensor at x=2288642, y=2282562: closest beacon is at x=1581951, y=2271709\nSensor at x=2215505, y=2975419: closest beacon is at x=2229474, y=3709584\nSensor at x=275497, y=3166843: closest beacon is at x=-626874, y=3143870\nSensor at x=1189444, y=2115305: closest beacon is at x=1581951, y=2271709\nSensor at x=172215, y=2327851: closest beacon is at x=-101830, y=2000000\nSensor at x=3953907, y=1957660: closest beacon is at x=2882446, y=1934422\nSensor at x=685737, y=2465261: closest beacon is at x=1581951, y=2271709\nSensor at x=1458348, y=2739442: closest beacon is at x=1581951, y=2271709\nSensor at x=3742876, y=2811554: closest beacon is at x=3133845, y=3162635\nSensor at x=437819, y=638526: closest beacon is at x=-101830, y=2000000\nSensor at x=2537979, y=1762726: closest beacon is at x=2882446, y=1934422\nSensor at x=1368739, y=2222863: closest beacon is at x=1581951, y=2271709\nSensor at x=2743572, y=3976937: closest beacon is at x=2229474, y=3709584\nSensor at x=2180640, y=105414: closest beacon is at x=3011118, y=-101788\nSensor at x=3845753, y=474814: closest beacon is at x=3011118, y=-101788\nSensor at x=2493694, y=3828087: closest beacon is at x=2229474, y=3709584\nSensor at x=2786014, y=3388077: closest beacon is at x=3133845, y=3162635\nSensor at x=3593418, y=3761871: closest beacon is at x=3133845, y=3162635\nSensor at x=856288, y=3880566: closest beacon is at x=2229474, y=3709584\nSensor at x=1757086, y=2518373: closest beacon is at x=1581951, y=2271709\nSensor at x=2853518, y=2939097: closest beacon is at x=3133845, y=3162635\nSensor at x=1682023, y=1449902: closest beacon is at x=1581951, y=2271709\nSensor at x=3360575, y=1739100: closest beacon is at x=2882446, y=1934422\nSensor at x=2904259, y=1465606: closest beacon is at x=2882446, y=1934422\nSensor at x=3078500, y=3564862: closest beacon is at x=3133845, y=3162635\nSensor at x=2835288, y=1011055: closest beacon is at x=2882446, y=1934422\nSensor at x=2998762, y=2414323: closest beacon is at x=2882446, y=1934422\n"}
+
```
+
+
```elixir
+
points =
+
puzzle_input
+
|> String.split("\n", trim: true)
+
|> Enum.map(fn line ->
+
%{"sx" => sx, "sy" => sy, "bx" => bx, "by" => by} =
+
Regex.named_captures(
+
~r/x=(?<sx>-?\d+), y=(?<sy>-?\d+):.*x=(?<bx>-?\d+), y=(?<by>-?\d+)/,
+
line
+
)
+
+
%{
+
sensor: {String.to_integer(sx), String.to_integer(sy)},
+
beacon: {String.to_integer(bx), String.to_integer(by)}
+
}
+
end)
+
+
circles =
+
points
+
|> Enum.map(fn %{beacon: {bx, by}, sensor: {sx, sy}} ->
+
radius = abs(bx - sx) + abs(by - sy)
+
+
{{sx, sy}, radius}
+
end)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
[
+
{{2288642, 2282562}, 717544},
+
{{2215505, 2975419}, 748134},
+
{{275497, 3166843}, 925344},
+
{{1189444, 2115305}, 548911},
+
{{172215, 2327851}, 601896},
+
{{3953907, 1957660}, 1094699},
+
{{685737, 2465261}, 1089766},
+
{{1458348, 2739442}, 591336},
+
{{3742876, 2811554}, 960112},
+
{{437819, 638526}, 1901123},
+
{{2537979, 1762726}, 516163},
+
{{1368739, 2222863}, 262058},
+
{{2743572, 3976937}, 781451},
+
{{2180640, 105414}, 1037680},
+
{{3845753, 474814}, 1411237},
+
{{2493694, 3828087}, 382723},
+
{{2786014, 3388077}, 573273},
+
{{3593418, 3761871}, 1058809},
+
{{856288, 3880566}, 1544168},
+
{{1757086, 2518373}, 421799},
+
{{2853518, 2939097}, 503865},
+
{{1682023, 1449902}, 921879},
+
{{3360575, 1739100}, 673451},
+
{{2904259, 1465606}, 490629},
+
{{3078500, 3564862}, 457572},
+
{{2835288, 1011055}, 970525},
+
{{2998762, 2414323}, 596217}
+
]
+
```
+
+
```elixir
+
defmodule RangeSet do
+
defstruct ranges: []
+
+
def new(), do: %__MODULE__{}
+
def new(%__MODULE__{} = set), do: set
+
def new(a..b//1) when a <= b, do: %__MODULE__{ranges: [a..b//1]}
+
def new(b..a//-1) when b > a, do: %__MODULE__{ranges: [a..b//1]}
+
def new(list), do: %__MODULE__{ranges: list |> Enum.sort_by(& &1.first) |> squash()}
+
+
def min(%__MODULE__{ranges: [a.._ | _]}), do: a
+
+
def max(%__MODULE__{ranges: ranges}) do
+
_..a = List.last(ranges)
+
+
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
+
|> Enum.chunk_every(2, 1, :discard)
+
|> Enum.flat_map(fn [_..a, b.._] -> [(a + 1)..(b - 1)] end)
+
|> squash()
+
+
%__MODULE__{ranges: gaps}
+
end
+
+
def empty?(%__MODULE__{ranges: ranges}), do: ranges == []
+
+
def has?(%__MODULE__{ranges: ranges}, value), do: Enum.any?(ranges, &(value in &1))
+
+
def length(%__MODULE__{ranges: ranges}),
+
do: Enum.reduce(ranges, 0, fn r, acc -> acc + Range.size(r) end)
+
+
def to_list(%__MODULE__{ranges: ranges}),
+
do: Enum.flat_map(ranges, & &1)
+
+
def remove(%__MODULE__{ranges: ranges}, int) when is_integer(int) do
+
new_ranges =
+
Enum.flat_map(ranges, fn a..b ->
+
cond do
+
a == int -> [(int + 1)..b]
+
b == int -> [a..(int - 1)]
+
int in a..b -> [a..(int - 1), (int + 1)..b]
+
true -> [a..b]
+
end
+
end)
+
+
%__MODULE__{ranges: new_ranges}
+
end
+
+
def remove(%__MODULE__{ranges: ranges}, c..d//1) when c <= d do
+
new_ranges =
+
Enum.flat_map(ranges, fn a..b ->
+
cond do
+
a in c..d and b in c..d -> []
+
a < c and b in c..d -> [a..(c - 1)]
+
a in c..d and b > d -> [(d + 1)..b]
+
c in a..b and d in a..b -> [a..(c - 1), (d + 1)..b]
+
true -> [a..b]
+
end
+
end)
+
+
%__MODULE__{ranges: new_ranges}
+
end
+
+
def remove(%__MODULE__{} = set, %__MODULE__{ranges: ranges}),
+
do: Enum.reduce(ranges, set, &remove(&2, &1))
+
+
def remove(%__MODULE__{} = set, list),
+
do: Enum.reduce(list, set, &remove(&2, &1))
+
+
def add(set, int) when is_integer(int), do: add(set, int..int//1)
+
+
def add(set, a..b//-1), do: add(set, b..a//1)
+
+
def add(%__MODULE__{} = set, a..b//1) when a > b, do: set
+
+
def add(%__MODULE__{ranges: ranges}, a..b//1 = range) when a <= b do
+
ranges =
+
ranges
+
|> insert_sorted(range)
+
|> squash()
+
+
%__MODULE__{ranges: ranges}
+
end
+
+
defp insert_sorted([], val), do: [val]
+
+
defp insert_sorted([a.._ = x | rest], b.._ = y) when a < b,
+
do: [x | insert_sorted(rest, y)]
+
+
defp insert_sorted(rest, y),
+
do: [y | rest]
+
+
defp squash([]), do: []
+
defp squash([_] = list), do: list
+
+
defp squash([a..b, c..d | rest]) when b >= c - 1,
+
do: squash([a..max(b, d) | rest])
+
+
defp squash([x | rest]), do: [x | squash(rest)]
+
end
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:module, RangeSet, <<70, 79, 82, 49, 0, 0, 39, ...>>, {:squash, 1}}
+
```
+
+
```elixir
+
RangeSet.new([6..10, -8..26])
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
%RangeSet{ranges: [-8..26]}
+
```
+
+
Our list can be change into list of radii of the circles (in Taxicab metric these will be visually squares), so then using inequality for circle
+
+
$$
+
r \ge d(C, a)
+
$$
+
+
where $d(a, b)$ is distance function for given metric, we can compute possible ranges of values at given line in constant time. In Taxicab metric $d$ is defined as:
+
+
$$
+
d(a, b) = |a_x - b_x| + |a_y - b_y|
+
$$
+
+
So after substitution at the above inequality we get:
+
+
$$
+
r \ge |C_x - a_x| + |C_y - a_y|
+
$$
+
+
In the task $a_y = const$ and $C = const$, so we need to solve only for $a_x$. So we can define $d_y = |C_y - a_y| = const$ as well.
+
+
That gives us:
+
+
$$
+
|a_x - C_x| \le r - d_y
+
$$
+
+
$$
+
\begin{align*}
+
\therefore&\ -r + d_y &\le&\ a_x - C_x &\le&\ r - d_y \\
+
\therefore&\ -r + d_y + C_x &\le&\ a_x &\le&\ r - d_y + C_x
+
\end{align*}
+
$$
+
+
```elixir
+
defmodule Beacons do
+
def covered_at_line(circles, a_y) do
+
Enum.reduce(circles, RangeSet.new(), fn {{c_x, c_y}, r}, set ->
+
d_y = abs(c_y - a_y)
+
RangeSet.add(set, (-r + d_y + c_x)..(r - d_y + c_x)//1)
+
end)
+
end
+
end
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:module, Beacons, <<70, 79, 82, 49, 0, 0, 9, ...>>, {:covered_at_line, 2}}
+
```
+
+
## Task 1
+
+
```elixir
+
a_y = 2_000_000
+
+
beacons_at_line =
+
Enum.flat_map(points, fn %{beacon: {x, y}} -> if y == a_y, do: [x], else: [] end)
+
+
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
+
```
+
+
## Task 2
+
+
```elixir
+
range = 4_000_000..0//-1
+
# range = 0..4_000_000
+
+
{y, [x]} =
+
range
+
|> Enum.find_value(fn y ->
+
covered = Beacons.covered_at_line(circles, y)
+
+
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} -->
+
+
```
+
10553942650264
+
```
+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
+
+
```
+250
2022/day21.livemd
···
+
<!-- livebook:{"persist_outputs":true} -->
+
+
# Day 21
+
+
```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: 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"},"chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2022", "21", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:ok,
+
"jqtt: tnwg * mbnq\nvsww: jmrn + twmm\nppws: qtfb * rdsp\nljqm: 14\nbsvb: tbqb - fqqm\nwfpq: hgdp * ddvm\njhtm: 2\nslnm: rrtr * lhwh\nlgzs: jtrw * dfmw\nrmwf: pmsv - llsm\nprzw: bqwv + ghcz\nrqwg: 6\npsrl: 4\njddv: plnt * gcfc\nvtbv: rwmn + zcwm\nhgtf: qrlv + brzm\nhhlf: 2\nqnwv: vhwb + thlf\nsbwr: ppws * rlvq\ncpld: gwmj + rhcd\nnnmv: gjsm * jrpf\nltft: rfvj * cttp\nsjzd: 2\nfnnl: rpmq * zgms\nthmv: 3\nslsp: 5\nqnhh: crqv + hdgl\nlzmd: 2\ncfjz: 18\nnftb: 3\nwndb: ztgl * cwnt\nbjbh: hhnq + wchj\nhcsl: sbtp + wrnf\nwljw: wrmd / ffct\nfctr: 2\nwnmz: 17\nmhfl: 3\ncrfw: sdvt * gvrz\nvqdv: 3\nzswr: 4\ntbgc: hqzm * qtsc\nbcmz: jqbf + vchc\nfltj: jlgw / prsv\npnbd: 2\nvqcc: 3\npdhb: 11\nmssc: hjbb * zzsf\nfbcp: pfhh + fhbm\nqjlj: 2\nbwmp: gwqd + zttp\nqqnm: fftd * mbst\nrmwh: tcnh - pcmh\nssrc: 2\ntlhm: tjfv + zpsf\nrnbd: jjvt + hmzp\ngbwn: cvlv + djwh\npfpd: 4\nnfvs: cpmc + vzhf\nssts: 3\nhvbh: 3\nfnwt: shzp * thgj\nbwjj: wfnf * dtqb\ndvll: 1\nrjtf: 3\ngtrh: lcqd + prrn\npbqm: 1\nnlrm: 5\ndftz: mzng * tncp\nrlsl: ppmh / pvnb\nhhgf: dwnr * qbrj\nlddg: tbzq * ncwd\npclv: qqnt - gcqz\nblhb: rnzq + mhqz\ndrnr: zlhg + mvcq\nhgwl: jqtl + wzsr\nzswf: blqr * lvsb\nfdbt: pwfs * gnhq\nfwlm: 1\nwpzv: 3\ncdwp: gfhs + wtbp\nhzch: fdbd + nrth\npdsl: 3\nphql: hbmw * wrlt\nztvt: 1\nfgfp: 13\nwfjt: 3\nwrmd: fhrp * jrdr\ncldc: fmgr + cdjg\nvfvb: zlgm - stzg\nqfrh: hbhc * gnhc\njrdr: 2\nfcdv: 3\nhjjp: cvmd * qnjb\nftmr: qtbj + gnfr\ngqfw: 3\nzgzh: phsj + jzrn\ncqvn: 7\nbbhr: jdbt * ccrh\nvrvs: 5\nrlvz: pwvl * lczp\nsmhn: 2\nrzhg: 6\nqbmc: 3\nwtvv: 4\nnqnb: 4\nzshh: ngfn + ljqm\nrpph: hbwt * fwfh\nlqqw: grqf * jwfc\njwgt: lwjj * fsfh\nwqmw: 4\nnzjs: 2\ngcvc: 2\npwvl: 16\ngwqd: 10\nprrn: 4\nbtrp: 5\nmpjh: 2\nfbcl: 2\nmwbr: 2\nlcgw: zpmm + lwfw\ndlsw: 1\nvwtr: rgsj / vfcg\nvhjq: wrvz * dmzh\nmdvc: 5\nsldj: 5\nfwpv: 11\npvqb: qwdt + srzd\nptqg: 12\nchzc: 2\nvfsz: 3\nhjlt: mrgj * ffdp\nmvtd: 5\njldc: dvvw * zbwz\nbsft: 2\nsvsd: 9\nqcbl: fztd * cpld\nhjzq: 3\nctmh: 2\ncnss: 2\nzqrj: mhhq * fjfc\njsgj: 5\nqrmb: 7\nnszq: rdhf * zstr\nmgsm: 5\nzmhz: cglq * cttz\nmsjt: 3\nczrh: cvbr / djtb\nlslt: grfq / hsgj\nnfcm: 3\nncsj: 14\nvgjt: 3\nldzh: 4\nlzdj: 8\nglrq: 5\ncjjr: 11\ndnwc: 8\npldf: vcdj * chzc\nrfwr: rqcp * qpwg\nzblf: 2\nswbp: wggc + qcnf\nhcjq: jfft * hhll\nfjlz: vjdq + dzsp\nzswq: wbmt + scrh\ntzrc: fflf + mpbq\nzsjl: jmdd * mpwj\ntmwj: 4\njfvd: 3\njqzf: 2\nhtzv: tlps + sjjp\ngmwm: 7\nqbrj: 2\ncmdr: lswp * lljh\nrtpp: 1\nqrdg: slst + bbrq\nhqzm: 2\nvdsw: 3\nhzhv: 6\nhumn: 927\ndzsp: 5\nlpsb: 5\njqcq: 5\nmvcq: 12\ncfhv: 2\nqrrf: vqvn - wprq\nmznq: sfjb * hvtd\nbzfw: 4\nnctp: 4\nbzjg: hcnm + jtbm\ngppp: fnfn * qqnm\nghzf: szlh * bgcc\nrfls: gjnf / hffp\nnfjz: 4\npqzg: 4\nfrhd: twtc * rrmn\nmvds: 1\nhqlh: pwvn * qtvf\nwfgr: twsv * tntz\nmfsl: dlsw + hlmh\nlzlf: szvt + qwcz\ncgwz: 14\nwvjb: 4\nhsnr: 4\ndhdl: hmcr * lscn\nqmwp: cbdg * mplg\njfft: qjfq + vzpv\ntttw: 6\nqcsp: 12\ncmtc: qtrv * fcfl\nzttp: jnbr * sldj\ncnrm: 3\nmqtj: nhhv * bsdz\ntwmm: mhbm * ltwj\nvphb: fcdv * wgpg\nrcpt: 2\nsglw: wplj + ffmd\ngwqw: pntz - dwzg\nbwdq: 3\ngjdr: mpqg + qsvs\nmgtw: ddgp + cqlr\ncgzf: 4\nvmpw: btrp + wlhb\ncvbn: 4\njcsn: lntg * tmqv\npgdh: frmz + sqth\nfqbc: lgzs + zttz\nllpw: 8\nhbnz: 12\nzdll: 19\npbnr: 5\npzcv: 1\nwlwl: 2\nljcq: 6\nvwgp: 8\nthlf: 2\nmzqq: pgdh + rmch\ndhrn: 5\njbrv: mttw * rjhz\npbgz: 2\ntmnw: dfdq - ljmt\nssqj: 6\nsplf: nlzg / jvrb\npflc: 2\nssmt: rlwg + rppv\ngpwh: 3\nnncw: 11\nggzr: sqvs * ctcq\nvjcm: 2\nzdlm: nsrp - nptq\npwfb: 3\nglpb: 5\nccrm: ztzh * mjjv\ntpnw: smdm + zblf\nmnmm: 2\nprnd: mwvp / lddf\nchfq: sbzg * qqcw\ngtcw: drhz + hmqm\nlpwm: 4\nlnpt: lpcg - gvrg\nbmsr: cqrt + mqst\nhbsb: lztz * tmll\nvcrf: 4\nsjwd: 3\nmjdq: fcvf * ghzf\ndpng: qjvl * htzv\nlvsb: 4\nmsmz: zbvr * ndpr\ngzgd: jtvv + djmv\nftsd: 2\ntjfh: 2\njggn: cqsq * szrw\nvjzc: 5\ncvqj: fwlm + qpdm\nngzd: jdvr + hzld\ngdzl: 3\nsvvl: hcsl + tqvn\nldqv: ncqc * pvcl\nfgqr: nwsb - glnr\nrzmw: 4\nrzlb: 5\nmvtf: 7\ntsbg: tshn * lspr\nglmh: 4\nmwjj: lfgq + wqqz\nrmnq: vmpw + vwtr\nlfsd: 3\nwdnd: 2\njfps: 2\nwzmg: jznb + ntth\nlmnv: wmwb * hlgs\nzghz: scnm + jgpj\nwgjp: slnt + wccg\ncmnb: 2\ngjnf: jzzv * cfrs\nlfwr: cwht + bmsr\nqqcw: 2\nhmzn: gwjs * tqfv\nvvjt: ftmz + bzmt\nvdvv: 2\nwnmv: 4\nvgnz: 3\nfmgr: 4\nsqvc: dzzd + jrhp\njsgr: znft * lhcl\nlfcf: 5\ndhhr: rmwf + ffjt\nrcbh: tvdm + wccm\nlntg: cqpv / gghf\nvqqr: dgct + vnjw\ntjsp: 2\npnjw: 18\npvfm: 2\ntzsj: 2\nrcnm: 2\nzt" <> ...}
+
```
+
+
```elixir
+
data =
+
puzzle_input
+
|> String.split("\n", trim: true)
+
|> Map.new(fn <<name::4-binary>> <> ": " <> rest ->
+
Regex.named_captures(~r"(?<num>\d+)|(?<a>.{4}) (?<op>[-+*/]) (?<b>.{4})", rest)
+
|> case do
+
%{"num" => "", "op" => op, "a" => a, "b" => b} -> {op, a, b}
+
%{"num" => num} -> String.to_integer(num)
+
end
+
|> then(&{name, &1})
+
end)
+
+
map_size(data)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
2773
+
```
+
+
```elixir
+
defmodule Evaluator do
+
def eval(key, map) do
+
case Map.fetch!(map, key) do
+
{op, a, b} ->
+
va = eval(a, map)
+
vb = eval(b, map)
+
+
do_math(op, va, vb)
+
+
num ->
+
num
+
end
+
end
+
+
defp do_math(op, a, b) when not is_integer(a) or not is_integer(b), do: {op, a, b}
+
defp do_math("+", a, b), do: a + b
+
defp do_math("-", a, b), do: a - b
+
defp do_math("*", a, b), do: a * b
+
defp do_math("/", a, b), do: div(a, b)
+
end
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:module, Evaluator, <<70, 79, 82, 49, 0, 0, 9, ...>>, {:do_math, 3}}
+
```
+
+
## Task 1
+
+
```elixir
+
Evaluator.eval("root", data)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
110181395003396
+
```
+
+
## Task 2
+
+
```elixir
+
{_, a, b} = data["root"]
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{"+", "tlpd", "jjmw"}
+
```
+
+
```elixir
+
vb = Evaluator.eval(b, %{data | "humn" => nil})
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
22931068684876
+
```
+
+
So we see that `b` is independent from `humn`.
+
+
```elixir
+
defmodule Solver do
+
def unravel(:humn, value), do: value
+
+
def unravel({"/", a, b}, value) when is_integer(b), do: unravel(a, value * b)
+
def unravel({"+", a, b}, value) when is_integer(b), do: unravel(a, value - b)
+
def unravel({"+", a, b}, value) when is_integer(a), do: unravel(b, value - a)
+
def unravel({"-", a, b}, value) when is_integer(b), do: unravel(a, value + b)
+
def unravel({"-", a, b}, value) when is_integer(a), do: unravel(b, a - value)
+
def unravel({"*", a, b}, value) when is_integer(b), do: unravel(a, div(value, b))
+
def unravel({"*", a, b}, value) when is_integer(a), do: unravel(b, div(value, a))
+
end
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:module, Solver, <<70, 79, 82, 49, 0, 0, 8, ...>>, {:unravel, 2}}
+
```
+
+
```elixir
+
va = Evaluator.eval(a, %{data | "humn" => :humn})
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{"/",
+
{"+",
+
{"*",
+
{"-", 87250326333032,
+
{"*",
+
{"-",
+
{"/",
+
{"+", 892,
+
{"*", 3,
+
{"+", 203,
+
{"/",
+
{"-",
+
{"/",
+
{"+", 660,
+
{"*", 2, {"-", {"*", 3, {"+", {"/", {"-", {"/", {"+", ...}, 2}, 85}, 5}, 124}}, 126}}},
+
2}, 183}, 3}}}}, 5}, 444}, 6}}, 2}, 808}, 2}
+
```
+
+
```elixir
+
Solver.unravel(va, vb)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
3721298272959
+
```
+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
+
+
```
+102
2023/day01.livemd
···
+
<!-- livebook:{"persist_outputs":true} -->
+
+
# Day 01
+
+
```elixir
+
Mix.install([
+
{:kino_aoc, ">= 0.0.0"}
+
])
+
```
+
+
## Section
+
+
<!-- livebook:{"attrs":{"assign_to":"puzzle_input","day":"1","session_secret":"ADVENT_OF_CODE_SESSION","year":"2023"},"chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2023", "1", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:ok,
+
"two934seven1\n8825eightknfv\nsevenoneqbfzntsix55\nfoursqpqvv192rdrbtcccfourone\n9jpzhpxqthreelmrnlhfqmn4\nonedpsckg3xdhmgtsixthreefivejlncszkxeight\n4twofour\n7eighttwo17fournsmrznntgjrdpkdjvx\n573\nninethree3\n3gngzkpkgrf\nqeightwo2xjvfkfiveone\ntwoonej26\nsgoneightfoureight5sevenjzsqghg\nbnrb36xtjd7four9\nthreepprhsff3prbpfivesevenseven4\n38sevennineninemnfzklttkxnine3\n8mllzkfqklhonefivemv4\nonedcqlqcrzn66three\n1fourjthreefc2gbtbdzsix\neight7two4258\n4hmfzdzf\n26dsmdzznm7\nplckvxznnineh34eight2\ndhrvd4eightgxznhqmh\n5fxhhkghvm3nineshpcxhtwo6fourhrktpbq\nqklhmhmdlgeighttwoonetwo52five\n86threemmpchhzdvsvxfzrj\n9clvchpgrslnkhdmfkjmlrvgnf\n8ncpdtspfivethree\ngtbtkqcgvh8945\nsevencrkbt3btljpdpgstlf\n8nine37bpkmtghhnc2hnreightwohvs\n5qxmsrthreempcmpdcnnv41\n8threezrxhxgx4g\njhsb3onep1\neight71rnz\n7p16lrxktlr6\n8one5fivelvdbjzz\n1nine2twodhnineonesixkqfcbgdlfg\nfour8sixfourfive\npjdmt4one8sdsdhhqxlqgzpk6qrtdvxm\nsixzfourkdpmnn92qbjkjqfqpn\n42threefiveh\n5fhgzt8threemzhblb6\nbbc3kxhvbfrn8four6five\n91fknhthreefour\nsix9fttmqpninethreevhgtrxklbvxbljsp1\nfour5five1471mtfv\n3bjkggcntwo3ptmjhmthree7\nfour2eightone\nthreedrzktlgbz4five\ndmpgttqfivekcdjbf49six\n9bplkkgrxgjqjqb3seven\n4861sx4six\nhjzmxtxvxkkpbvgpvmgb4two8bqxlvponesq\nlkxxtkctlphjfivepjlrg1\nxszdbbvxjrfxs2vrmmbfourpzcfmgppk33eightwors\n966fourflbfsk3\n1bskshtjseven5qlbjhqgzhbzxvlxsvtcmmzseven\n56two28cbhfsdcjsix2four\n6s5qcmvjltqeightslhnzmvbfvcmxj\ntwosevenjxk6lhrkknnkq\nkjkj2lkkldqbgzhglmthree9\nftxhnpms1onetwoxg2\nthree9sixsevenmrgggztckzgzv7\nstvgmjgnine2vvsnjhlzkstwo5szsbvzjdzb\nv6\nthreetwolscvhrlmm3r\ntwo17kblkphfninefour6six1\none6fiveeight9sixjzljjfknrhkzxr\ndgpqm43xthreekxgspjzrzcsix\n2two8fourpppb2\nfiveseven5four\n5rttwofivefnmbkn8nine2eight\n43threeninelgnpzrdtbc1lbkjkvqrdcd\n1seventx\nnctwonefourjzgskmxjmq2\nrpzpht2tdxczzfthreeseven\ntwo1seven\n6bjztkxhsixkgnkroneightht\n9mqzkgmv4vxqrpf4\n49hlj\n46gv\n75sixfddn75\neight87xzjkdpnnjjfqeight\n9pfcdhxbcrnpsnmvkqnsqsninedgtlmmc5\nxmfbn34\n99lvrrndpqcnhznn\nqsmxhxfph24three\nlql25\n8five1dhrkm\ntwoninefourcxksqfmn1\n7eightdclrvn\none2seveneight3ninemcpnmonetwo\n33fivefivenftbczsdstlxzbp\n9r97five\n5fivessskxvnt6qqbkkqrggxg9gsdtbptpn\nthreesjdpjdkczjgthree6\ntwojqm86\nbttrx15qfznmdncnz5\nppckphrtzhstd3xvthzrxxlrrjtk\nqkm6ckeight7gnmqkltz6jsrgjhbck\nzdjjjlpmjtphbjpm9threeskqrphxbfqqeightone\nkonesix1three\nfour24391rzxtffour\nhsevenfive36fqrbjpfj7\ndxdcssixbcnp8two639\nhnvg2\nsixeighthmqkjjsix6tbvdhzone2vsn\ndfzlxq7pjmq5\n5n3\ntwovjcgxdsdngt2smfxfqxeight\nftpjlnvg5qshclfzqtc2eightninefivecsrgk\nzzgsjsjffpvcgfmjtnpkrsqlmpzlt9four\n4btrhpznzr8oneightg\npph2one\n5seveneighteight\n31sfrfrcgmseven\nfour7bdqgrhfive3\nnbrzbggpseven9prthjvknq\n3sixonefourh\nfourgkrpkzdmhtwoseven6txplz\nfour84ldbhnkxjph\n6eightonesrb\ngnmckftk62jgsjxzpk\nbzctx9onetmcnzhxkrtchjgqxv66\n1three5\n27two\n34eightwox\n6ndgrbmfkfive2ksxfbnjbl7fkrm\nkxpz4gjmgcgzzq63five\nnfvmfrbc151one8nggsdqvm\n4clnctseven5nsn5\nhcrpbvqmmdbstlxccthkththreebm6\ngdnmh6cslzhjhdl8nine\nsevenninethreefive4bgknpbnine\n2sevent6three1\n2jbrmdxgpnine7\nnshlgtbkmcmgkmqone3\ndklhc9sevenrxxzzxltsnlltqcjrbgprnx\ngmrjhlvzppmklnl39\nkv86eight3dcdpp6pmdzcvsix\nfiveseven2sevensix6952\n3xrtthnsevenjxsxpzvc\n256nmzrlzbczv\n4dp7onesixvpcf\n25onesevenonexvnst4smvlfszcrv\nlcxncproneseven37five\nninezjsrptfivenhsqxrdz7one\ncscdmnfrcxfqdtkmhkldgjlxdjqsxslhdzvvt4\nsixfnjnfkqm67blkmnqtwo\nfivethree7\n2five5ninegcmqbkpp61npkpml9\n3qktrxninefour\nqdhmxstwo44two\n21nine\nrbnineone3xppvtbmv3sevenvxkkgmgklg\nmcvzplmpvptwo38\nsv176threeone\n5vksixqsccgdkrrfourcgnpsfxbvj\nxxtwone6eight\nthreeonespkbnsj9onesevenpz5\nfivenncrfvhfdsevengxzkxbkrklgsfvllrkbx4\n69kp1seven8dqkrx\ndmb9ccghdjjpjxfivehtwo4\n6nhgdkpdone\ntfvqdqdqcszxbrdmmrninesct2\n8sevenfour2eight8rskc\ncpmgffcvln9sjdsgfivesix5rppfsfmmqtffive\n5two7\n7threecrkljthreetwo\n6qgqzsdhprd\n959zgjscgtm\nfourtwoppfrdqgtseven9\n8bbchvoneeightr\ngtddrb1rznsdjtonethree5four\n8rrskfzlmlbrsninezdzpt3\n6njhmkpp4onefive8two\n4cqpnkcxjtwoqzqmjnqccfs256hcnqpfm\nnineeightseven62sixhlxlps\ndtqplzzf87threecthree\nmqptgzjxddxgxpjr5\n9194jbjjktwofive\nfive514foursevendzxlh2\n6nineeight85zvx\nfour8gsgrstfmdv99hpkfgptzqkhsmgsnlggrseven\n9three298\n3fpttzk35\nrbtckzonexkqmfxrnsbsrkqbq66sixkcqfzjfour\nsixkdcrrrppcsix399fccnsbhfxvfiveft\nxfjxbfvmb" <> ...}
+
```
+
+
## Part 1
+
+
```elixir
+
puzzle_input
+
|> String.split()
+
|> Enum.map(fn line ->
+
for <<c <- line>>, c in ?0..?9, do: c - ?0
+
end)
+
|> Enum.map(fn nums -> List.first(nums) * 10 + List.last(nums) end)
+
|> Enum.sum()
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
52974
+
```
+
+
## Part 2
+
+
The tricky part there is that words can overlap, and we need to take that up to the account. It took me way too much time to understand that.
+
+
```elixir
+
defmodule Part2 do
+
def parse(""), do: []
+
def parse(<<c>> <> rest) when c in ?1..?9, do: [c - ?0 | parse(rest)]
+
+
words = ~w[one two three four five six seven eight nine]
+
+
for {word, idx} <- Enum.with_index(words, 1) do
+
def parse(unquote(word) <> _ = str) do
+
<<_>> <> rest = str
+
[unquote(idx) | parse(rest)]
+
end
+
end
+
+
def parse(<<_>> <> rest), do: parse(rest)
+
end
+
+
puzzle_input
+
|> String.split()
+
|> Enum.map(&Part2.parse/1)
+
|> Enum.map(fn nums -> List.first(nums) * 10 + List.last(nums) end)
+
|> Enum.sum()
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
53340
+
```
+
+
```elixir
+
words = ~w[one two three four five six seven eight nine]
+
pattern = Enum.concat(1..9, words) |> Enum.join("|")
+
+
to_num = fn n ->
+
if v = Enum.find_index(words, &(&1 == n)), do: v + 1, else: String.to_integer(n)
+
end
+
+
puzzle_input
+
|> String.split()
+
|> Enum.map(&Regex.scan(~r/^.*?(#{pattern}).*(#{pattern}).*?$/, &1))
+
|> dbg()
+
|> Enum.map(fn
+
[[_, a, b]] ->
+
to_num.(a) * 10 + to_num.(b)
+
+
[[_, a]] ->
+
a = to_num.(a)
+
a * 10 + a
+
end)
+
|> Enum.sum()
+
```
+
+
<!-- livebook:{"offset":6289,"stamp":{"token":"XCP.8wDt6KmmXvHba68hXcGnXNOf4ySnrVXFg3xBlBhffIp7QdMVOlpx87HS35zyFWnNl8D6ubMeKZ0nbHD6o1BhtUMF4AvpCD9FtMxlHIqrB6hrbn7N6ZkPZqriythIFxCvpA","version":2}} -->
+435
2023/day02.livemd
···
+
<!-- livebook:{"persist_outputs":true} -->
+
+
# Day 02
+
+
```elixir
+
Mix.install([:kino_aoc])
+
```
+
+
## Section
+
+
<!-- livebook:{"attrs":{"assign_to":"puzzle_input","day":"2","session_secret":"ADVENT_OF_CODE_SESSION","year":"2023"},"chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2023", "2", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:ok,
+
"Game 1: 3 blue, 7 green, 10 red; 4 green, 4 red; 1 green, 7 blue, 5 red; 8 blue, 10 red; 7 blue, 19 red, 1 green\nGame 2: 6 red, 10 green; 11 green, 4 red; 16 green, 2 blue; 7 green, 5 blue, 4 red; 17 green, 1 red, 1 blue\nGame 3: 5 red, 9 blue, 1 green; 5 red; 11 red, 2 green, 8 blue; 2 green, 6 blue\nGame 4: 2 red, 5 green; 2 blue, 3 red, 3 green; 3 red, 2 blue; 8 green, 2 red\nGame 5: 12 red, 13 blue; 13 blue, 2 green, 9 red; 9 blue, 1 red; 2 green, 12 blue; 1 green, 1 red, 11 blue\nGame 6: 4 blue, 11 red; 4 red; 1 green, 7 red; 1 green, 1 blue; 8 blue, 10 red; 1 green, 2 blue, 8 red\nGame 7: 7 blue, 15 red, 1 green; 5 green, 17 red, 7 blue; 5 blue, 1 green; 11 blue, 2 green, 17 red; 14 green, 9 red, 2 blue; 6 blue, 19 red\nGame 8: 13 green; 5 green; 3 blue, 9 green, 1 red; 4 red, 11 green, 4 blue\nGame 9: 4 green, 1 red, 1 blue; 4 green, 7 blue, 7 red; 9 blue, 4 red; 2 blue, 8 red, 5 green; 6 blue, 2 green; 5 red, 5 green, 10 blue\nGame 10: 1 green, 5 blue, 3 red; 4 green, 9 red, 3 blue; 11 red, 2 green, 5 blue; 3 green, 1 blue, 2 red; 6 red, 2 blue\nGame 11: 2 red, 6 green, 12 blue; 2 red, 9 blue, 1 green; 12 green, 3 blue\nGame 12: 1 red, 1 blue, 12 green; 6 green, 2 red, 1 blue; 6 red, 6 green, 1 blue; 3 green, 6 red\nGame 13: 5 red, 19 green, 3 blue; 6 red, 7 blue, 11 green; 8 blue, 6 red; 3 blue, 4 green, 4 red; 8 red, 15 green, 5 blue; 5 blue, 2 red, 10 green\nGame 14: 5 blue, 9 green; 4 green, 6 blue; 14 green, 1 red, 4 blue; 3 blue, 3 green; 2 green; 5 blue, 7 green, 1 red\nGame 15: 5 red, 8 blue; 9 blue, 3 red; 5 red, 1 green, 16 blue; 1 blue, 3 red, 2 green; 5 red, 2 green, 10 blue\nGame 16: 6 blue, 9 green, 10 red; 8 blue, 9 red, 14 green; 7 green, 1 blue, 1 red; 8 red, 5 green, 8 blue; 10 red, 5 blue, 14 green; 7 blue, 11 red, 3 green\nGame 17: 12 blue, 12 red, 6 green; 14 green, 17 blue, 4 red; 11 blue, 1 red, 13 green\nGame 18: 7 blue, 2 green, 4 red; 1 blue, 2 green, 4 red; 2 red, 17 blue\nGame 19: 3 red, 9 green; 8 red, 2 blue, 2 green; 3 blue, 15 green, 11 red; 18 green, 3 red, 1 blue\nGame 20: 5 green, 5 red, 16 blue; 8 blue, 6 green, 4 red; 10 red, 11 blue; 5 red, 5 blue, 5 green\nGame 21: 1 red, 3 blue, 14 green; 6 red, 6 blue, 17 green; 12 green, 17 blue, 3 red; 15 green, 1 red, 19 blue; 3 red, 18 blue, 4 green\nGame 22: 15 blue; 11 blue, 2 red, 1 green; 1 green, 7 red; 1 red, 18 blue, 1 green; 16 blue; 3 red, 6 blue\nGame 23: 11 blue, 6 green, 4 red; 9 green, 11 red, 8 blue; 5 green, 5 red, 2 blue; 11 green, 4 blue, 11 red; 3 green, 9 blue, 2 red\nGame 24: 7 green, 2 red; 8 red, 1 blue, 15 green; 3 red, 6 green, 6 blue\nGame 25: 9 blue, 9 green; 3 green, 7 blue, 1 red; 6 green, 1 red, 1 blue; 6 green, 1 red, 1 blue\nGame 26: 1 green, 15 blue, 1 red; 1 red, 12 blue, 1 green; 16 blue; 5 red, 11 green, 14 blue; 6 green, 4 red, 14 blue\nGame 27: 14 red, 9 green; 11 red, 5 green, 6 blue; 1 red, 6 blue, 9 green\nGame 28: 6 green, 1 blue, 9 red; 1 green, 9 red; 7 red; 11 red, 1 blue, 2 green; 8 red, 10 green; 6 green, 1 blue, 5 red\nGame 29: 1 red, 19 blue, 3 green; 9 blue, 1 red; 8 green, 17 blue; 11 blue, 4 green\nGame 30: 7 blue; 5 blue, 1 red, 1 green; 3 blue, 1 red\nGame 31: 9 red, 2 green, 1 blue; 5 red, 1 green, 3 blue; 2 green, 7 red; 2 green, 12 red\nGame 32: 1 red, 1 blue, 17 green; 14 blue, 10 green, 6 red; 12 green, 11 blue, 3 red\nGame 33: 2 red, 1 green, 3 blue; 7 blue, 4 green; 1 red, 3 green, 5 blue\nGame 34: 9 blue, 1 green, 9 red; 12 blue, 2 green, 12 red; 3 blue, 12 red; 2 green, 14 blue, 11 red; 10 red, 12 blue\nGame 35: 6 blue, 2 red; 5 blue; 6 green, 9 blue, 3 red; 3 green, 1 red, 2 blue\nGame 36: 9 blue, 4 green, 6 red; 2 red, 4 green; 7 red, 3 green; 6 green, 2 blue; 3 red, 4 blue, 3 green; 3 green, 4 red, 16 blue\nGame 37: 2 green, 8 red, 4 blue; 3 red, 4 blue, 2 green; 5 blue, 3 green; 9 blue, 15 green; 5 red, 11 green, 7 blue\nGame 38: 12 red, 1 blue; 10 red, 3 green, 2 blue; 7 blue, 3 green, 8 red; 14 red, 2 green\nGame 39: 16 green, 2 red, 17 blue; 6 red, 4 green, 13 blue; 7 blue, 1 green, 4 red; 2 green, 3 blue; 12 green, 6 red, 17 blue; 5 red, 2 blue, 6 green\nGame 40: 3 green, 4 blue, 2 red; 2 green, 3 red; 6" <> ...}
+
```
+
+
```elixir
+
games =
+
puzzle_input
+
|> String.split("\n", trim: true)
+
|> Enum.map(fn "Game " <> game ->
+
{id, ": " <> rest} = Integer.parse(game)
+
+
picks =
+
for pick <- String.split(rest, "; ") do
+
pick
+
|> String.split(", ")
+
|> Map.new(fn balls ->
+
{num, " " <> color} = Integer.parse(balls)
+
{color, num}
+
end)
+
end
+
+
{id, picks}
+
end)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
[
+
{1,
+
[
+
%{"blue" => 3, "green" => 7, "red" => 10},
+
%{"green" => 4, "red" => 4},
+
%{"blue" => 7, "green" => 1, "red" => 5},
+
%{"blue" => 8, "red" => 10},
+
%{"blue" => 7, "green" => 1, "red" => 19}
+
]},
+
{2,
+
[
+
%{"green" => 10, "red" => 6},
+
%{"green" => 11, "red" => 4},
+
%{"blue" => 2, "green" => 16},
+
%{"blue" => 5, "green" => 7, "red" => 4},
+
%{"blue" => 1, "green" => 17, "red" => 1}
+
]},
+
{3,
+
[
+
%{"blue" => 9, "green" => 1, "red" => 5},
+
%{"red" => 5},
+
%{"blue" => 8, "green" => 2, "red" => 11},
+
%{"blue" => 6, "green" => 2}
+
]},
+
{4,
+
[
+
%{"green" => 5, "red" => 2},
+
%{"blue" => 2, "green" => 3, "red" => 3},
+
%{"blue" => 2, "red" => 3},
+
%{"green" => 8, "red" => 2}
+
]},
+
{5,
+
[
+
%{"blue" => 13, "red" => 12},
+
%{"blue" => 13, "green" => 2, "red" => 9},
+
%{"blue" => 9, "red" => 1},
+
%{"blue" => 12, "green" => 2},
+
%{"blue" => 11, "green" => 1, "red" => 1}
+
]},
+
{6,
+
[
+
%{"blue" => 4, "red" => 11},
+
%{"red" => 4},
+
%{"green" => 1, "red" => 7},
+
%{"blue" => 1, "green" => 1},
+
%{"blue" => 8, "red" => 10},
+
%{"blue" => 2, "green" => 1, "red" => 8}
+
]},
+
{7,
+
[
+
%{"blue" => 7, "green" => 1, "red" => 15},
+
%{"blue" => 7, "green" => 5, "red" => 17},
+
%{"blue" => 5, "green" => 1},
+
%{"blue" => 11, "green" => 2, "red" => 17},
+
%{"blue" => 2, "green" => 14, "red" => 9},
+
%{"blue" => 6, "red" => 19}
+
]},
+
{8,
+
[
+
%{"green" => 13},
+
%{"green" => 5},
+
%{"blue" => 3, "green" => 9, "red" => 1},
+
%{"blue" => 4, "green" => 11, "red" => 4}
+
]},
+
{9,
+
[
+
%{"blue" => 1, "green" => 4, "red" => 1},
+
%{"blue" => 7, "green" => 4, "red" => 7},
+
%{"blue" => 9, "red" => 4},
+
%{"blue" => 2, "green" => 5, "red" => 8},
+
%{"blue" => 6, "green" => 2},
+
%{"blue" => 10, "green" => 5, "red" => 5}
+
]},
+
{10,
+
[
+
%{"blue" => 5, "green" => 1, "red" => 3},
+
%{"blue" => 3, "green" => 4, "red" => 9},
+
%{"blue" => 5, "green" => 2, "red" => 11},
+
%{"blue" => 1, "green" => 3, "red" => 2},
+
%{"blue" => 2, "red" => 6}
+
]},
+
{11,
+
[
+
%{"blue" => 12, "green" => 6, "red" => 2},
+
%{"blue" => 9, "green" => 1, "red" => 2},
+
%{"blue" => 3, "green" => 12}
+
]},
+
{12,
+
[
+
%{"blue" => 1, "green" => 12, "red" => 1},
+
%{"blue" => 1, "green" => 6, "red" => 2},
+
%{"blue" => 1, "green" => 6, "red" => 6},
+
%{"green" => 3, "red" => 6}
+
]},
+
{13,
+
[
+
%{"blue" => 3, "green" => 19, "red" => 5},
+
%{"blue" => 7, "green" => 11, "red" => 6},
+
%{"blue" => 8, "red" => 6},
+
%{"blue" => 3, "green" => 4, "red" => 4},
+
%{"blue" => 5, "green" => 15, "red" => 8},
+
%{"blue" => 5, "green" => 10, "red" => 2}
+
]},
+
{14,
+
[
+
%{"blue" => 5, "green" => 9},
+
%{"blue" => 6, "green" => 4},
+
%{"blue" => 4, "green" => 14, "red" => 1},
+
%{"blue" => 3, "green" => 3},
+
%{"green" => 2},
+
%{"blue" => 5, "green" => 7, "red" => 1}
+
]},
+
{15,
+
[
+
%{"blue" => 8, "red" => 5},
+
%{"blue" => 9, "red" => 3},
+
%{"blue" => 16, "green" => 1, "red" => 5},
+
%{"blue" => 1, "green" => 2, "red" => 3},
+
%{"blue" => 10, "green" => 2, "red" => 5}
+
]},
+
{16,
+
[
+
%{"blue" => 6, "green" => 9, "red" => 10},
+
%{"blue" => 8, "green" => 14, "red" => 9},
+
%{"blue" => 1, "green" => 7, "red" => 1},
+
%{"blue" => 8, "green" => 5, "red" => 8},
+
%{"blue" => 5, "green" => 14, "red" => 10},
+
%{"blue" => 7, "green" => 3, "red" => 11}
+
]},
+
{17,
+
[
+
%{"blue" => 12, "green" => 6, "red" => 12},
+
%{"blue" => 17, "green" => 14, "red" => 4},
+
%{"blue" => 11, "green" => 13, "red" => 1}
+
]},
+
{18,
+
[
+
%{"blue" => 7, "green" => 2, "red" => 4},
+
%{"blue" => 1, "green" => 2, "red" => 4},
+
%{"blue" => 17, "red" => 2}
+
]},
+
{19,
+
[
+
%{"green" => 9, "red" => 3},
+
%{"blue" => 2, "green" => 2, "red" => 8},
+
%{"blue" => 3, "green" => 15, "red" => 11},
+
%{"blue" => 1, "green" => 18, "red" => 3}
+
]},
+
{20,
+
[
+
%{"blue" => 16, "green" => 5, "red" => 5},
+
%{"blue" => 8, "green" => 6, "red" => 4},
+
%{"blue" => 11, "red" => 10},
+
%{"blue" => 5, "green" => 5, "red" => 5}
+
]},
+
{21,
+
[
+
%{"blue" => 3, "green" => 14, "red" => 1},
+
%{"blue" => 6, "green" => 17, "red" => 6},
+
%{"blue" => 17, "green" => 12, "red" => 3},
+
%{"blue" => 19, "green" => 15, "red" => 1},
+
%{"blue" => 18, "green" => 4, "red" => 3}
+
]},
+
{22,
+
[
+
%{"blue" => 15},
+
%{"blue" => 11, "green" => 1, "red" => 2},
+
%{"green" => 1, "red" => 7},
+
%{"blue" => 18, "green" => 1, "red" => 1},
+
%{"blue" => 16},
+
%{"blue" => 6, "red" => 3}
+
]},
+
{23,
+
[
+
%{"blue" => 11, "green" => 6, "red" => 4},
+
%{"blue" => 8, "green" => 9, "red" => 11},
+
%{"blue" => 2, "green" => 5, "red" => 5},
+
%{"blue" => 4, "green" => 11, "red" => 11},
+
%{"blue" => 9, "green" => 3, "red" => 2}
+
]},
+
{24,
+
[
+
%{"green" => 7, "red" => 2},
+
%{"blue" => 1, "green" => 15, "red" => 8},
+
%{"blue" => 6, "green" => 6, "red" => 3}
+
]},
+
{25,
+
[
+
%{"blue" => 9, "green" => 9},
+
%{"blue" => 7, "green" => 3, "red" => 1},
+
%{"blue" => 1, "green" => 6, "red" => 1},
+
%{"blue" => 1, "green" => 6, "red" => 1}
+
]},
+
{26,
+
[
+
%{"blue" => 15, "green" => 1, "red" => 1},
+
%{"blue" => 12, "green" => 1, "red" => 1},
+
%{"blue" => 16},
+
%{"blue" => 14, "green" => 11, "red" => 5},
+
%{"blue" => 14, "green" => 6, "red" => 4}
+
]},
+
{27,
+
[
+
%{"green" => 9, "red" => 14},
+
%{"blue" => 6, "green" => 5, "red" => 11},
+
%{"blue" => 6, "green" => 9, "red" => 1}
+
]},
+
{28,
+
[
+
%{"blue" => 1, "green" => 6, "red" => 9},
+
%{"green" => 1, "red" => 9},
+
%{"red" => 7},
+
%{"blue" => 1, "green" => 2, "red" => 11},
+
%{"green" => 10, "red" => 8},
+
%{"blue" => 1, "green" => 6, "red" => 5}
+
]},
+
{29,
+
[
+
%{"blue" => 19, "green" => 3, "red" => 1},
+
%{"blue" => 9, "red" => 1},
+
%{"blue" => 17, "green" => 8},
+
%{"blue" => 11, "green" => 4}
+
]},
+
{30, [%{"blue" => 7}, %{"blue" => 5, "green" => 1, "red" => 1}, %{"blue" => 3, "red" => 1}]},
+
{31,
+
[
+
%{"blue" => 1, "green" => 2, "red" => 9},
+
%{"blue" => 3, "green" => 1, "red" => 5},
+
%{"green" => 2, "red" => 7},
+
%{"green" => 2, "red" => 12}
+
]},
+
{32,
+
[
+
%{"blue" => 1, "green" => 17, "red" => 1},
+
%{"blue" => 14, "green" => 10, "red" => 6},
+
%{"blue" => 11, "green" => 12, "red" => 3}
+
]},
+
{33,
+
[
+
%{"blue" => 3, "green" => 1, "red" => 2},
+
%{"blue" => 7, "green" => 4},
+
%{"blue" => 5, "green" => 3, "red" => 1}
+
]},
+
{34,
+
[
+
%{"blue" => 9, "green" => 1, "red" => 9},
+
%{"blue" => 12, "green" => 2, "red" => 12},
+
%{"blue" => 3, "red" => 12},
+
%{"blue" => 14, "green" => 2, "red" => 11},
+
%{"blue" => 12, "red" => 10}
+
]},
+
{35,
+
[
+
%{"blue" => 6, "red" => 2},
+
%{"blue" => 5},
+
%{"blue" => 9, "green" => 6, "red" => 3},
+
%{"blue" => 2, "green" => 3, "red" => 1}
+
]},
+
{36,
+
[
+
%{"blue" => 9, "green" => 4, "red" => 6},
+
%{"green" => 4, "red" => 2},
+
%{"green" => 3, "red" => 7},
+
%{"blue" => 2, "green" => 6},
+
%{"blue" => 4, "green" => 3, "red" => 3},
+
%{"blue" => 16, "green" => 3, "red" => 4}
+
]},
+
{37,
+
[
+
%{"blue" => 4, "green" => 2, "red" => 8},
+
%{"blue" => 4, "green" => 2, "red" => 3},
+
%{"blue" => 5, "green" => 3},
+
%{"blue" => 9, "green" => 15},
+
%{"blue" => 7, "green" => 11, "red" => 5}
+
]},
+
{38,
+
[
+
%{"blue" => 1, "red" => 12},
+
%{"blue" => 2, "green" => 3, "red" => 10},
+
%{"blue" => 7, "green" => 3, "red" => 8},
+
%{"green" => 2, "red" => 14}
+
]},
+
{39,
+
[
+
%{"blue" => 17, "green" => 16, "red" => 2},
+
%{"blue" => 13, "green" => 4, "red" => 6},
+
%{"blue" => 7, "green" => 1, "red" => 4},
+
%{"blue" => 3, "green" => 2},
+
%{"blue" => 17, "green" => 12, "red" => 6},
+
%{"blue" => 2, "green" => 6, "red" => 5}
+
]},
+
{40,
+
[
+
%{"blue" => 4, "green" => 3, "red" => 2},
+
%{"green" => 2, "red" => 3},
+
%{"blue" => 6, "green" => 6, "red" => 2},
+
%{"green" => 5},
+
%{"blue" => 3, "green" => 5, "red" => 1}
+
]},
+
{41,
+
[
+
%{"green" => 13, "red" => 11},
+
%{"blue" => 1, "green" => 3, "red" => 2},
+
%{"blue" => 1, "green" => 3, "red" => 9},
+
%{"green" => 11, "red" => 12},
+
%{"green" => 1, "red" => 9},
+
%{"green" => 9, ...}
+
]},
+
{42,
+
[
+
%{"blue" => 2, "green" => 4},
+
%{"blue" => 6, "green" => 10},
+
%{"blue" => 13, "green" => 6, "red" => 3},
+
%{"blue" => 11, "green" => 17},
+
%{"blue" => 8, ...}
+
]},
+
{43,
+
[
+
%{"blue" => 2, "green" => 10, "red" => 10},
+
%{"blue" => 3, "green" => 5, "red" => 3},
+
%{"blue" => 4, "green" => 10, ...},
+
%{"green" => 5},
+
%{...}
+
]},
+
{44,
+
[
+
%{"blue" => 1, "green" => 5, "red" => 4},
+
%{"blue" => 1, "green" => 3, ...},
+
%{"blue" => 1, ...},
+
%{...},
+
...
+
]},
+
{45, [%{"blue" => 7, "green" => 4, ...}, %{"blue" => 3, ...}, %{...}, ...]},
+
{46, [%{"blue" => 5, ...}, %{...}, ...]},
+
{47, [%{...}, ...]},
+
{48, [...]},
+
{49, ...},
+
{...},
+
...
+
]
+
```
+
+
## Part 1
+
+
```elixir
+
games
+
|> Enum.filter(fn {_, picks} ->
+
Enum.all?(picks, fn map ->
+
Map.get(map, "red", 0) <= 12 and Map.get(map, "green", 0) <= 13 and
+
Map.get(map, "blue", 0) <= 14
+
end)
+
end)
+
|> Enum.map(&elem(&1, 0))
+
|> Enum.sum()
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
2162
+
```
+
+
## Part 2
+
+
```elixir
+
games
+
|> Enum.map(fn {_, picks} ->
+
picks
+
|> Enum.reduce([0, 0, 0], fn hand, [r, g, b] ->
+
[
+
max(Map.get(hand, "red", 0), r),
+
max(Map.get(hand, "green", 0), g),
+
max(Map.get(hand, "blue", 0), b)
+
]
+
end)
+
|> Enum.product()
+
end)
+
|> Enum.sum()
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
72513
+
```
+
+
<!-- livebook:{"offset":15042,"stamp":{"token":"XCP.FeGN4d2e9dnN-0MEzQ7fkG8b8Y3D1FEiGVZmcvfp_IBmCEdpr8gG7HkIpV-Id27eJzCE5vj63AzjPXXsdEgWHwh-T5OO4n9ak1Zs__R9RD4uOYpy2NSEJkYkMGlwtPNvlg","version":2}} -->
+319
2023/day03.livemd
···
+
<!-- livebook:{"persist_outputs":true} -->
+
+
# Day 03
+
+
```elixir
+
Mix.install([
+
:kino_aoc
+
])
+
```
+
+
## Section
+
+
<!-- livebook:{"attrs":{"assign_to":"puzzle_input","day":"3","session_secret":"ADVENT_OF_CODE_SESSION","year":"2023"},"chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2023", "3", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:ok,
+
".......12.......935............184.720...243........589.652..........435..........483.............6...........................904...........\n......*.....968*.....$............*........=..348...*..........986....*...................459....*........422................#......%482....\n....291............612....290..........903........699......218*.......376............890....*.838...81......*.....138.../194................\n..............156......$..*...891.&731....%..89...................523..........699....+...227......*.......225....=...........388....*......\n................*...189..591.*................*.......783.....107..-...54.287..$................533.../..............909........&.603.424...\n...229*952.....938............470.555.......746...28.....+...*.........................................279..826..788*.......................\n...................................*...............@.........867.-....102..845...542.779.....................*........182.166...511.........\n563.727.....282....237..171.......892...183.......................989....*..........*................$....709...8*974.=...%.....*.....873...\n....#..........+...*.......*..........................&......129+......491...................877....715.......................270.......#...\n.................53.....781...&295....@773.336......547................................45......*.............=800.....*359..................\n...342*468....&.....573....................*.................................%850............*..465................192.....*.......&115.....\n............988.......*...731.............789.673....*256..............677..................621...........#....716......910..297........22..\n204&....69............905...=.....641.472.......#.524............127....*..714.........*62..........622..324..&.................*...........\n..........*........................+....@.................812......*..955.....*.....257....../.................../..............545.........\n........668....91..&.........840......+..............566.....+...66.........660..............469.................525...765...........25.....\n...............$...666.979..*........952...122......%............................71......=39...../94.........................132......*.....\n......@.................../.460..#.......=.=..........146..625........214.........#.278................667..........386.......-....936......\n....643.......@..................974...464...........*.....*...........*.............%.....$...........=...=..%995...*......................\n........./...577...-....3.../186.................*.995.....678.&.......882...559...........374.......&...554.........428.......725....*.....\n.......96........678....%.....................529..............374...........*......924........=277..606..................#...#......8.257..\n...609....................397.......475...................651.......856......697.&.....&..=...................486........888................\n............-................*..................756...399....*..42................866....287.....#......515...*......................137....\n.....285..947....#..........997......=.....665..*......*..420...*.....-..268*457.............=63..758.....+..623.............+../...........\n..............458.....422.......338...827...+..462....797.....26....523..........*.880*.............................&.....934..157..........\n.......149........409....$................................................868.378......144..149............356.....872..............871.533.\n....22...*..........$........7.......149....979......................826.&.....................@........-.....*275.....................*....\n........518.773*.........10..$..........*........805..812.972......................123......*............98.........=........./609.682......\n.................5........./............349........$.....*..................786....*.......160..903...40.............209...............*....\n.......*.....................................497...........#.............../.....153.795............./.........&806..........839....419.337.\n78...58" <> ...}
+
```
+
+
```elixir
+
IO.puts(puzzle_input)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
.......12.......935............184.720...243........589.652..........435..........483.............6...........................904...........
+
......*.....968*.....$............*........=..348...*..........986....*...................459....*........422................#......%482....
+
....291............612....290..........903........699......218*.......376............890....*.838...81......*.....138.../194................
+
..............156......$..*...891.&731....%..89...................523..........699....+...227......*.......225....=...........388....*......
+
................*...189..591.*................*.......783.....107..-...54.287..$................533.../..............909........&.603.424...
+
...229*952.....938............470.555.......746...28.....+...*.........................................279..826..788*.......................
+
...................................*...............@.........867.-....102..845...542.779.....................*........182.166...511.........
+
563.727.....282....237..171.......892...183.......................989....*..........*................$....709...8*974.=...%.....*.....873...
+
....#..........+...*.......*..........................&......129+......491...................877....715.......................270.......#...
+
.................53.....781...&295....@773.336......547................................45......*.............=800.....*359..................
+
...342*468....&.....573....................*.................................%850............*..465................192.....*.......&115.....
+
............988.......*...731.............789.673....*256..............677..................621...........#....716......910..297........22..
+
204&....69............905...=.....641.472.......#.524............127....*..714.........*62..........622..324..&.................*...........
+
..........*........................+....@.................812......*..955.....*.....257....../.................../..............545.........
+
........668....91..&.........840......+..............566.....+...66.........660..............469.................525...765...........25.....
+
...............$...666.979..*........952...122......%............................71......=39...../94.........................132......*.....
+
......@.................../.460..#.......=.=..........146..625........214.........#.278................667..........386.......-....936......
+
....643.......@..................974...464...........*.....*...........*.............%.....$...........=...=..%995...*......................
+
........./...577...-....3.../186.................*.995.....678.&.......882...559...........374.......&...554.........428.......725....*.....
+
.......96........678....%.....................529..............374...........*......924........=277..606..................#...#......8.257..
+
...609....................397.......475...................651.......856......697.&.....&..=...................486........888................
+
............-................*..................756...399....*..42................866....287.....#......515...*......................137....
+
.....285..947....#..........997......=.....665..*......*..420...*.....-..268*457.............=63..758.....+..623.............+../...........
+
..............458.....422.......338...827...+..462....797.....26....523..........*.880*.............................&.....934..157..........
+
.......149........409....$................................................868.378......144..149............356.....872..............871.533.
+
....22...*..........$........7.......149....979......................826.&.....................@........-.....*275.....................*....
+
........518.773*.........10..$..........*........805..812.972......................123......*............98.........=........./609.682......
+
.................5........./............349........$.....*..................786....*.......160..903...40.............209...............*....
+
.......*.....................................497...........#.............../.....153.795............./.........&806..........839....419.337.
+
78...582............675................145.........405....77..361............952.......*..../741....................624..527*...............
+
...................../../....=.....+....&.............*51.....*..........733*.........728.........173....834.....76.........................
+
................878....276..792.....372....................385..179.............@610.............................%........146=..............
+
..........522.....*...........................-....30....-........*.@................110=..+.......197.....643.................762......%...
+
......%....*...173.............420..407......261.........687.806.12..104.....914..........685.233.&.......*.....549...=...........*......591
+
.....837..135.......313...579....%.=.....613................../..........729.........257#.....&.........430.399*.....157.........970........
+
...................*.....*.....*......@.....*............../....566........+.....................*906....................%..................
+
....459.78$.775.768..62...345.537......122.803.142*758...148...*....992................711....316.........#...............521.298*590..289..
+
....*.................#.........................................444............382.....*...@...............753.......927................/...
+
.....592..735......+.............634.......652.....853....690................./.......874.846.35.....884.........182.-......................
+
.419........*.839.157.......795...................*.......*...........928........................756....*64......*.....*19.....309..........
+
.........716...*.......591....*....358$.#378.............623...............687.........-816......*............292...110....&....*......643..
+
..134...........910......*.941.......................................547=....*....................490....938+..............422.482..........
+
...*..331....$..........80.................#346....180...........737.........76.......992@...91......................../....................
+
...16....$.140.464*831.....933.917....303............*......%.....*....336........339.......*.............@..939....583....*564.........864.
+
..............................*........=...+54.....449......209.912.....+.....615..%.....605............960..*..........219.................
+
.........@442.....730..................................413...........................26.....................944..336........188......./.....
+
...190............#...@...524.544....968*.............*........466...222...536...843.@..........=.....32...........$..........-.......410...
+
......*..80@..491....232..-......*.......16........402......27..*...*.....*...................480....*........&........894..................
+
.....218.........*.............=..819......................*........857...896...........677........689........638...45*.....993.............
+
................754...........434.........622.338...........607....................&......&.%213...........................-................
+
........+.894......................681.......*.........484.........963.498...*..538.............................................346.........
+
.....802.....*162....752...........................................*........520...........229.2.586..513..............25=.746........782*423
+
...............................@...307#.497....551..996..696....879...911................%......................277*........................
+
....*157.....137....#.........621.........*...#.....*...#............*............527......9........./..............844.....@224....304.....
+
.541............*.649.............412.....744......560..............404.....240.......986*.@.......346.....@..........................+.....
+
......268....764.................%.......................902....856.......*....*..........................242.....842.....#.................
+
........&...............514..38..........+..=...........@..............715.142..587.......307.................731...*...954....878*.........
+
............................*.....349....76.92....612.....376.......................257...$...................../.968..............765......
+
........960*414........713.501......&............%.......*......*941............................#........415...........937%.................
+
....967............409..*......605......................375..771........599*884.................880.........*...127..$.................$513.
+
.....*................*..171..*.....@.......507.895..................*.................636...........768...114....-..292.......-...223......
+
...807...977.......218.......753...47.......*......*..............507.90....../725.......*.........+...@.....................755......*.....
+
............*478.............................542....676...............................673........974.....@....*170....261..............134..
+
800...............532............................15............%...445..102.............../510.........625.279..........-.....*.............
+
.......................654.....850.405......................395.....-.......467....477...........973............../........191........398...
+
.925...793...423*.........@..........................................................=.659..........*.....817.....230...........653..-......
+
.......*.........52...........764$....273...................@........430....................................*...........669.....-.......71..
+
.435....804..177....990.838.........#..-...475...297..337..360.........*....914.............................833.............................
+
....*.......*.........*...*.......281......&......*..+.............328..746......=215.......359....295.....................#481......868....
+
..967........936.689%.785..515...............*64.827........................761.........+....&.......+..............................*....637
+
....../.+265..............................562...............235........585..*...........793........=...838.147....284.902..301*330..........
+
....579.........................21%..327................481..*...469%..*.....297.704..............797.....*...........*.................#...
+
......................638............*...................*....81.......780.........*...../...282....................907.882.781.......797...
+
..........671....608.................295.................302......953............171..919.......*........................*...*......#.......
+
............*....*....251.....191........#............*..........................................999.....451....+....286.415.581....274.....
+
..245$.....217...649.-....................898......950..................495*497.......53*............@...........398..-.....................
+
...........................942.......323...............+.....623.........................804.......875........................#.............
+
.....42..543.................*..320....*..918....314....145...........603......991$.921.......261......................762...187.....951*638
+
.....*..#........53........374........756...........*.........-.......................*........../..217*550..............*..................
+
....217..........*................................743......703....368...$861..4*966.415..703................................*959........*344
+
...........626...31...602.................700..........696........*.....................*......396..........591.......*124..................
+
..135........@................................699.139.....*.662....46........=797......144.....#...*289......*.....840............-...102.44
+
................909.......180.............100.*....#...574..*............52...................................451............764.517....*...
+
........701*..........127*............117../...787...........67.....903..........273....*900................................=..........112..
+
............430............423.67.......*..............*572...........@...199.........94..........686.....679.....................921*......
+
.542*119...............396....*.......938...........250......888..........*.....978...................25..../.........306.............780...
+
...............251........*.....................238......................340....+..............112....*........120...*....24................
+
.223.....549......-..98..60..775..28*105...........*.436..951.599.................309*682.......*..937...158.....*....697.*......764..$.....
+
.....788............#....................768.....266........*..%..............................779........*.......542.......148...*....529...
+
....*......310.............412.......23.+....289..........560............249+.204..606*................271...805.......394.......898........
+
....919.......&...867.......*........*......%.........592............166.........*.....460.........369..........*........*..................
+
.........920.......*.....233.....732..500.....950.....*.......514...........110..961..................*309.....450..#...521.................
+
.................753...............*............#...965..............................852...841....%........524.....981............653.......
+
...........858...........*..234..922........65..................991.........-839.800....*......869...836..$.............675..789...*....505.
+
..........*.............516...*..................774.....&.149.=.................*.......737.........*......402....%.......*....#..762......
+
........780.........4.........116.....................976..-...........%........791..................300.....%....338.471...................
+
...................*.................480*160..3..............*727.....363................................................................167
+
...........743.....721.......................*..........808...............942...........339.289.............$............416.....$..........
+
..955...................606*623.............718...503....*...................*245..........*........531.....686......250..../....275........
+
.............@....................110...............*...309..#....&......210..........386.................%...........*........+........391.
+
.....444.....743......519..691......*.......-824......+......759.617....*.......710..*.....814.........356.........464.......709............
+
......*..746......247.....*......596..999.............907.............296.-..../.......760.+.................$.890.......................669
+
...479.....*.........*.......561.....+..........*178......................977....266...*.....640..........607.....*.....%...........545.....
+
........395...=......361........*372.........655..........398...203..11................147..*......../.............196..499........*........
+
..561........646......................*898.......175.570.....$.....#...*..135..............633..314...871......898..........891...90.....780
+
.......*91........405..............627..............*....736.........760.....*........=..........*...........%....*..........*..............
+
....722...........*......................................*.................744.698.367..-........767..........236.692.......308.............
+
...............740........./............906......*593...977.......645............*......167.............................................*...
+
........+...............123...................281....................*...543......461........................175.....................381.319
+
.282...814......771*........920.......................@............473....*...............&....872...../401.....*......=......18............
+
....*.........%......993...*...........................256..223...........242....977.......293.-...............550.....435..................
+
....23.........960........307....$.....504.638*656...............&...................203.............33.$430..................731...........
+
................................885......*................398....763...........805.....=....338.......*......146*916..................513...
+
..20...............42....................828.............../...................*............$.........531............159*761......78........
+
......805-...-..........598...........#.............351........34.........682..516.534..............*........&..........................283.
+
..............664....../.......255..887.....258......%.........*.........*............*.....226..931.91......128............................
+
...557.938#.......75.....585..*...............*.194......#..686........786..........755.......&..........637..............988.......275.....
+
....*............%....35...*.141...........508.....*865.967..............................80*............./.....978....790*.....@...*........
+
.662..................*..............@939...........................204........484....34....99.............@.................350.54.........
+
............358....832..=......................%......307.95........*......654...*......&.........734.....491...50...924.385................
+
............*............340................483.........-.*.......118..794*.....431...........783..*..............-......*.........&594.#...
+
..........338........=.............$.................*....94....................................*...546.....$.......187..593.768........282.
+
...............796.380.183....+.564..94.144.........138..............394.392.....971.......#928.447........275..57...*.......&..............
+
...........233...*.......%...40........*........................945.....*.........-.................%.............=.438...........*......906
+
.....881.../...491...903..........918.....303......................*........578*...................807......597................681.539......
+
......*.................*.463.467*....246.......577.....198.....245.....967.....988.&.........759.......=...*.........-889..................
+
......462..978........664...%...........*.-731.../.....&....375.............#.......217........@........381.250...219......947..............
+
..........&..........................252.......%.............*..............258............427...137...............@........@....-175.......
+
....864...................461..................234.......69.222........*...........411....=............651...#..............................
+
....*......243...............*283...................777-..*..........92.761..581%.*.....................$.....258..867..876.................
+
.916......%.........629.................911*238...........680...239................672.............137@...469.........*.......737...@.......
+
..............764....*........894/..289...........944..........#...........@....%........../876..........*.........687.........*....436.....
+
......442.255.....442..903.............*.....*493..../......................338..346...................927..............764.....536.........
+
.........*.....*........*.....869*888.597.241..................11-....542#...........412*..................235..............................
+
.804.329......344....195...94.......................................*....................880......44.622.........342.18...............417...
+
....*.....=................+.........76..328.....803.....658.....254.............327..........340......*.............@......................
+
...........254........../...........*...*...........*234...%..........20.....238...*..........*.........380......&......78.246%...598.......
+
.96....990.........%..718...%....869.......596....*......................423.....433..93.....613....$.............905...=........*.....497..
+
...*....*........=.86.....499..............*...385.296...................*...........*...............523.$.....................529...$.*....
+
...780.685.....822....................560.35.............................529......780.....................453......................711..930.
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
:ok
+
```
+
+
```elixir
+
defmodule Day03 do
+
def parse_line("", {_, _, acc}), do: acc
+
def parse_line("." <> rest, {x, y, acc}), do: parse_line(rest, {x + 1, y, acc})
+
+
def parse_line(<<c>> <> _ = str, {x, y, items}) when c in ?0..?9 do
+
{num, rest} = Integer.parse(str)
+
len = floor(:math.log10(num) + 1)
+
ref = make_ref()
+
+
points =
+
for i <- 0..(len - 1) do
+
{{x + i, y}, {ref, num}}
+
end
+
+
parse_line(rest, {x + len, y, points ++ items})
+
end
+
+
def parse_line(<<c>> <> rest, {x, y, items}) do
+
parse_line(rest, {x + 1, y, [{{x, y}, <<c>>} | items]})
+
end
+
+
def around({x, y}) do
+
for dx <- -1..1, dy <- -1..1, do: {x + dx, y + dy}
+
end
+
end
+
+
grid =
+
puzzle_input
+
|> String.split()
+
|> Enum.with_index()
+
|> Enum.flat_map(fn {line, y} ->
+
Day03.parse_line(line, {0, y, []})
+
end)
+
+
{parts, ids} =
+
grid
+
|> Enum.split_with(fn {_, value} ->
+
is_binary(value)
+
end)
+
+
parts = Map.new(parts)
+
ids = Map.new(ids)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
%{
+
{77, 129} => {#Reference<0.209765579.1433141249.123990>, 581},
+
{120, 47} => {#Reference<0.209765579.1433141249.123295>, 894},
+
{4, 5} => {#Reference<0.209765579.1433141249.122921>, 229},
+
{78, 98} => {#Reference<0.209765579.1433141249.123728>, 245},
+
{29, 25} => {#Reference<0.209765579.1433141249.123095>, 7},
+
{4, 81} => {#Reference<0.209765579.1433141249.123572>, 135},
+
{121, 77} => {#Reference<0.209765579.1433141249.123544>, 762},
+
{119, 60} => {#Reference<0.209765579.1433141249.123401>, 292},
+
{111, 108} => {#Reference<0.209765579.1433141249.123813>, 175},
+
{78, 75} => {#Reference<0.209765579.1433141249.123526>, 497},
+
{58, 84} => {#Reference<0.209765579.1433141249.123603>, 572},
+
{58, 33} => {#Reference<0.209765579.1433141249.123159>, 687},
+
{13, 55} => {#Reference<0.209765579.1433141249.123356>, 764},
+
{91, 38} => {#Reference<0.209765579.1433141249.123211>, 846},
+
{9, 58} => {#Reference<0.209765579.1433141249.123378>, 960},
+
{25, 87} => {#Reference<0.209765579.1433141249.123628>, 60},
+
{21, 97} => {#Reference<0.209765579.1433141249.123717>, 721},
+
{126, 48} => {#Reference<0.209765579.1433141249.123304>, 993},
+
{26, 82} => {#Reference<0.209765579.1433141249.123584>, 180},
+
{22, 36} => {#Reference<0.209765579.1433141249.123185>, 62},
+
{79, 81} => {#Reference<0.209765579.1433141249.123577>, 797},
+
{65, 55} => {#Reference<0.209765579.1433141249.123358>, 856},
+
{99, 39} => {#Reference<0.209765579.1433141249.123220>, 756},
+
{52, 42} => {#Reference<0.209765579.1433141249.123245>, 180},
+
{120, 77} => {#Reference<0.209765579.1433141249.123544>, 762},
+
{133, 57} => {#Reference<0.209765579.1433141249.123377>, 765},
+
{68, 81} => {#Reference<0.209765579.1433141249.123576>, 46},
+
{22, 103} => {#Reference<0.209765579.1433141249.123768>, 361},
+
{44, 93} => {#Reference<0.209765579.1433141249.123687>, 65},
+
{87, 32} => {#Reference<0.209765579.1433141249.123151>, 110},
+
{81, 37} => {#Reference<0.209765579.1433141249.123201>, 382},
+
{111, 25} => {#Reference<0.209765579.1433141249.123099>, 275},
+
{98, 0} => {#Reference<0.209765579.1433141249.122882>, 6},
+
{110, 80} => {#Reference<0.209765579.1433141249.123570>, 591},
+
{19, 138} => {#Reference<0.209765579.1433141249.124066>, 86},
+
{88, 62} => {#Reference<0.209765579.1433141249.123415>, 673},
+
{37, 15} => {#Reference<0.209765579.1433141249.123010>, 952},
+
{65, 44} => {#Reference<0.209765579.1433141249.123266>, 912},
+
{28, 20} => {#Reference<0.209765579.1433141249.123049>, 397},
+
{10, 32} => {#Reference<0.209765579.1433141249.123149>, 522},
+
{101, 87} => {#Reference<0.209765579.1433141249.123637>, 937},
+
{87, 2} => {#Reference<0.209765579.1433141249.122897>, 890},
+
{46, 108} => {#Reference<0.209765579.1433141249.123810>, 281},
+
{82, 139} => {#Reference<0.209765579.1433141249.124078>, 780},
+
{137, 104} => {#Reference<0.209765579.1433141249.123789>, 780},
+
{82, 100} => {#Reference<0.209765579.1433141249.123745>, 710},
+
{127, 130} => {#Reference<0.209765579.1433141249.124003>, 737},
+
{45, 130} => {#Reference<0.209765579.1433141249.123997>, 238},
+
{70, ...} => {#Reference<0.209765579.1433141249.123447>, ...},
+
{...} => {...},
+
...
+
}
+
```
+
+
```elixir
+
used_parts =
+
for {xy, _} <- parts,
+
dxy <- Day03.around(xy),
+
{:ok, val} <- [Map.fetch(ids, dxy)],
+
into: %{},
+
do: val
+
+
Enum.sum(Map.values(used_parts))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
540025
+
```
+
+
```elixir
+
cogs =
+
for {xy, "*"} <- parts,
+
values =
+
Map.take(ids, Day03.around(xy)) |> Map.values() |> Enum.uniq() |> Enum.map(&elem(&1, 1)),
+
match?([_, _], values),
+
do: Enum.product(values)
+
+
Enum.sum(cogs)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
84584891
+
```
+
+
<!-- livebook:{"offset":29202,"stamp":{"token":"XCP.Hs1g7AgBFOPVrUlnTOZsUUYdlKqkVk9YGMfmcjbRTRcbqm-cLSKFtJFUt2xo4pDeRaPAO77_5Pz02OpzGN1yLqZbyQUSz2G-71NUakdpnMXvmGgs1Bs_FkofPt8OrELeDA","version":2}} -->
+199
2023/day04.livemd
···
+
<!-- livebook:{"persist_outputs":true} -->
+
+
# Day 04
+
+
```elixir
+
Mix.install([:kino_aoc])
+
```
+
+
## Section
+
+
<!-- livebook:{"attrs":{"assign_to":"puzzle_input","day":"4","session_secret":"ADVENT_OF_CODE_SESSION","year":"2023"},"chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2023", "4", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:ok,
+
"Card 1: 43 19 57 13 44 22 29 20 34 33 | 34 68 13 38 32 57 20 64 42 7 44 54 16 51 33 85 43 24 86 93 83 29 25 19 22\nCard 2: 41 56 28 16 47 58 86 8 82 23 | 90 4 63 41 24 8 51 65 39 86 16 53 47 62 74 58 56 82 28 76 37 98 89 67 23\nCard 3: 10 48 83 6 54 51 52 5 22 80 | 36 51 66 86 68 73 93 52 5 65 48 71 85 10 40 22 80 6 20 83 95 54 21 76 92\nCard 4: 17 4 8 74 97 13 52 27 99 95 | 55 31 73 47 95 46 96 69 27 52 45 62 53 12 21 5 74 13 8 50 77 54 91 32 43\nCard 5: 46 50 28 25 44 73 3 14 17 20 | 33 14 44 71 73 59 19 80 40 20 5 6 72 85 47 62 30 50 83 51 24 28 3 77 39\nCard 6: 65 19 45 54 72 39 64 15 3 60 | 91 62 10 73 1 77 25 9 92 7 81 48 19 50 52 32 69 75 24 93 30 60 72 59 53\nCard 7: 41 65 93 76 74 61 59 90 89 87 | 39 61 99 12 71 59 15 10 72 87 41 89 76 88 38 95 90 65 53 80 19 74 93 11 28\nCard 8: 93 64 11 24 13 29 1 51 30 69 | 95 52 7 61 4 44 30 31 64 65 17 34 11 88 71 50 53 73 86 48 60 43 33 51 29\nCard 9: 52 82 95 38 80 53 84 21 93 49 | 41 16 63 88 92 46 23 81 42 3 5 35 8 49 6 22 70 32 38 14 40 61 78 51 10\nCard 10: 41 29 95 65 52 22 51 18 88 44 | 88 92 47 56 71 19 58 52 15 96 25 41 75 29 65 55 43 9 64 81 73 32 5 18 30\nCard 11: 76 66 65 38 41 82 9 81 11 51 | 4 55 70 38 58 17 5 67 26 81 91 48 28 45 83 68 64 66 25 51 95 47 63 71 54\nCard 12: 96 62 75 58 44 72 73 74 9 14 | 20 37 54 97 70 72 18 68 79 3 45 44 15 11 73 59 64 77 61 95 34 16 55 49 2\nCard 13: 79 82 49 23 78 67 45 43 18 11 | 30 28 53 80 13 50 27 70 69 90 18 35 62 98 60 14 38 4 73 15 33 44 77 51 84\nCard 14: 72 65 58 67 11 90 77 21 22 12 | 17 76 4 40 15 22 92 67 43 55 90 79 65 31 71 73 58 12 21 46 20 87 63 77 9\nCard 15: 80 54 73 48 42 70 69 21 23 97 | 31 6 27 93 90 91 16 65 24 25 46 84 37 87 40 58 29 3 64 32 15 62 47 18 94\nCard 16: 15 72 5 85 34 50 49 22 65 64 | 72 92 38 37 79 84 67 93 36 88 50 8 44 19 85 73 76 41 2 45 21 86 6 49 16\nCard 17: 7 70 36 21 60 80 50 31 23 59 | 6 18 1 92 40 22 30 69 38 14 56 81 25 11 77 62 44 4 85 5 82 45 37 24 64\nCard 18: 63 61 70 64 94 76 25 15 26 89 | 22 78 89 65 23 3 29 50 34 72 32 43 8 62 21 15 20 94 68 53 12 84 99 39 57\nCard 19: 34 56 99 80 89 90 47 57 84 39 | 82 6 93 38 61 32 30 46 55 94 85 53 18 1 16 33 11 98 37 5 65 48 12 17 41\nCard 20: 90 72 6 31 62 86 1 29 34 70 | 64 84 86 29 90 3 89 50 6 54 92 85 98 32 63 24 83 43 99 59 77 12 56 38 69\nCard 21: 65 22 72 35 30 38 3 10 98 95 | 63 65 21 71 94 58 25 16 66 51 20 75 28 11 15 24 87 56 83 31 67 1 97 64 52\nCard 22: 95 70 39 21 87 97 98 96 30 6 | 72 26 52 65 62 10 60 49 46 36 25 55 11 42 1 31 3 73 48 29 63 51 66 17 34\nCard 23: 72 74 91 77 42 31 15 61 80 85 | 59 62 43 19 17 16 49 83 95 35 76 67 99 46 48 44 84 98 97 13 51 55 79 29 65\nCard 24: 3 74 76 13 52 81 40 84 73 98 | 23 71 42 2 83 5 18 75 57 41 38 46 60 66 49 62 36 51 12 86 25 22 82 79 1\nCard 25: 39 25 66 16 13 27 48 78 52 23 | 43 48 98 13 88 66 55 18 71 91 11 94 75 96 89 16 4 23 51 50 62 95 63 44 81\nCard 26: 66 30 18 57 40 36 60 95 99 15 | 60 22 73 21 69 84 95 66 51 57 49 12 30 79 99 70 46 61 92 37 36 40 18 31 39\nCard 27: 54 11 56 55 83 78 47 57 50 19 | 45 70 77 49 12 41 69 78 91 20 51 67 3 6 22 62 27 60 4 63 59 75 43 95 31\nCard 28: 71 72 99 35 76 23 8 44 46 53 | 25 97 99 77 37 23 51 22 65 62 60 46 4 47 92 84 9 61 24 82 52 58 39 32 88\nCard 29: 69 33 37 74 19 38 81 82 62 66 | 42 3 67 30 52 90 47 46 34 4 1 71 98 50 54 94 58 15 28 83 91 59 22 78 86\nCard 30: 25 5 15 20 84 23 86 74 50 22 | 20 85 71 46 21 92 61 15 22 73 51 1 84 86 49 25 57 33 44 82 45 5 23 50 74\nCard 31: 26 60 71 4 51 57 81 61 99 64 | 13 70 71 77 9 68 76 99 97 55 94 4 98 34 27 54 61 11 26 31 57 81 39 51 60\nCard 32: 61 16 7 90 49 39 24 34 35 17 | 90 75 34 25 39 26 59 67 24 35 62 19 17 54 31 16 71 76 7 64 8 60 61 13 82\nCard 33: 91 74 62 52 86 6 46 60 16 88 | 27 4 32 1 74 52 69 19 62 16 91 26 86 22 55 59 6 60 83 65 18 72 93 53 41\nCard 34: 79 47 49 71 56 89 21 14 29 58 | 80 2 93 71 37 3 33 70 9 18 20 97 85 6 96 73 35 52 74 63 55 99 41 46 44\nCard 35: 13 30 58 94 50 44 38 99 40 9 | 5 75 79 40 84 20 9 2 67 95 24 30 96 62 50 45 28 99 71 26 52 74 54 44 66\nC" <> ...}
+
```
+
+
```elixir
+
cards =
+
puzzle_input
+
|> String.split("\n", trim: true)
+
|> Enum.map(fn "Card" <> rest ->
+
{id, ": " <> rest} = rest |> String.trim() |> Integer.parse()
+
+
[wins, inputs] =
+
rest
+
|> String.split(" | ")
+
|> Enum.map(fn part ->
+
part
+
|> String.split()
+
|> Enum.map(&String.to_integer/1)
+
end)
+
+
{id, wins, inputs}
+
end)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
[
+
{1, [43, 19, 57, 13, 44, 22, 29, 20, 34, 33],
+
[34, 68, 13, 38, 32, 57, 20, 64, 42, 7, 44, 54, 16, 51, 33, 85, 43, 24, 86, 93, 83, 29, 25, 19,
+
22]},
+
{2, [41, 56, 28, 16, 47, 58, 86, 8, 82, 23],
+
[90, 4, 63, 41, 24, 8, 51, 65, 39, 86, 16, 53, 47, 62, 74, 58, 56, 82, 28, 76, 37, 98, 89, 67,
+
23]},
+
{3, [10, 48, 83, 6, 54, 51, 52, 5, 22, 80],
+
[36, 51, 66, 86, 68, 73, 93, 52, 5, 65, 48, 71, 85, 10, 40, 22, 80, 6, 20, 83, 95, 54, 21, 76,
+
92]},
+
{4, [17, 4, 8, 74, 97, 13, 52, 27, 99, 95],
+
[55, 31, 73, 47, 95, 46, 96, 69, 27, 52, 45, 62, 53, 12, 21, 5, 74, 13, 8, 50, 77, 54, 91, 32,
+
43]},
+
{5, [46, 50, 28, 25, 44, 73, 3, 14, 17, 20],
+
[33, 14, 44, 71, 73, 59, 19, 80, 40, 20, 5, 6, 72, 85, 47, 62, 30, 50, 83, 51, 24, 28, 3, 77, 39]},
+
{6, [65, 19, 45, 54, 72, 39, 64, 15, 3, 60],
+
[91, 62, 10, 73, 1, 77, 25, 9, 92, 7, 81, 48, 19, 50, 52, 32, 69, 75, 24, 93, 30, 60, 72, 59, 53]},
+
{7, ~c")A]LJ=;ZYW",
+
[39, 61, 99, 12, 71, 59, 15, 10, 72, 87, 41, 89, 76, 88, 38, 95, 90, 65, 53, 80, 19, 74, 93, 11,
+
28]},
+
{8, [93, 64, 11, 24, 13, 29, 1, 51, 30, 69],
+
[95, 52, 7, 61, 4, 44, 30, 31, 64, 65, 17, 34, 11, 88, 71, 50, 53, 73, 86, 48, 60, 43, 33, 51,
+
29]},
+
{9, [52, 82, 95, 38, 80, 53, 84, 21, 93, 49],
+
[41, 16, 63, 88, 92, 46, 23, 81, 42, 3, 5, 35, 8, 49, 6, 22, 70, 32, 38, 14, 40, 61, 78, 51, 10]},
+
{10, [41, 29, 95, 65, 52, 22, 51, 18, 88, 44],
+
[88, 92, 47, 56, 71, 19, 58, 52, 15, 96, 25, 41, 75, 29, 65, 55, 43, 9, 64, 81, 73, 32, 5, 18,
+
30]},
+
{11, ~c"LBA&)R\tQ\v3",
+
[4, 55, 70, 38, 58, 17, 5, 67, 26, 81, 91, 48, 28, 45, 83, 68, 64, 66, 25, 51, 95, 47, 63, 71,
+
54]},
+
{12, [96, 62, 75, 58, 44, 72, 73, 74, 9, 14],
+
[20, 37, 54, 97, 70, 72, 18, 68, 79, 3, 45, 44, 15, 11, 73, 59, 64, 77, 61, 95, 34, 16, 55, 49,
+
2]},
+
{13, [79, 82, 49, 23, 78, 67, 45, 43, 18, 11],
+
[30, 28, 53, 80, 13, 50, 27, 70, 69, 90, 18, 35, 62, 98, 60, 14, 38, 4, 73, 15, 33, 44, 77, 51,
+
84]},
+
{14, [72, 65, 58, 67, 11, 90, 77, 21, 22, 12],
+
[17, 76, 4, 40, 15, 22, 92, 67, 43, 55, 90, 79, 65, 31, 71, 73, 58, 12, 21, 46, 20, 87, 63, 77,
+
9]},
+
{15, [80, 54, 73, 48, 42, 70, 69, 21, 23, 97],
+
[31, 6, 27, 93, 90, 91, 16, 65, 24, 25, 46, 84, 37, 87, 40, 58, 29, 3, 64, 32, 15, 62, 47, 18,
+
94]},
+
{16, [15, 72, 5, 85, 34, 50, 49, 22, 65, 64],
+
[72, 92, 38, 37, 79, 84, 67, 93, 36, 88, 50, 8, 44, 19, 85, 73, 76, 41, 2, 45, 21, 86, 6, 49, 16]},
+
{17, [7, 70, 36, 21, 60, 80, 50, 31, 23, 59],
+
[6, 18, 1, 92, 40, 22, 30, 69, 38, 14, 56, 81, 25, 11, 77, 62, 44, 4, 85, 5, 82, 45, 37, 24, 64]},
+
{18, [63, 61, 70, 64, 94, 76, 25, 15, 26, 89],
+
[22, 78, 89, 65, 23, 3, 29, 50, 34, 72, 32, 43, 8, 62, 21, 15, 20, 94, 68, 53, 12, 84, 99, 39,
+
57]},
+
{19, ~c"\"8cPYZ/9T'",
+
[82, 6, 93, 38, 61, 32, 30, 46, 55, 94, 85, 53, 18, 1, 16, 33, 11, 98, 37, 5, 65, 48, 12, 17, 41]},
+
{20, [90, 72, 6, 31, 62, 86, 1, 29, 34, 70],
+
[64, 84, 86, 29, 90, 3, 89, 50, 6, 54, 92, 85, 98, 32, 63, 24, 83, 43, 99, 59, 77, 12, 56, 38,
+
69]},
+
{21, [65, 22, 72, 35, 30, 38, 3, 10, 98, 95],
+
[63, 65, 21, 71, 94, 58, 25, 16, 66, 51, 20, 75, 28, 11, 15, 24, 87, 56, 83, 31, 67, 1, 97, 64,
+
52]},
+
{22, [95, 70, 39, 21, 87, 97, 98, 96, 30, 6],
+
[72, 26, 52, 65, 62, 10, 60, 49, 46, 36, 25, 55, 11, 42, 1, 31, 3, 73, 48, 29, 63, 51, 66, 17,
+
34]},
+
{23, [72, 74, 91, 77, 42, 31, 15, 61, 80, 85],
+
[59, 62, 43, 19, 17, 16, 49, 83, 95, 35, 76, 67, 99, 46, 48, 44, 84, 98, 97, 13, 51, 55, 79, 29,
+
...]},
+
{24, [3, 74, 76, 13, 52, 81, 40, 84, 73, 98],
+
[23, 71, 42, 2, 83, 5, 18, 75, 57, 41, 38, 46, 60, 66, 49, 62, 36, 51, 12, 86, 25, 22, 82, ...]},
+
{25, [39, 25, 66, 16, 13, 27, 48, 78, 52, 23],
+
[43, 48, 98, 13, 88, 66, 55, 18, 71, 91, 11, 94, 75, 96, 89, 16, 4, 23, 51, 50, 62, 95, ...]},
+
{26, [66, 30, 18, 57, 40, 36, 60, 95, 99, 15],
+
[60, 22, 73, 21, 69, 84, 95, 66, 51, 57, 49, 12, 30, 79, 99, 70, 46, 61, 92, 37, 36, ...]},
+
{27, [54, 11, 56, 55, 83, 78, 47, 57, 50, 19],
+
[45, 70, 77, 49, 12, 41, 69, 78, 91, 20, 51, 67, 3, 6, 22, 62, 27, 60, 4, 63, ...]},
+
{28, [71, 72, 99, 35, 76, 23, 8, 44, 46, 53],
+
[25, 97, 99, 77, 37, 23, 51, 22, 65, 62, 60, 46, 4, 47, 92, 84, 9, 61, 24, ...]},
+
{29, [69, 33, 37, 74, 19, 38, 81, 82, 62, 66],
+
[42, 3, 67, 30, 52, 90, 47, 46, 34, 4, 1, 71, 98, 50, 54, 94, 58, 15, ...]},
+
{30, [25, 5, 15, 20, 84, 23, 86, 74, 50, 22],
+
[20, 85, 71, 46, 21, 92, 61, 15, 22, 73, 51, 1, 84, 86, 49, 25, 57, ...]},
+
{31, [26, 60, 71, 4, 51, 57, 81, 61, 99, 64],
+
[13, 70, 71, 77, 9, 68, 76, 99, 97, 55, 94, 4, 98, 34, 27, 54, ...]},
+
{32, [61, 16, 7, 90, 49, 39, 24, 34, 35, 17],
+
[90, 75, 34, 25, 39, 26, 59, 67, 24, 35, 62, 19, 17, 54, 31, ...]},
+
{33, [91, 74, 62, 52, 86, 6, 46, 60, 16, 88],
+
[27, 4, 32, 1, 74, 52, 69, 19, 62, 16, 91, 26, 86, 22, ...]},
+
{34, [79, 47, 49, 71, 56, 89, 21, 14, 29, 58],
+
[80, 2, 93, 71, 37, 3, 33, 70, 9, 18, 20, 97, 85, ...]},
+
{35, [13, 30, 58, 94, 50, 44, 38, 99, 40, 9], [5, 75, 79, 40, 84, 20, 9, 2, 67, 95, 24, 30, ...]},
+
{36, [51, 30, 95, 27, 56, 7, 65, 94, 32, 86], [33, 90, 32, 80, 1, 79, 97, 66, 23, 29, 45, ...]},
+
{37, [14, 13, 1, 4, 86, 17, 9, 41, 68, 91], [1, 17, 85, 42, 82, 2, 91, 9, 94, 8, ...]},
+
{38, [63, 34, 17, 95, 15, 21, 1, 29, 39, 28], [81, 73, 45, 15, 65, 54, 74, 76, 12, ...]},
+
{39, ~c"\nB7,U:P$.-", [45, 37, 60, 8, 86, 31, 76, 90, ...]},
+
{40, [31, 12, 91, 62, 79, 34, 7, 81, ...], [49, 90, 73, 12, 57, 54, 83, ...]},
+
{41, [45, 60, 94, 64, 30, 32, 90, ...], [85, 65, 13, 79, 4, 36, ...]},
+
{42, [26, 16, 82, 83, 74, 68, ...], [21, 59, 65, 72, 29, ...]},
+
{43, [33, 83, 48, 64, 26, ...], [78, 22, 1, 43, ...]},
+
{44, ~c"ZD&a5<:2'b", [88, 31, 11, ...]},
+
{45, [79, 31, 56, ...], [90, 53, ...]},
+
{46, ~c".4$XY?'L&(", [82, ...]},
+
{47, ~c"\f_C\b%SR4\t3", [...]},
+
{48, [...], ...},
+
{49, ...},
+
{...},
+
...
+
]
+
```
+
+
## Part 1
+
+
```elixir
+
cards
+
|> Enum.map(fn {_, wins, inputs} ->
+
matches = length(wins) - length(wins -- inputs)
+
+
if matches > 0, do: 2 ** (matches - 1), else: 0
+
end)
+
|> dbg()
+
|> Enum.sum()
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
19855
+
```
+
+
## Part 2
+
+
```elixir
+
cards
+
|> Enum.reduce(%{}, fn {id, wins, inputs}, acc ->
+
matches = length(wins) - length(wins -- inputs)
+
+
{current, acc} =
+
Map.get_and_update(acc, id, fn v ->
+
v = (v || 0) + 1
+
{v, v}
+
end)
+
+
Enum.reduce(1..matches//1, acc, &Map.update(&2, id + &1, current, fn a -> a + current end))
+
end)
+
|> Map.values()
+
|> Enum.sum()
+
|> dbg()
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
10378710
+
```
+
+
<!-- livebook:{"offset":11578,"stamp":{"token":"XCP.MkFlr54HtUrLxNpCiRslp5uHY2WvhZ1VtV-O2Kmdgys3ejH3O0uJAEJe8o8FxytUQyFTMJeefRatVMyr9J3CU3x5R4g7Ie-s_vb0vC-AepFre8COUMkA6Ws70S_FqoCSbA","version":2}} -->
+194
2023/day05.livemd
···
+
<!-- livebook:{"persist_outputs":true} -->
+
+
# Day 05
+
+
```elixir
+
Mix.install([:kino_aoc, {:range_set, github: "hauleth/range_set"}])
+
```
+
+
## Parse
+
+
<!-- livebook:{"attrs":{"assign_to":"puzzle_input","day":"5","session_secret":"ADVENT_OF_CODE_SESSION","year":"2023"},"chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2023", "5", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:ok,
+
"seeds: 1310704671 312415190 1034820096 106131293 682397438 30365957 2858337556 1183890307 665754577 13162298 2687187253 74991378 1782124901 3190497 208902075 226221606 4116455504 87808390 2403629707 66592398\n\nseed-to-soil map:\n2879792625 0 201678008\n2425309256 1035790247 296756276\n2722065532 1759457739 157727093\n400354950 1917184832 1164285801\n0 201678008 400354950\n1564640751 602032958 433757289\n1998398040 1332546523 426911216\n\nsoil-to-fertilizer map:\n3434127746 3670736129 29685965\n1809924203 1168707872 308179\n2108903682 1437989162 44479258\n237181023 2915565442 27901445\n1173998623 2434447796 13633544\n75539025 740516241 29278225\n41104738 706081954 34434287\n3279397405 3488165796 12149874\n3463813711 3827946213 157129363\n1810232382 769794466 15695437\n877824710 677909236 28172718\n2215709448 1746651561 307558709\n1825927819 1692597620 54053941\n104817250 420198730 132363773\n2916210208 392942051 27256679\n1022591555 2448081340 151407068\n3925105941 3985075576 182313682\n1897186025 2212065968 211717657\n2198981202 1304666789 16728246\n850656807 2054210270 27167903\n3766599721 3500315670 158506220\n3419071398 3279397405 15056348\n7830088 2126976435 33274650\n3620943074 3658821890 11914239\n1264213180 2599488408 138420934\n811586355 2160251085 12020898\n3632857313 3354423388 133742408\n1612763314 1169016051 108601184\n1721364498 2172271983 39793985\n1187632167 601328223 76581013\n823607253 1277617235 27049554\n728944387 2737909342 82641968\n0 2426617708 7830088\n3291547279 3700422094 127524119\n1402634114 1482468420 210129200\n905997428 1321395035 107714902\n4107419623 3294453753 59969635\n1879981760 785489903 17204265\n2153382940 2081378173 45598262\n277361019 802694168 366013704\n1761158483 552562503 48765720\n646208806 2832829861 82735581\n2523268157 0 392942051\n1013712330 1429109937 8879225\n643374723 2423783625 2834083\n265082468 2820551310 12278551\n\nfertilizer-to-water map:\n4253122607 1473424614 41844689\n3040447798 2659805568 46237011\n0 146022665 42081460\n55436822 188104125 65067713\n42081460 132667303 13355362\n2429043181 3587614447 54605699\n888256662 672288214 24436041\n4064969883 1978094070 95324589\n3086684809 977403736 339965972\n120504535 253171838 93494065\n2810558403 2603914183 55891385\n3898695123 2901215107 166274760\n2483648880 4002918707 103777141\n1300545784 2848997109 52217998\n2418717938 1463099371 10325243\n1022681665 808998429 30429585\n2866449788 1411682577 4750813\n1181605510 4172708724 118940274\n2078503930 2466708865 42530000\n1105548530 1545561518 76056980\n978705579 2573458117 30456066\n2324405069 1317369708 94312869\n1991848966 3429793336 22435712\n4190586687 2706042579 43180396\n1352763782 1416433390 46665981\n3760606255 1683093685 138088868\n1399429763 3452229048 135385399\n2121033930 839428014 137975722\n2940673664 2749222975 99774134\n1053111250 2073418659 52437280\n3426650781 1821182553 152991287\n1534815162 2195329002 252024339\n730962658 3067489867 157294004\n3579642068 710244275 98754154\n1786839501 3224783871 205009465\n2259009652 1974173840 3920230\n2587426021 370264097 223132382\n2871200601 2125855939 69473063\n213998600 44701447 87965856\n4233767083 2447353341 19355524\n2262929882 1621618498 61475187\n1009161645 696724255 13520020\n3678396222 593396479 78891735\n912692703 4106695848 66012876\n3757287957 4291648998 3318298\n301964456 0 44701447\n2014284678 2509238865 64219252\n370264097 3642220146 360698561\n4160294472 1515269303 30292215\n\nwater-to-light map:\n4066036887 2992193346 95912236\n531075515 493316918 162009008\n3260565192 854248031 437396028\n1341316194 4205924684 89042612\n1879858967 2058162578 692895326\n452475911 655325926 78599604\n2997176790 1690328655 208783332\n2731804884 3324847814 265371906\n355611136 0 96864775\n2572754293 1899111987 159050591\n1081338600 3590219720 138271571\n1430358806 2779435417 212757929\n3234337635 4179697127 26227557\n854248031 3728491291 227090569\n4161949123 3955581860 102409244\n3205960122 2751057904 28377513\n50952557 147817332 304658579\n1219610171 4057991104 121706023\n4264358367 1291644059 30608929\n3697961220 1322252988 368075667\n1643116735 3088105582 236742232\n693084523 452475911 40841007\n0 96864775 50952557\n\nlight-to-temperature ma" <> ...}
+
```
+
+
```elixir
+
# puzzle_input =
+
"""
+
seeds: 79 14 55 13
+
+
seed-to-soil map:
+
50 98 2
+
52 50 48
+
+
soil-to-fertilizer map:
+
0 15 37
+
37 52 2
+
39 0 15
+
+
fertilizer-to-water map:
+
49 53 8
+
0 11 42
+
42 0 7
+
57 7 4
+
+
water-to-light map:
+
88 18 7
+
18 25 70
+
+
light-to-temperature map:
+
45 77 23
+
81 45 19
+
68 64 13
+
+
temperature-to-humidity map:
+
0 69 1
+
1 0 69
+
+
humidity-to-location map:
+
60 56 37
+
56 93 4
+
"""
+
|> String.trim()
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
"seeds: 79 14 55 13\n\nseed-to-soil map:\n50 98 2\n52 50 48\n\nsoil-to-fertilizer map:\n0 15 37\n37 52 2\n39 0 15\n\nfertilizer-to-water map:\n49 53 8\n0 11 42\n42 0 7\n57 7 4\n\nwater-to-light map:\n88 18 7\n18 25 70\n\nlight-to-temperature map:\n45 77 23\n81 45 19\n68 64 13\n\ntemperature-to-humidity map:\n0 69 1\n1 0 69\n\nhumidity-to-location map:\n60 56 37\n56 93 4"
+
```
+
+
```elixir
+
defmodule Mapping do
+
@behaviour Access
+
+
import Kernel, except: [apply: 2]
+
+
defstruct [:values]
+
+
def from_list(lst) do
+
%__MODULE__{values: Enum.sort(lst)}
+
end
+
+
defp apply({a.._, to}, v), do: v - a + to
+
+
@impl Access
+
def fetch(%__MODULE__{values: list}, key) when is_integer(key) do
+
{:ok, sorted_find(list, key)}
+
end
+
+
def fetch(%__MODULE__{values: map}, %RangeSet{ranges: ranges}) do
+
ranges
+
|> Enum.flat_map(&map_range(&1, map))
+
|> RangeSet.new()
+
|> then(&{:ok, &1})
+
end
+
+
defp sorted_find([], n), do: n
+
defp sorted_find([{a..b, _} = result | _], n) when n in a..b, do: apply(result, n)
+
defp sorted_find([{a.._, _} | _], n) when n < a, do: n
+
defp sorted_find([_ | rest], n), do: sorted_find(rest, n)
+
+
defp map_range(range, []), do: [range]
+
defp map_range(_..hi = range, [{lo.._, _} | _]) when lo > hi, do: [range]
+
defp map_range(lo.._ = range, [{_..hi, _} | rest]) when lo > hi, do: map_range(range, rest)
+
+
defp map_range(arg_range, [{fun_range, _} = fun_def | maps]) do
+
fun_lo..fun_hi = fun_range
+
arg_lo..arg_hi = arg_range
+
lo = max(fun_lo, arg_lo)
+
hi = min(fun_hi, arg_hi)
+
+
[
+
apply(fun_def, lo)..apply(fun_def, hi)
+
| if(hi < arg_hi, do: map_range((hi + 1)..arg_hi, maps), else: [])
+
]
+
end
+
end
+
+
[seeds | maps] =
+
puzzle_input
+
|> String.split("\n\n", trim: true)
+
+
mappings =
+
maps
+
|> Enum.map(fn map ->
+
[_ | lines] = String.split(map, "\n")
+
+
lines
+
|> Enum.map(&String.split/1)
+
|> Enum.map(fn line ->
+
[to, from, len] = Enum.map(line, &String.to_integer/1)
+
{from..(from + len - 1), to}
+
end)
+
|> Mapping.from_list()
+
end)
+
+
seeds =
+
seeds
+
|> String.split()
+
|> tl()
+
|> Enum.map(&String.to_integer/1)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
warning: function get_and_update/3 required by behaviour Access is not implemented (in module Mapping)
+
2023/day05.livemd#cell:5c3rqk2ysnul3qg2ajsq46avpmyi5ixw:1: Mapping (module)
+
+
warning: function pop/2 required by behaviour Access is not implemented (in module Mapping)
+
2023/day05.livemd#cell:5c3rqk2ysnul3qg2ajsq46avpmyi5ixw:1: Mapping (module)
+
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
[1310704671, 312415190, 1034820096, 106131293, 682397438, 30365957, 2858337556, 1183890307,
+
665754577, 13162298, 2687187253, 74991378, 1782124901, 3190497, 208902075, 226221606, 4116455504,
+
87808390, 2403629707, 66592398]
+
```
+
+
## Part 1
+
+
```elixir
+
seeds
+
|> Enum.map(&Enum.reduce(mappings, &1, fn mapping, val -> mapping[val] end))
+
|> Enum.min()
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
51752125
+
```
+
+
## Part 2
+
+
```elixir
+
seeds
+
|> Enum.chunk_every(2)
+
|> Enum.map(fn [start, length] -> start..(start + length - 1) end)
+
|> RangeSet.new()
+
|> then(&Enum.reduce(mappings, &1, fn map, r -> map[r] end))
+
|> RangeSet.min()
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
12634632
+
```
+
+
<!-- livebook:{"offset":8450,"stamp":{"token":"XCP.9I0OWZix2U9jQ5DLHq6aPMZLzaSvoWmFrdBbv9pxQfaL_IHSsv0UiMHQgeLV96EpUjfWS_hLXKNfPjSWsmdceQyf2OEIe1gAC7o2oOp3S4I9UlfKFypRqLfs3Jo6p-UtGQ","version":2}} -->
+107
2023/day06.livemd
···
+
<!-- livebook:{"persist_outputs":true} -->
+
+
# Day 06
+
+
```elixir
+
Mix.install([:kino_aoc])
+
```
+
+
## Section
+
+
<!-- livebook:{"attrs":{"assign_to":"puzzle_input","day":"6","session_secret":"ADVENT_OF_CODE_SESSION","year":"2023"},"chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2023", "6", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:ok, "Time: 44 80 65 72\nDistance: 208 1581 1050 1102"}
+
```
+
+
```elixir
+
# puzzle_input =
+
"""
+
Time: 7 15 30
+
Distance: 9 40 200
+
"""
+
|> String.trim()
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
"Time: 7 15 30\nDistance: 9 40 200"
+
```
+
+
```elixir
+
defmodule Day06 do
+
def solve(t, d) do
+
delta = t ** 2 - 4 * d
+
+
sq_delta = :math.sqrt(delta)
+
+
diff = if sq_delta == floor(sq_delta), do: 1, else: 0
+
+
x1 = (-t + sq_delta) / -2
+
x2 = (-t - sq_delta) / -2
+
+
ceil(x2) - ceil(x1) - diff
+
end
+
end
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:module, Day06, <<70, 79, 82, 49, 0, 0, 8, ...>>, {:solve, 2}}
+
```
+
+
## Part 1
+
+
```elixir
+
puzzle_input
+
|> String.split("\n")
+
|> Enum.map(fn line ->
+
line
+
|> String.split(" ", trim: true)
+
|> tl()
+
|> Enum.map(&String.to_integer/1)
+
end)
+
|> Enum.zip()
+
|> Enum.map(fn {t, d} -> Day06.solve(t, d) end)
+
|> Enum.product()
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
32076
+
```
+
+
## Part 2
+
+
```elixir
+
[t, d] =
+
puzzle_input
+
|> String.split("\n")
+
|> Enum.map(fn line ->
+
line
+
|> String.split(" ", trim: true)
+
|> tl()
+
|> Enum.join()
+
|> String.to_integer()
+
end)
+
+
Day06.solve(t, d)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
34278221
+
```
+
+
<!-- livebook:{"offset":1728,"stamp":{"token":"XCP.RVwRJJq0k3Evn9IAmQDOmuVfBQ2xs0pbIqwAVIMLYEO8Olj2RUttefJ6ky9G2BD-EzyDh-ZjERuBL8PVkFPkYz8g7hdsY0keFA-TEIL4GC3n2j_IwPT1JHFDQ0FwiPBw5g","version":2}} -->
+180
2023/day07.livemd
···
+
<!-- livebook:{"persist_outputs":true} -->
+
+
# Untitled notebook
+
+
```elixir
+
Mix.install([:kino_aoc])
+
```
+
+
## Section
+
+
<!-- livebook:{"attrs":{"assign_to":"puzzle_input","day":"7","session_secret":"ADVENT_OF_CODE_SESSION","year":"2023"},"chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2023", "7", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:ok,
+
"7KAK7 63\n9889J 846\nJ37QA 670\nT2T2J 5\n827K6 552\nKTT5T 116\nJTJ63 457\n55656 482\nA924K 555\n323QQ 568\n2QQ5J 32\nJ4434 784\n9T5A4 738\nT666J 983\n6K6J2 351\n933TT 851\n95567 364\n5T598 858\n55TT4 895\n92T2T 893\n2638T 17\nTT3T9 509\n8T954 579\n834JQ 962\nA9TK7 710\n22552 201\nT7627 879\nK3795 875\nJ79A7 865\nJ9A99 986\n56674 627\n3QT25 470\n53553 542\n3T3K9 718\nAA4AJ 345\n95999 475\nK3335 221\n3QQQ3 207\nTAAAA 152\nA3AQ9 796\n7Q922 53\nJQJQQ 873\nJ888J 808\nTJ223 828\n52355 782\n72889 264\n4KA44 244\nQJK6K 964\nA3T76 71\n38A27 303\n5893T 841\n576J4 826\n884JQ 386\n27233 359\n45A55 906\nK7KT6 677\nT3KT3 254\n7K663 291\n78887 999\nAT8JA 609\n9A2T2 334\nJ3339 607\nJ99K9 427\nK2K66 909\nTT3J3 693\n65732 67\n5Q397 381\nQKJA4 276\n66678 582\n3553K 171\n2AJT7 631\n8JKKK 78\n44764 115\nK3K33 367\n46A66 407\n94673 646\n9QA53 597\nJQ33Q 213\n8A8J8 611\n7QQ77 426\nAJ99A 312\n77883 103\n6666J 914\n33365 495\n66565 890\n88899 258\n333A3 410\n8KT8K 463\n85888 241\n8TQA2 151\n666Q3 118\nQ684T 820\n82228 641\n5335J 644\n2Q7K6 806\n47747 538\nJTATA 186\n74979 127\n79TK9 142\n78787 764\n7QJTJ 650\nA2228 880\n24J4A 195\n6Q3T3 358\n5QJQT 286\n7Q7QQ 232\nJ9JA9 145\n39334 383\n94495 155\nK26K2 344\nT78QQ 76\nK292K 318\n7AJAA 562\n9875Q 876\nQ5555 82\nAT4TT 569\n77779 671\nQTTT2 994\n7T64Q 651\n74779 20\n88T48 639\n93999 373\n3KJQK 385\nT73TJ 612\n766K8 60\nTA538 161\n542T5 52\nK299T 249\nT3A2A 981\n92947 908\n866J2 21\nJ7K23 149\nJQ747 417\nK7J77 837\nAAA6A 925\n7TJ77 506\nK8QKK 248\nKAAAJ 931\nQQQ8Q 37\n79972 961\n777AA 56\n722J2 752\n64346 518\n5JTJ2 629\nK9999 898\nT2AQK 256\n66JJ6 222\nA7A3A 557\n877TT 247\nTKJ59 608\n53775 968\nT8TTT 136\n28862 691\n37QTT 252\nKJ442 772\n866J6 604\n324K5 596\nT7973 309\n2Q922 859\nJ4Q7Q 234\nKQ39T 355\nQ3Q35 635\nTJ428 498\nAKJ48 877\nQ3Q7J 183\n6K6KK 237\nA5Q7K 775\n8T22T 257\n8AA88 225\n777K4 523\nQJK78 917\nK5J82 788\nQ6JAA 339\nT3J63 483\n5555A 3\n7A333 31\nJ7QQ7 711\n54QKQ 726\nJ463A 363\nJJJJJ 905\n3T33T 702\nQ626Q 593\nKQ9KJ 855\n299A2 421\nQK57Q 868\nK29T3 570\n88338 836\n66696 637\n5A755 24\nT49T7 400\n6QJK6 366\nJ3J43 33\n65J66 701\n8J982 821\n2T68J 919\n4J44K 209\n97662 633\n7J344 135\nJK99K 269\n4547A 49\n6557Q 753\n85585 395\nJT555 465\n88884 800\n95A9J 980\n44J46 429\n8AJ8A 372\nK42Q8 184\n79863 329\nQQJQ3 203\n78A8K 166\n6Q7Q6 47\n87727 87\n55755 148\n99739 104\nK956J 357\n53533 10\n54AQ3 761\n66339 143\n38833 563\nAAAA2 304\n6KATK 768\nA6J83 101\n626J6 165\nJTJJQ 193\nK7444 949\n95432 420\nTTT96 311\n833AA 105\n38233 439\n2777Q 912\nJ6442 150\n56A3K 371\nJT24T 226\n4KK88 532\n2J972 823\nTA4Q7 945\n77TJT 578\n55T9A 683\nKJT3Q 394\nTT9TT 28\nT6A9A 932\n32466 306\n2A5J6 270\n8A863 915\n6J4AA 565\n3AJ82 260\n98789 96\n6666K 642\nKK587 982\nA8A3Q 795\nA333A 630\n79999 827\n587A6 587\n5888J 997\nTTT77 647\nQQQ88 412\n6346T 798\nJQQT9 507\nAA223 872\n75475 590\nK8374 680\n72252 464\nQ7775 594\nKAKQK 973\n5T4T4 353\nJQ3JQ 139\n99334 1\n646K4 90\n6AKA5 536\nT3KA9 296\n63QT9 11\nQ8AJ3 308\nAAA8A 922\nJ7722 954\nT8A32 891\nQAQQA 75\nT9TJ9 424\nA8573 786\n2T33J 485\n85T6T 834\n255QQ 405\nTJT8T 131\n89289 408\n9626T 515\n8J2A2 721\nJ4522 812\n7T757 79\n9A999 398\n554AJ 217\nKKKK8 362\nJQTJ3 746\nK8J76 960\nTK6QA 706\n5Q895 976\n33993 690\n9699A 320\nA8265 640\n66AAJ 958\n66664 48\n59Q2K 661\nJ8668 324\n9AJ25 889\n862Q8 546\n8K9T9 198\nK3K3K 215\nJTJ77 689\nAJTT5 377\n88JJ7 448\n8737J 688\n7KQKQ 51\nKKK5K 295\n79T9T 757\n59A47 502\n43AJ9 573\nK9792 605\n37Q33 824\nTTT6T 737\nA4A22 486\n652KK 478\nAK42Q 990\nQ44J5 853\n5Q999 902\n99JJJ 619\nJJQKK 714\nTA5JK 530\nAQQAA 756\nA6JAJ 43\n55KKK 832\n36A2J 374\n4333J 816\nA2J9A 461\n95Q49 292\nJK9A2 365\nJ5256 93\nKK6J6 953\n8QJ72 750\n95959 845\nKK4KK 57\nJ57Q2 686\n5QKA9 119\nJ5J99 342\nKKK2K 454\n33A3K 177\n688J2 409\nQJTTK 766\n3K978 741\n64T47 603\n34584 776\n89KT2 251\nT893T 653\nKK957 717\n9Q8Q5 959\nK5KQ5 174\n3Q223 456\n2J9Q4 934\nA37AQ 58\n42Q35 712\n33633 809\n57J3J 326\n58959 867\nQ838J 632\nQQKJK 936\n8Q7T7 238\nT2T2T 491\n2T987 391\n69KQT 6\nQ6J98 815\nA4JQ4 299\nKAKAJ 25\n8765J 792\n9492J 272\n5QQK5 64\nJ9966 348\n8K888 418\nK8833 813\n33853 129\n24344 321\nQ4444 970\n44QQT 55\n82T28 547\n97K7Q 262\n3A34A 255\nK5K9K 567\nQT4QT 65\n84484 211\nK54QT 471\n23K3K 951\nKTQ2J 157\nJQKKK 705\nJJ333 673\n44222 137\n26K72 991\nT59KT 34\nTQ7QT 684\nJ9J99 435\n26648 950\nT4TKA 758\n6K66K 294\n5JQ55 85\n392QT 387\n54A7J 773\n99Q9T 903\n56365 692\n44T24 490\n538Q4 261\n65277 703\n44A44 941\nJ2A34 535\n7J733 649\n2422T 467\n3J9AJ 554\n3KT3K 389\nA999A 288\n2Q5J" <> ...}
+
```
+
+
```elixir
+
# puzzle_input =
+
"""
+
32T3K 765
+
T55J5 684
+
KK677 28
+
KTJJT 220
+
QQQJA 483
+
"""
+
|> String.trim()
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
"32T3K 765\nT55J5 684\nKK677 28\nKTJJT 220\nQQQJA 483"
+
```
+
+
```elixir
+
defmodule Day07 do
+
def rate({hand, _}) do
+
{jokers, rest} = Map.pop(Enum.frequencies(hand), -1, 0)
+
+
pos =
+
rest
+
|> Map.values()
+
|> Enum.sort(:desc)
+
|> case do
+
[] -> [jokers]
+
[v | rest] -> [v + jokers | rest]
+
end
+
+
{pos, hand}
+
end
+
+
@cards ~C[TJQKA] |> Enum.with_index(10) |> Map.new()
+
+
def card_values(hand) do
+
for <<card <- hand>> do
+
Map.get(@cards, card, card - ?0)
+
end
+
end
+
+
def rate_bids(hands) do
+
hands
+
|> Enum.with_index(1)
+
|> Enum.reduce(0, fn {{_, bid}, idx}, acc ->
+
acc + bid * idx
+
end)
+
end
+
end
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:module, Day07, <<70, 79, 82, 49, 0, 0, 12, ...>>, {:rate_bids, 1}}
+
```
+
+
```elixir
+
hands =
+
puzzle_input
+
|> String.split("\n")
+
|> Enum.map(fn <<hand::binary-5>> <> " " <> bid ->
+
{Day07.card_values(hand), String.to_integer(bid)}
+
end)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
[
+
{[7, 13, 14, 13, 7], 63},
+
{~c"\t\b\b\t\v", 846},
+
{[11, 3, 7, 12, 14], 670},
+
{[10, 2, 10, 2, 11], 5},
+
{[8, 2, 7, 13, 6], 552},
+
{[13, 10, 10, 5, 10], 116},
+
{[11, 10, 11, 6, 3], 457},
+
{[5, 5, 6, 5, 6], 482},
+
{[14, 9, 2, 4, 13], 555},
+
{[3, 2, 3, 12, 12], 568},
+
{[2, 12, 12, 5, 11], 32},
+
{[11, 4, 4, 3, 4], 784},
+
{[9, 10, 5, 14, 4], 738},
+
{[10, 6, 6, 6, 11], 983},
+
{[6, 13, 6, 11, 2], 351},
+
{[9, 3, 3, 10, 10], 851},
+
{[9, 5, 5, 6, 7], 364},
+
{[5, 10, 5, 9, 8], 858},
+
{[5, 5, 10, 10, 4], 895},
+
{[9, 2, 10, 2, 10], 893},
+
{[2, 6, 3, 8, 10], 17},
+
{[10, 10, 3, 10, 9], 509},
+
{[8, 10, 9, 5, 4], 579},
+
{[8, 3, 4, 11, 12], 962},
+
{[14, 9, 10, 13, 7], 710},
+
{[2, 2, 5, 5, 2], 201},
+
{[10, 7, 6, 2, 7], 879},
+
{[13, 3, 7, 9, 5], 875},
+
{[11, 7, 9, 14, 7], 865},
+
{[11, 9, 14, 9, 9], 986},
+
{[5, 6, 6, 7, 4], 627},
+
{[3, 12, 10, 2, 5], 470},
+
{[5, 3, 5, 5, 3], 542},
+
{[3, 10, 3, 13, 9], 718},
+
{[14, 14, 4, 14, 11], 345},
+
{[9, 5, 9, 9, 9], 475},
+
{[13, 3, 3, 3, 5], 221},
+
{[3, 12, 12, 12, 3], 207},
+
{[10, 14, 14, 14, 14], 152},
+
{[14, 3, 14, 12, 9], 796},
+
{[7, 12, 9, 2, 2], 53},
+
{~c"\v\f\v\f\f", 873},
+
{~c"\v\b\b\b\v", 808},
+
{[10, 11, 2, 2, 3], 828},
+
{[5, 2, 3, 5, ...], 782},
+
{[7, 2, 8, ...], 264},
+
{[4, 13, ...], 244},
+
{[12, ...], 964},
+
{[...], ...},
+
{...},
+
...
+
]
+
```
+
+
## Part 1
+
+
```elixir
+
hands
+
|> Enum.sort_by(&Day07.rate/1)
+
|> Day07.rate_bids()
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
251121738
+
```
+
+
## Part 2
+
+
```elixir
+
hands
+
|> Enum.map(fn {hand, bid} -> {Enum.map(hand, &if(&1 == 11, do: -1, else: &1)), bid} end)
+
|> Enum.sort_by(&Day07.rate/1)
+
|> Day07.rate_bids()
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
251421071
+
```
+
+
<!-- livebook:{"offset":7885,"stamp":{"token":"XCP.wRgoLUWae4DX2XUFjTo7CA3j7RlO-lLQQd2jtlaKP6rWdhi_OVydNRFeTmRoLmnU14Jb8Qb8scC1mQjIUhrSe0CuCogmDX7jjcItdJFOzvfF779xRDbllL3GnQv9Rg9vfQ","version":2}} -->
+73
2023/day08.livemd
···
+
# Day 08
+
+
```elixir
+
Mix.install([:kino_aoc])
+
```
+
+
## Section
+
+
<!-- livebook:{"attrs":{"assign_to":"puzzle_input","day":"8","session_secret":"ADVENT_OF_CODE_SESSION","year":"2023"},"chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2023", "8", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
```elixir
+
# puzzle_input =
+
"""
+
LR
+
+
11A = (11B, XXX)
+
11B = (XXX, 11Z)
+
11Z = (11B, XXX)
+
22A = (22B, XXX)
+
22B = (22C, 22C)
+
22C = (22Z, 22Z)
+
22Z = (22B, 22B)
+
XXX = (XXX, XXX)
+
"""
+
```
+
+
```elixir
+
defmodule Day08 do
+
def find_path(instructions, pos, map) do
+
Enum.reduce_while(instructions, pos, fn
+
{_, idx}, <<_, _, ?Z>> -> {:halt, idx}
+
{step, _}, pos -> {:cont, elem(Map.fetch!(map, pos), step)}
+
end)
+
end
+
end
+
+
[instructions | rest] =
+
String.split(puzzle_input, "\n", trim: true)
+
+
instructions =
+
Stream.cycle(for <<c <- instructions>>, do: if(c == ?L, do: 0, else: 1))
+
|> Stream.with_index()
+
+
map =
+
Map.new(rest, fn
+
<<src::binary-3>> <> " = (" <> <<left::binary-3>> <> ", " <> <<right::binary-3>> <> ")" ->
+
{src, {left, right}}
+
end)
+
```
+
+
## Part 1
+
+
```elixir
+
Day08.find_path(instructions, "AAA", map)
+
```
+
+
## Part 2
+
+
```elixir
+
starts = map |> Map.keys() |> Enum.filter(&String.ends_with?(&1, "A"))
+
+
Task.async_stream(starts, &Day08.find_path(instructions, &1, map), ordered: false)
+
|> Enum.reduce(1, fn {:ok, a}, b ->
+
div(a * b, Integer.gcd(a, b))
+
end)
+
```
+
+
<!-- livebook:{"offset":1485,"stamp":{"token":"XCP.dP8RakyYvjO2Dt2LfELbhGu7h_AlwhvgijUPOM_xnTL158Wj_I2mpQbyuTUJEnrHmVyOVnplBQcB1UHSBWM-ogSxBCmlsFU8DVr00oukCY_wP9T2YAIinkNIn_0CtZ7tkg","version":2}} -->
+188
2023/day09.livemd
···
+
<!-- livebook:{"persist_outputs":true} -->
+
+
# Day 09
+
+
```elixir
+
Mix.install([:kino_aoc])
+
```
+
+
## Section
+
+
<!-- livebook:{"attrs":{"assign_to":"puzzle_input","day":"9","session_secret":"ADVENT_OF_CODE_SESSION","year":"2023"},"chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2023", "9", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:ok,
+
"27 49 92 176 327 586 1039 1879 3511 6711 12850 24194 44291 78456 134365 222769 358339 560653 855336 1275364 1862543\n15 25 36 57 117 286 706 1643 3584 7420 14791 28745 55012 104457 197703 373565 703877 1318603 2446886 4482001 8081143\n2 -1 -1 5 35 140 429 1101 2482 5067 9586 17171 29829 51664 91688 169675 327410 648943 1295161 2560233 4960367\n17 40 75 124 195 314 553 1083 2269 4852 10332 21799 45683 95258 197352 404834 819561 1634448 3210609 6218318 11892083\n12 28 47 77 148 320 690 1410 2740 5170 9648 17942 33138 60228 106667 182671 300884 474856 715541 1024739 1384064\n23 34 56 98 179 335 630 1192 2323 4773 10330 22981 51089 111404 236460 488303 984007 1942732 3771076 7214380 13617999\n-3 9 34 76 147 268 465 760 1157 1623 2064 2296 2011 738 -2201 -7740 -17123 -31963 -54306 -86700 -132269\n2 5 10 28 85 240 617 1451 3148 6359 12068 21694 37207 61258 97323 149861 224486 328153 469358 658352 907369\n2 8 19 26 30 54 164 525 1536 4108 10175 23584 51670 108250 219765 438340 869318 1727304 3445143 6876026 13651774\n-7 -3 9 42 129 327 726 1476 2850 5366 9996 18495 33888 61158 108183 186975 315279 518595 832691 1306680 2006739\n14 15 24 47 93 174 306 517 868 1493 2664 4887 9035 16524 29538 51309 86458 141403 224840 348303 526809\n-4 10 50 125 241 410 669 1105 1873 3186 5269 8334 12802 20376 37376 83418 211850 554706 1416484 3461131 8070127\n15 39 76 141 268 519 996 1856 3329 5739 9528 15283 23766 35947 53040 76542 108275 150431 205620 276921 367936\n24 38 52 61 53 10 -73 -138 42 1075 4356 12809 32195 73394 156469 318214 626801 1211053 2319569 4439602 8532786\n4 10 36 100 243 556 1233 2668 5629 11577 23262 45830 88824 169667 319485 592472 1080426 1934604 3397664 5849192 9869161\n-4 7 35 84 170 335 665 1316 2552 4799 8719 15308 26022 42935 68933 107948 165236 247703 364283 526372 748322\n-7 4 31 85 196 437 976 2172 4734 9973 20207 39455 74747 138831 256043 475047 895657 1722829 3370197 6649632 13104456\n16 32 58 111 217 410 745 1344 2499 4865 9805 20028 40853 82880 167863 341774 703534 1466538 3085872 6511449 13672565\n-5 -11 -19 -29 -41 -55 -71 -89 -109 -131 -155 -181 -209 -239 -271 -305 -341 -379 -419 -461 -505\n5 8 27 84 220 507 1078 2190 4332 8382 15798 28785 50293 83555 130708 190077 252623 301509 328232 401228 871348\n22 31 48 86 172 357 726 1417 2671 4960 9297 17952 36037 74887 159044 340266 724833 1525270 3155647 6402851 12728283\n13 26 37 45 58 113 311 867 2175 4888 10013 19021 33972 57655 93743 146963 223281 330102 476485 673373 933838\n12 37 78 151 286 522 901 1478 2383 3991 7275 14433 29888 61749 123771 237731 435898 762853 1275224 2036831 3105150\n8 21 55 123 237 408 646 960 1358 1847 2433 3121 3915 4818 5832 6958 8196 9545 11003 12567 14233\n3 19 44 71 100 149 259 491 916 1602 2605 3974 5783 8206 11654 16996 25889 41245 67866 113281 188822\n8 19 57 138 279 498 814 1247 1818 2549 3463 4584 5937 7548 9444 11653 14204 17127 20453 24214 28443\n9 4 5 23 80 223 554 1285 2829 5953 12058 23725 45786 87356 165507 311589 581617 1072658 1947779 3472867 6069516\n4 5 15 44 100 191 336 594 1120 2264 4761 10142 21660 46317 99077 211200 446093 928628 1898502 3807091 7495429\n15 29 52 91 168 327 635 1168 1976 3031 4181 5172 5894 7252 13693 39949 128019 387751 1089032 2861339 7106618\n4 27 76 163 300 499 772 1131 1588 2155 2844 3667 4636 5763 7060 8539 10212 12091 14188 16515 19084\n0 14 49 126 288 620 1290 2632 5308 10611 21004 41028 78750 147953 271285 484572 842448 1425348 2347731 3767130 5893244\n3 5 19 56 140 317 663 1291 2357 4065 6671 10486 15878 23273 33155 46065 62599 83405 109179 140660 178624\n15 24 50 100 174 275 432 735 1381 2730 5370 10190 18460 31917 52856 84225 129723 193900 282258 401352 558890\n3 10 28 67 151 337 751 1653 3540 7288 14321 26777 47618 80603 130010 199955 293113 408598 538706 664167 747489\n20 41 74 126 209 345 579 1013 1892 3804 8106 17770 38987 84130 177153 363333 726644 1420251 2718970 5107486 9425181\n15 27 39 51 63 75 87 99 111 123 135 147 159 171 183 195 207 219 231 243 255\n8 21 58 139 303 630 1288 2630 5374 10904 21738 42245 79828 147184 267217 484267 889432 1675307 3248534 6450147 12967977\n12 18 24 30 36 42 48 54 60 66 72 78 84 " <> ...}
+
```
+
+
```elixir
+
lines =
+
puzzle_input
+
|> String.split("\n", trim: true)
+
|> Enum.map(fn line ->
+
line
+
|> String.split()
+
|> Enum.map(&String.to_integer/1)
+
end)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
[
+
[27, 49, 92, 176, 327, 586, 1039, 1879, 3511, 6711, 12850, 24194, 44291, 78456, 134365, 222769,
+
358339, 560653, 855336, 1275364, 1862543],
+
[15, 25, 36, 57, 117, 286, 706, 1643, 3584, 7420, 14791, 28745, 55012, 104457, 197703, 373565,
+
703877, 1318603, 2446886, 4482001, 8081143],
+
[2, -1, -1, 5, 35, 140, 429, 1101, 2482, 5067, 9586, 17171, 29829, 51664, 91688, 169675, 327410,
+
648943, 1295161, 2560233, 4960367],
+
[17, 40, 75, 124, 195, 314, 553, 1083, 2269, 4852, 10332, 21799, 45683, 95258, 197352, 404834,
+
819561, 1634448, 3210609, 6218318, 11892083],
+
[12, 28, 47, 77, 148, 320, 690, 1410, 2740, 5170, 9648, 17942, 33138, 60228, 106667, 182671,
+
300884, 474856, 715541, 1024739, 1384064],
+
[23, 34, 56, 98, 179, 335, 630, 1192, 2323, 4773, 10330, 22981, 51089, 111404, 236460, 488303,
+
984007, 1942732, 3771076, 7214380, 13617999],
+
[-3, 9, 34, 76, 147, 268, 465, 760, 1157, 1623, 2064, 2296, 2011, 738, -2201, -7740, -17123,
+
-31963, -54306, -86700, -132269],
+
[2, 5, 10, 28, 85, 240, 617, 1451, 3148, 6359, 12068, 21694, 37207, 61258, 97323, 149861, 224486,
+
328153, 469358, 658352, 907369],
+
[2, 8, 19, 26, 30, 54, 164, 525, 1536, 4108, 10175, 23584, 51670, 108250, 219765, 438340, 869318,
+
1727304, 3445143, 6876026, 13651774],
+
[-7, -3, 9, 42, 129, 327, 726, 1476, 2850, 5366, 9996, 18495, 33888, 61158, 108183, 186975,
+
315279, 518595, 832691, 1306680, 2006739],
+
[14, 15, 24, 47, 93, 174, 306, 517, 868, 1493, 2664, 4887, 9035, 16524, 29538, 51309, 86458,
+
141403, 224840, 348303, 526809],
+
[-4, 10, 50, 125, 241, 410, 669, 1105, 1873, 3186, 5269, 8334, 12802, 20376, 37376, 83418, 211850,
+
554706, 1416484, 3461131, 8070127],
+
[15, 39, 76, 141, 268, 519, 996, 1856, 3329, 5739, 9528, 15283, 23766, 35947, 53040, 76542,
+
108275, 150431, 205620, 276921, 367936],
+
[24, 38, 52, 61, 53, 10, -73, -138, 42, 1075, 4356, 12809, 32195, 73394, 156469, 318214, 626801,
+
1211053, 2319569, 4439602, 8532786],
+
[4, 10, 36, 100, 243, 556, 1233, 2668, 5629, 11577, 23262, 45830, 88824, 169667, 319485, 592472,
+
1080426, 1934604, 3397664, 5849192, 9869161],
+
[-4, 7, 35, 84, 170, 335, 665, 1316, 2552, 4799, 8719, 15308, 26022, 42935, 68933, 107948, 165236,
+
247703, 364283, 526372, 748322],
+
[-7, 4, 31, 85, 196, 437, 976, 2172, 4734, 9973, 20207, 39455, 74747, 138831, 256043, 475047,
+
895657, 1722829, 3370197, 6649632, 13104456],
+
[16, 32, 58, 111, 217, 410, 745, 1344, 2499, 4865, 9805, 20028, 40853, 82880, 167863, 341774,
+
703534, 1466538, 3085872, 6511449, 13672565],
+
[-5, -11, -19, -29, -41, -55, -71, -89, -109, -131, -155, -181, -209, -239, -271, -305, -341,
+
-379, -419, -461, -505],
+
[5, 8, 27, 84, 220, 507, 1078, 2190, 4332, 8382, 15798, 28785, 50293, 83555, 130708, 190077,
+
252623, 301509, 328232, 401228, 871348],
+
[22, 31, 48, 86, 172, 357, 726, 1417, 2671, 4960, 9297, 17952, 36037, 74887, 159044, 340266,
+
724833, 1525270, 3155647, 6402851, 12728283],
+
[13, 26, 37, 45, 58, 113, 311, 867, 2175, 4888, 10013, 19021, 33972, 57655, 93743, 146963, 223281,
+
330102, 476485, 673373, 933838],
+
[12, 37, 78, 151, 286, 522, 901, 1478, 2383, 3991, 7275, 14433, 29888, 61749, 123771, 237731,
+
435898, 762853, 1275224, 2036831, 3105150],
+
[8, 21, 55, 123, 237, 408, 646, 960, 1358, 1847, 2433, 3121, 3915, 4818, 5832, 6958, 8196, 9545,
+
11003, 12567, 14233],
+
[3, 19, 44, 71, 100, 149, 259, 491, 916, 1602, 2605, 3974, 5783, 8206, 11654, 16996, 25889, 41245,
+
67866, 113281, 188822],
+
[8, 19, 57, 138, 279, 498, 814, 1247, 1818, 2549, 3463, 4584, 5937, 7548, 9444, 11653, 14204,
+
17127, 20453, 24214, 28443],
+
[9, 4, 5, 23, 80, 223, 554, 1285, 2829, 5953, 12058, 23725, 45786, 87356, 165507, 311589, 581617,
+
1072658, 1947779, 3472867, 6069516],
+
[4, 5, 15, 44, 100, 191, 336, 594, 1120, 2264, 4761, 10142, 21660, 46317, 99077, 211200, 446093,
+
928628, 1898502, 3807091, 7495429],
+
[15, 29, 52, 91, 168, 327, 635, 1168, 1976, 3031, 4181, 5172, 5894, 7252, 13693, 39949, 128019,
+
387751, 1089032, 2861339, 7106618],
+
[4, 27, 76, 163, 300, 499, 772, 1131, 1588, 2155, 2844, 3667, 4636, 5763, 7060, 8539, 10212,
+
12091, 14188, 16515, ...],
+
[0, 14, 49, 126, 288, 620, 1290, 2632, 5308, 10611, 21004, 41028, 78750, 147953, 271285, 484572,
+
842448, 1425348, 2347731, ...],
+
[3, 5, 19, 56, 140, 317, 663, 1291, 2357, 4065, 6671, 10486, 15878, 23273, 33155, 46065, 62599,
+
83405, ...],
+
[15, 24, 50, 100, 174, 275, 432, 735, 1381, 2730, 5370, 10190, 18460, 31917, 52856, 84225, 129723,
+
...],
+
[3, 10, 28, 67, 151, 337, 751, 1653, 3540, 7288, 14321, 26777, 47618, 80603, 130010, 199955, ...],
+
[20, 41, 74, 126, 209, 345, 579, 1013, 1892, 3804, 8106, 17770, 38987, 84130, 177153, ...],
+
[15, 27, 39, 51, 63, 75, 87, 99, 111, 123, 135, 147, 159, 171, ...],
+
[8, 21, 58, 139, 303, 630, 1288, 2630, 5374, 10904, 21738, 42245, 79828, ...],
+
[12, 18, 24, 30, 36, 42, 48, 54, 60, 66, 72, 78, ...],
+
[0, 4, 25, 68, 141, 272, 548, 1191, 2693, 6050, 13171, ...],
+
[4, -3, -3, 13, 61, 170, 394, 850, 1809, 3869, ...],
+
[-7, -12, -10, 18, 99, 265, 551, 994, 1633, ...],
+
[10, 11, 22, 61, 152, 325, 616, 1067, ...],
+
[-3, 8, 30, 79, 184, 392, 785, ...],
+
[2, 3, 19, 75, 213, 511, ...],
+
[1, 16, 38, 75, 146, ...],
+
[3, 25, 64, 128, ...],
+
[15, 31, 66, ...],
+
[27, 52, ...],
+
[6, ...],
+
[...],
+
...
+
]
+
```
+
+
```elixir
+
defmodule Day09 do
+
def extrapolate(list, field \\ &List.last/1) do
+
reduce(list, [field.(list)], field)
+
end
+
+
defp reduce(list, acc, field) do
+
if Enum.all?(list, &(&1 == 0)) do
+
acc
+
else
+
new =
+
list
+
|> Enum.chunk_every(2, 1, :discard)
+
|> Enum.map(fn [a, b] -> b - a end)
+
+
reduce(new, [field.(new) | acc], field)
+
end
+
end
+
end
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:module, Day09, <<70, 79, 82, 49, 0, 0, 10, ...>>, {:reduce, 3}}
+
```
+
+
## Part 1
+
+
```elixir
+
lines
+
|> Enum.map(fn line ->
+
Day09.extrapolate(line)
+
|> Enum.reduce(&+/2)
+
end)
+
|> Enum.sum()
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
1842168671
+
```
+
+
## Part 2
+
+
```elixir
+
lines
+
|> Enum.map(fn line ->
+
Day09.extrapolate(line, &List.first/1)
+
|> Enum.reduce(&-/2)
+
end)
+
|> Enum.sum()
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
903
+
```
+
+
<!-- livebook:{"offset":11034,"stamp":{"token":"XCP.4niSRZnU_1qf0GtnoryY24xBSp3eHuDV770anpiMIG4QlQY1-YQrGuwXL43UbHafeRUdUytg7ITWDNnIHchGL1JYNXi-59qaGTyx0nfkbcwCqqLa0ukaCsTcU-1fFxEk3w","version":2}} -->
+264
2023/day10.livemd
···
+
<!-- livebook:{"persist_outputs":true} -->
+
+
# Day 10
+
+
```elixir
+
Mix.install([:kino_aoc])
+
```
+
+
## Section
+
+
<!-- livebook:{"attrs":{"assign_to":"puzzle_input","day":"10","session_secret":"ADVENT_OF_CODE_SESSION","year":"2023"},"chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2023", "10", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:ok,
+
"|-L.FL-FJFL.|7FJ7F|F7-7F77.FL7---.7FF77--.|-F|FF--7FF7F-7F--77FFFJFJF7.F-LF7LFJJ.F|.|77F7F---7FLL.|FFJ.FF7-77..F77.-F-7FL-FF|77F-FFLL-FJ-|.J\n|7JF77-|L7J-F-JJL7|-|LJLF-|7.|.LLLJ7|-7.LFJFF--JF7L7|||FJ|F-J77L|F7.L-FJF----L7.FF.FJ-J-L-7|L|LJ7FJJJ.F|L-7L7.FF-|-7F-|J..||LJ-|-J-.|L|J|LF|\nLJ-LL|F7|LL7LLL-|-F7||..||..FJ.FJJF-7JJ|.7JLL--7|L7LJLJ|FJL-77|..FFJ7FJ7L7-|-JL.F--7LJJ|LJJ.F-|L7.FF-L7-F-7F77|J7||FLFJ|FFLL7.|JFJJ--J|.7-7|\n|.FJ.|F7-7L77|||L7JL-7LF777-JJ.|7F-L7JFJ7|F-|.LLJ|L---7||F--J7JFLF|JF-.--7||J.|F-.7LLLFF7||7F777L7FJ-||LJ7|||F|L-7.JJ.||7||J7.|-LL.7J.F7L7--\nF-7LF||.FLJL-7|FF|L7FL-L||F-7|FL7LJ|L7L|.LLJ|FJJLF---7|||L---7L7|L|7||FLFLJ|-FF-7|777FJ7|-FFJ|L77LL-F.JJJL7LLJ.|L7FJFF-77LF-7-|-|77L|7.L--7|\nF-JF-L7--J|JLL7-|LJ|F|J7L|J.J-|F7J7F|JF-7.|LF7F77L--7||LJF---JL-JJ|LJ7FJL7L|JLFJF|7FF7.-JJFL7|-F77J-777JF|L7J.|--L|J7|7LJ7JFJJ..|-J--7.L7.FJ\nL7J|7||J--L-F7.||LFL-JF7.F7.|.FL7.FF7L|7F|FF-7F-7F7FJLJF7L----7JFFJJ.J|7L|7L7JLL|JFFJ7.|.|F-J|FJL7|F7-|F7JF|FF.|.||7L-J7LF-||.L7J7L7FJ7.L-.|\nL7.L-FJJJF|FJ-.|JF--J7FJ7LLJ-..LJF||L-7F-7-L7|L7|||L--7|L-----J-FF-F7FL77|---F7JLL-|JF-77FL-7LJF-JFJ|-|-7-7L-7-7-JLJ-|L7-JJLF7-J-7|L77JFJJ.|\nLL-|FJL7.L|J7|-L7F.|FL-.FJJ.F-F-F-7L-7LJFJ|F|L-JLJL7F7|L----7|.F7F7F7JJ-L--|JJ7|-7-LF|FJF7J|L-7||FJFJ.LLJ.77||.L.LF7LF-F77F-J.F7-J7L-F7FJF-.\nFJ.|J7L77-7LL7J-7---FJ-FL---|||FJFJLLL-7|F7FL-----7||||F--7FJ-FJ||LJ||..LF7|JL--F||.FJL7||LF-7|L7|FJF7-.F-LJ.-7.F7.77F7||7-|L7LJJJFJ.FJJF-L.\n|.F|F7-.|.JJ.L..L|JL7..FJL|FF-7L7L-7F--JLJ|7LF7F--JLJLJ|F7LJJFL7||F-J--J7|7..F|-FL|FL7FJ|L7L7LJFJ|L7||7F|J|L7.F7F77.FJ||L--7--7|7.L-7L-77J|7\nLF-LL.L7J.FF-.F-||--.|-|-F--|FJ7L-7|L--7F7|F-J||F7F---7|||F7LFFJLJL7JL|.FF-77FF7JJF77|||L7L-JF-JLL7||L7F7|F-|.||||LFL7||F7FJ-LJ-77J-J7.LJF7J\nFF.|..7JJ7FLJ7|L-7F|F|.|7LLL|L7F--JL7F7||LJL7FJLJLJLF7|||LJL7FJF---J-|F77|JL7L|||FJL-JL-7L--7L7F7FJ|L7||L7L-F-J|||F7F||||LJ7LLJ.7JFFLF-L7LJ-\nL.FJ-|77--F||F77JJLF-7-J7F7LL7||F--7||LJL7|FJL-7F--7|||LJF--JL7|F-7JF--F7|.L7.|L7L----7FJF7FJFJ||L7|FJ||FJ77L-7LJ||L-JLJL7-|..-.|F7--77LJ-|J\nF|.L7||--FLJ7.L7F-J|FJJFF7FF7||LJF7||L7F7L7L7F-JL-7||||F-JLF-7|LJFJ7JFLF--77L-L7|7FF-7|L7||L7L7||FJ|L7LJ|F7F-7|F-JL--7F--J7F|J-F|7|LLJL7JF|.\nJ|LF|FJFFL.|F7LLJ|.|L7F7||FJLJL--JLJL7LJL7L7|L--7FJLJLJ|LF-JFJ|F-JF7.|.L7FJF7JFJL7FJFJ|FJ||7L7||LJFJ7L7FJ||L7|||F-7F7||F7LLJJ7.FJ.F77JF|F7|F\n||JFJ|F|J|7|JJL|-7-L7LJ|||L-7F7F--7F7L7F7L7LJF--JL--7F7L7|F-JFJL-7||-F-7||FJL7L7FJL7L-JL7||F-JLJF-JLF-JL-J|FJLJLJFJ|LJLJ|7J.F|7LJL|--7FJF|||\nL7--.LLJJ--|.FFJF-7-L-7||L-7LJ||F7LJL7LJL7L-7L-7F7F-J|L7LJL77L7F-J|L7L7|||L-7|FJL7FJF-7FJ||L-7F7|F7JL7F7F-JL--7F-J|L--7FJF77J|F|JLL7FLFLLJ|F\n.JLLF77.L-.|.LJ-7||FF-J||F-JF7LJ|L--7L-7FJF7|F-J||L--JLL-7FJF7||F7L7|FJ||L7FJLJF-JL-J||L7|L-7LJ|||L7FJ|||JF7F-J|F--7F-JL-JL7F---7JJ|F-JJ7LL-\n7-F7|FLJ7|7L-|.FJFL-L-7||L7FJL7LL-7FJF7|L-JLJL-7|L7F-7F7FJ|FJLJLJL7||L7||FJL-7FJF7F7F7|FJ|F-JF7|||FJ|FJLJFJ|L-7||F-JL--7F-7LJF--JJ7||||.7F|.\nL7LL|J|FFJ7FL7.FFJFFF-JLJFJL7FJF7FJ|FJ||F7F---7||FJL7||||FJ|F-7F7FJ||FJLJL7FFJL-J||LJLJL7|L-7||||||L||F7FJFJF-JLJ|F7F7FJL7L7FJF7.F7J-FF.FL-7\nLJ.LL7-J-JL|F|F---7FJF7F7L-7|L7|LJFJL7|LJLJF7FJLJL-7|LJ|||L||7LJLJJ|||F---JFJF---JL---7FJ|F-J|LJ||L7||||L7||L---7LJ|||L7FJ-|L-JL-J|.F-JFF.L7\nFJF|.L--L|-FLFL--7|L7||||F-J|FJL-7L7FJ|7F--JLJF----JL-7LJL7|L---7F7|LJL-7F7|FJF-7F-7F7|L7|L-7L7FJ|FJ|||L7|L7-F-7L-7LJL-JL-7L--7F--J.|.7JL|L|\nF-|77FJLFFJ|J.|F7|L7LJLJ||F-JL7F7L7|L7L7L----7L----7F7L-7FJ|F---J||L---7||LJL7L7|L7|||L7||F-JFJL-J|FJ||FJ|FJFJFJF7|F---7F7L7.LLJJJ.--7J.F777\n|..77-L-7-.LF7FJLJFJ7FF-J|L--7||L7||FJFJF7F7L|F---7|||F7|L7|L--7FJL7F7FJ||F7FJFJ|FJLJL7|||L7FJF7F-JL7LJL7|L-JFJFJLJ|F7F|||FJ-LJ|LLL.J|F-F.|.\n-7-LL|7FJ7L-|-|F-7L--7L-7|F7L|||FJ||L7|F|||L7||JF7LJ|LJ|L7||F--JL7FJ||L7|||LJL|FJL---7||||FJ|FJLJF--JF--J|F--JFJF--J|L7|||L7JFFF7L|7.L|F77J7\nF|7J.-J-LL7L-JLJ7L7F-JF-JLJL-JLJ|FJL7|L7||L7LJL7||F7L-7L7|||L-7F7|L7|L7|||L---JL7F-7FJ||LJL-J|FF7L-7FJ|F-JL7F7L7L7F7|FJLJL-J-F-7.F|F7JL-JFFF\nFLF.LLL7|.|-7.F7F7||F7L-------7FJL7FJL7|||LL7F-J|||L--JFJ|||F-J|||FJL7||LJF-----JL7||FJ|F---7L-J|F7||F7L--7|||.|FJ|LJ|F7.F7|7L7L7-J|FJL|LLJJ\nLJ.|7|LF|7J.LFJLJLJLJL7F--7F--JL--JL7FJ|||F-JL-7||L---7|FJLJL-7|LJL77|||F-JF-7-F7FJLJ|7LJF--JF--J|||LJ|FF7|||L-JL-JF7LJ|FJL77FJFJ|.JJ7F-J|||\nFF-|-J|" <> ...}
+
```
+
+
```elixir
+
# puzzle_input =
+
"""
+
...........
+
.S-------7.
+
.|F-----7|.
+
.||.....||.
+
.||.....||.
+
.|L-7.F-J|.
+
.|..|.|..|.
+
.L--J.L--J.
+
...........
+
"""
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
"...........\n.S-------7.\n.|F-----7|.\n.||.....||.\n.||.....||.\n.|L-7.F-J|.\n.|..|.|..|.\n.L--J.L--J.\n...........\n"
+
```
+
+
```elixir
+
defmodule Day10 do
+
@pipes %{
+
?| => %{s: {{0, 1}, :s}, n: {{0, -1}, :n}},
+
?- => %{e: {{1, 0}, :e}, w: {{-1, 0}, :w}},
+
?L => %{s: {{1, 0}, :e}, w: {{0, -1}, :n}},
+
?J => %{s: {{-1, 0}, :w}, e: {{0, -1}, :n}},
+
?7 => %{n: {{-1, 0}, :w}, e: {{0, 1}, :s}},
+
?F => %{n: {{1, 0}, :e}, w: {{0, 1}, :s}}
+
}
+
+
for {k, v} <- @pipes do
+
v = Macro.escape(v)
+
def symbol_to_map(unquote(k)), do: unquote(v)
+
def map_to_symbol(unquote(v)), do: unquote(k)
+
end
+
+
def symbol_to_map(?S), do: :start
+
def map_to_symbol(nil), do: nil
+
+
@around [
+
{{0, -1}, :n, :s},
+
{{0, 1}, :s, :n},
+
{{-1, 0}, :w, :e},
+
{{1, 0}, :e, :w}
+
]
+
+
def start(map) do
+
{sx, sy} = start = Enum.find_value(map, fn {k, v} -> if v == :start, do: k end)
+
+
routes =
+
for {{dx, dy}, face_next, route} <- @around,
+
pipe = map[{sx + dx, sy + dy}] || %{},
+
Map.has_key?(pipe, face_next),
+
do: route
+
+
dbg(routes)
+
smap = start_to_map(routes)
+
begin = smap |> Map.values() |> hd()
+
start_map = Map.merge(smap, %{start: begin})
+
+
{start, Map.put(map, start, start_map)}
+
end
+
+
defp start_to_map(next) do
+
Enum.find_value(@pipes, fn {_, map} ->
+
if Enum.all?(next, &Map.has_key?(map, &1)), do: map
+
end)
+
end
+
end
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:module, Day10, <<70, 79, 82, 49, 0, 0, 20, ...>>, {:start_to_map, 1}}
+
```
+
+
```elixir
+
pipes =
+
for {line, y} <- Enum.with_index(String.split(puzzle_input)),
+
{segment, x} <- Enum.with_index(String.to_charlist(line)),
+
segment in ~c'|-LJ7FS',
+
into: %{} do
+
{{x, y}, Day10.symbol_to_map(segment)}
+
end
+
+
{start, pipes} = Day10.start(pipes)
+
+
dbg(pipes[start])
+
+
rat =
+
Stream.unfold({start, :start}, fn {{x, y} = pos, face} ->
+
{{dx, dy}, f} = pipes[pos][face]
+
next_pos = {x + dx, y + dy}
+
+
{next_pos, {next_pos, f}}
+
end)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
[:n, :e]
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
%{start: {{0, 1}, :s}, e: {{0, 1}, :s}, n: {{-1, 0}, :w}}
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
#Function<63.53678557/2 in Stream.unfold/2>
+
```
+
+
## Part 1
+
+
```elixir
+
length =
+
rat
+
|> Stream.with_index(1)
+
|> Enum.find_value(fn {p, idx} -> if p == start, do: idx end)
+
+
div(length, 2)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
7066
+
```
+
+
## Part 2
+
+
```elixir
+
map =
+
rat
+
|> Enum.take(length + 1)
+
|> Map.new(&{&1, pipes[&1]})
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
%{
+
{18, 103} => %{e: {{0, 1}, :s}, n: {{-1, 0}, :w}},
+
{61, 121} => %{w: {{0, 1}, :s}, n: {{1, 0}, :e}},
+
{112, 138} => %{s: {{1, 0}, :e}, w: {{0, -1}, :n}},
+
{37, 47} => %{e: {{0, 1}, :s}, n: {{-1, 0}, :w}},
+
{77, 129} => %{s: {{0, 1}, :s}, n: {{0, -1}, :n}},
+
{120, 47} => %{s: {{-1, 0}, :w}, e: {{0, -1}, :n}},
+
{116, 69} => %{s: {{0, 1}, :s}, n: {{0, -1}, :n}},
+
{124, 56} => %{s: {{0, 1}, :s}, n: {{0, -1}, :n}},
+
{117, 125} => %{w: {{-1, 0}, :w}, e: {{1, 0}, :e}},
+
{32, 15} => %{w: {{-1, 0}, :w}, e: {{1, 0}, :e}},
+
{103, 106} => %{s: {{0, 1}, :s}, n: {{0, -1}, :n}},
+
{30, 113} => %{w: {{-1, 0}, :w}, e: {{1, 0}, :e}},
+
{123, 104} => %{e: {{0, 1}, :s}, n: {{-1, 0}, :w}},
+
{89, 14} => %{s: {{0, 1}, :s}, n: {{0, -1}, :n}},
+
{35, 30} => %{s: {{0, 1}, :s}, n: {{0, -1}, :n}},
+
{37, 53} => %{w: {{0, 1}, :s}, n: {{1, 0}, :e}},
+
{77, 130} => %{s: {{0, 1}, :s}, n: {{0, -1}, :n}},
+
{78, 98} => %{s: {{0, 1}, :s}, n: {{0, -1}, :n}},
+
{101, 62} => %{w: {{0, 1}, :s}, n: {{1, 0}, :e}},
+
{95, 56} => %{w: {{-1, 0}, :w}, e: {{1, 0}, :e}},
+
{102, 74} => %{w: {{-1, 0}, :w}, e: {{1, 0}, :e}},
+
{11, 39} => %{w: {{0, 1}, :s}, n: {{1, 0}, :e}},
+
{65, 43} => %{s: {{0, 1}, :s}, n: {{0, -1}, :n}},
+
{22, 38} => %{s: {{1, 0}, :e}, w: {{0, -1}, :n}},
+
{14, 86} => %{w: {{-1, 0}, :w}, e: {{1, 0}, :e}},
+
{49, 117} => %{e: {{0, 1}, :s}, n: {{-1, 0}, :w}},
+
{20, 41} => %{s: {{-1, 0}, :w}, e: {{0, -1}, :n}},
+
{29, 25} => %{s: {{0, 1}, :s}, n: {{0, -1}, :n}},
+
{86, 10} => %{w: {{0, 1}, :s}, n: {{1, 0}, :e}},
+
{83, 36} => %{e: {{0, 1}, :s}, n: {{-1, 0}, :w}},
+
{29, 26} => %{s: {{-1, 0}, :w}, e: {{0, -1}, :n}},
+
{47, 27} => %{s: {{-1, 0}, :w}, e: {{0, -1}, :n}},
+
{31, 42} => %{s: {{-1, 0}, :w}, e: {{0, -1}, :n}},
+
{120, 42} => %{e: {{0, 1}, :s}, n: {{-1, 0}, :w}},
+
{121, 77} => %{s: {{0, 1}, :s}, n: {{0, -1}, :n}},
+
{103, 39} => %{s: {{1, 0}, :e}, w: {{0, -1}, :n}},
+
{102, 57} => %{e: {{0, 1}, :s}, n: {{-1, 0}, :w}},
+
{32, 111} => %{e: {{0, 1}, :s}, n: {{-1, 0}, :w}},
+
{84, 102} => %{s: {{0, 1}, :s}, n: {{0, -1}, :n}},
+
{67, 98} => %{s: {{-1, 0}, :w}, e: {{0, -1}, :n}},
+
{119, 60} => %{s: {{0, 1}, :s}, n: {{0, -1}, :n}},
+
{116, 96} => %{w: {{-1, 0}, :w}, e: {{1, 0}, :e}},
+
{13, 85} => %{s: {{0, 1}, :s}, n: {{0, -1}, :n}},
+
{82, 60} => %{w: {{-1, 0}, :w}, e: {{1, 0}, :e}},
+
{132, 99} => %{w: {{-1, 0}, :w}, e: {{1, 0}, :e}},
+
{111, 108} => %{s: {{1, 0}, :e}, w: {{0, ...}, :n}},
+
{111, 103} => %{s: {{-1, ...}, :w}, e: {{...}, ...}},
+
{15, 92} => %{e: {{...}, ...}, n: {...}},
+
{58, ...} => %{s: {...}, ...},
+
{...} => %{...},
+
...
+
}
+
```
+
+
```elixir
+
{min_x, max_x, min_y, max_y} =
+
Enum.reduce(Map.keys(map), {:inf, -1, :inf, -1}, fn {x, y}, {min_x, max_x, min_y, max_y} ->
+
{min(min_x, x), max(max_x, x), min(min_y, y), max(max_y, y)}
+
end)
+
+
Enum.reduce(min_y..max_y, 0, fn y, acc ->
+
{_, new_acc, _} =
+
Enum.reduce(min_x..max_x, {_in? = false, acc, nil}, fn x, {in?, count, cut} ->
+
pos = {x, y}
+
pipe = Day10.map_to_symbol(map[pos])
+
+
case {in?, cut, pipe} do
+
# Empty - count
+
{true, _, nil} -> {true, count + 1, nil}
+
{false, _, nil} -> {false, count, nil}
+
# Keeping same in? over dead ends or horizontal pipes
+
{in?, ?F, ?J} -> {in?, count, nil}
+
{in?, ?L, ?7} -> {in?, count, nil}
+
{in?, cut, ?-} -> {in?, count, cut}
+
# crossing pipes
+
{in?, _, cut} when cut in ~c[FL] -> {not in?, count, cut}
+
{in?, _, _} -> {not in?, count, nil}
+
end
+
end)
+
+
new_acc
+
end)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
401
+
```
+
+
<!-- livebook:{"offset":10970,"stamp":{"token":"XCP.eg8I0JKuYGKRQ6ZLEkgXh_CgBWFloHr69nddniRhrGb8VYehWkNOR5xKnO3pCjta4lPqCOhary3a6WOL4GEwXCX8z-X23nu4atIlpcMYS7lwpipAaHv0JWjqM8DTukYlMg","version":2}} -->
+125
2023/day11.livemd
···
+
<!-- livebook:{"persist_outputs":true} -->
+
+
# Day 11
+
+
```elixir
+
Mix.install([:kino_aoc])
+
```
+
+
## Section
+
+
<!-- livebook:{"attrs":{"assign_to":"puzzle_input","day":"11","session_secret":"ADVENT_OF_CODE_SESSION","year":"2023"},"chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2023", "11", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:ok,
+
".#...........#.........................................................................#...............#...........#........................\n.......................#....................................................................................................................\n...............................#...........#.................#.............................#.............................................#..\n......#............................................#........................................................................................\n......................................................................#.....#.....................#.........................................\n.................#.......#.......................................#................#.....#.....................#.............................\n.........................................#.................#................................................................................\n................................#.............................................................#..........#..................................\n#.......................................................................#..............................................#.................#..\n..........#....................................#......................................#............................................#........\n................#....................................#........#.............................................................................\n......#........................................................................#............................................................\n......................#..............#..............................................................#..........#.....#......................\n..................................................#.......................#..................................................#..........#...\n............................#...............................................................................................................\n........#...................................................................................................................................\n..................#.......................#................................................................#................................\n.............................................................#........#.....................................................................\n..............................#.......#......................................#.............#........................#.......................\n.#............................................................................................................#...........................#.\n...................................................................................................#....................#...................\n....................#......................#.............#.....#..................................................................#.........\n.................................................................................................................#..........................\n............................................................................................................................................\n....................................................................#.....................#.................................................\n.................................#..............................................#..............#............#.............#.................\n...........................#............................................#...........................................#.......................\n......................#.........................#...........................................................................................\n.......................................#....................................#...................................#...........................\n.....#." <> ...}
+
```
+
+
```elixir
+
lines = String.split(puzzle_input, "\n", trim: true)
+
+
galaxies =
+
for {line, y} <- Enum.with_index(lines),
+
{d, x} <- Enum.with_index(String.to_charlist(line)),
+
d == ?#,
+
do: {x, y}
+
+
{sx, sy} =
+
Enum.reduce(galaxies, {0, 0}, fn {x, y}, {mx, my} -> {max(x, mx), max(y, my)} end)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{139, 139}
+
```
+
+
```elixir
+
[rows, cols] =
+
Enum.reduce(galaxies, [MapSet.new(), MapSet.new()], fn {x, y}, [rows, cols] ->
+
[MapSet.put(rows, y), MapSet.put(cols, x)]
+
end)
+
+
empty_rows = MapSet.difference(MapSet.new(0..sy), rows) |> MapSet.to_list() |> Enum.sort()
+
empty_cols = MapSet.difference(MapSet.new(0..sx), cols) |> MapSet.to_list() |> Enum.sort()
+
+
{empty_rows, empty_cols}
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{[23, 54, 77, 81, 87, 91, 106, 107], ~c".178SYh"}
+
```
+
+
```elixir
+
defmodule Day11 do
+
def reduce_unique_pairs(xs, init, fun) when is_function(fun, 3) do
+
do_map(hd(xs), tl(xs), fun, init)
+
end
+
+
def do_map(_h, [], _fun, acc), do: acc
+
+
def do_map(a, xs, fun, acc) do
+
new =
+
Enum.reduce(xs, acc, fn b, acc1 -> fun.(a, b, acc1) end)
+
+
do_map(hd(xs), tl(xs), fun, new)
+
end
+
+
def expand({x, y}, empty_rows, empty_cols, m \\ 2) do
+
{x + delta(x, empty_cols) * (m - 1), y + delta(y, empty_rows) * (m - 1)}
+
end
+
+
defp delta(p, empty) do
+
Enum.count(empty, &(p > &1))
+
end
+
end
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:module, Day11, <<70, 79, 82, 49, 0, 0, 12, ...>>, {:delta, 2}}
+
```
+
+
## Part 1
+
+
```elixir
+
galaxies
+
|> Enum.map(&Day11.expand(&1, empty_rows, empty_cols))
+
|> Day11.reduce_unique_pairs(0, fn {xa, ya}, {xb, yb}, acc ->
+
acc + abs(xb - xa) + abs(yb - ya)
+
end)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
9686930
+
```
+
+
## Part 2
+
+
```elixir
+
galaxies
+
|> Enum.map(&Day11.expand(&1, empty_rows, empty_cols, 1_000_000))
+
|> Day11.reduce_unique_pairs(0, fn {xa, ya}, {xb, yb}, acc ->
+
acc + abs(xb - xa) + abs(yb - ya)
+
end)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
630728425490
+
```
+
+
<!-- livebook:{"offset":6621,"stamp":{"token":"XCP.eVlqF57ZVWEep_9Yi2Bop2YbV2ltU4T8e1DrVKC83DPGypJtqq5uBZpnlG1ix3mgZ2cTntGIcUv867ImHAf_1T32D0t35IKejAKx886nb4XpUxf8FuS27jeNiQIFpCl4Pg","version":2}} -->
+184
2023/day12.livemd
···
+
<!-- livebook:{"persist_outputs":true} -->
+
+
# Day 12
+
+
```elixir
+
Mix.install([:kino_aoc])
+
```
+
+
## Section
+
+
<!-- livebook:{"attrs":{"assign_to":"puzzle_input","day":"12","session_secret":"ADVENT_OF_CODE_SESSION","year":"2023"},"chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2023", "12", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:ok,
+
".#??..#??.?. 3,1,1,1\n???.##??#??????#???# 1,13,1\n.??#.?#??#????#?? 2,4,1,1,1\n???#??#.???#.?#??#?# 4,2,1,2,1,4\n????#?##???#.??.? 2,2,6,1\n.?????#???.###.##? 7,3,2\n.###?..#??????#???? 4,8,1\n??????????????? 1,1,1,2,1\n???.????????#? 1,3,1,1\n???.#..?#.?#?#??#?. 2,1,1,5,1\n.?..??#.????. 1,3,1,2\n.#?.??#?????##.# 1,2,1,3,1\n?###????.#?? 5,1,2\n?#??.????? 2,4\n?.#????#?????#??#?? 1,6,1,4,1\n#????????#?#?? 1,7,1,1\n?#??.?????? 3,1,1\n?..??#?###?? 1,6\n???.?.??#??##?? 1,1,1,5,1\n#???#.?????? 2,1,3,1\n?###??.??.?#???..? 4,1,2,1,1,1\n?.#???#?.?? 2,1,1\n#??##????##??????#? 7,5,2\n????#????????????# 1,6,1,1,2\n#?.?.##???? 1,1,5\n.?????.?#???????? 1,2,2,2,1\n#??.???#?.????? 2,5,1,1\n?????????.#???. 6,2\n?????????? 1,1,4\n?#??#??#?## 1,7\n????#?##???#? 1,6,1,1\n??#??#.???#?????? 1,1,1,7,1\n?????##?.?#??. 1,2,4\n???##????###????. 4,7\n?.?.?.?#???? 1,1,6\n???..??.????.###??. 2,2,2,5\n????##??#????? 1,7,1,1\n???..????#??? 2,6\n.??.????????. 1,2\n?.#?.????? 1,2\n??????.#???#? 2,5\n?????#.###???#.???# 6,7,1,1\n##.????##..#??#?. 2,6,1,1\n?????.??.?????????. 1,6\n??????..#?# 4,3\n#??????#??..?#? 10,2\n?.?????.?#??? 1,2\n???#??????.. 2,4\n.#?#???####??.?#?##? 12,5\n?.?????##??? 3,4\n?###?###????????# 10,3\n.?????????#? 1,5\n#?##????#???? 1,2,2,1\n.??????.??#???. 1,2,1,1,1\n??#.?#.????# 1,2,1,1\n???????.?#??????.?? 2,1,1,8,1\n???#??.?#???? 5,2,2\n?#??????###???. 2,8\n.??????#???????#? 1,12\n??..???#?#??? 1,6\n?.??????.. 1,1,3\n??#??.?#??#. 1,1,1,1\n?#?????.??????. 1,1,6\n.#?#?????#?#???#?.?? 5,9\n???#???#.#?##????? 5,1,7,1\n?#.??#??#?..?? 1,5,1\n#???#????#?.? 1,1,6,1\n????????.#? 4,1\n????#?#?#??.??.?? 8,1\n???#?????#?#?..#? 4,1,4,1\n??.??????#??.?#??#. 1,3,1,1\n.????????????? 1,2,2,1\n#.?#?#?#?.??? 1,6,1\n?#??#??..?#?? 3,2,3\n..#?.?#??#?# 2,6\n???#?.?..???## 3,1,2\n?????.?#?.???## 3,3,3\n??.?????..????? 3,5\n?.?????##? 1,1,2\n?.??#.#????#???.. 1,3,1,1,4\n??#??#?#?##????.# 3,3,6,1\n?.?.?.?####???.#. 1,8,1\n?##?????#?.?#.. 3,1,1,2,1\n???#???????.#. 2,4,1\n????.??.?#???? 1,3\n.?#?#?#??????##??? 2,11,2\n??.?#?.#?. 2,2,2\n????#...?#???# 4,5\n.??..???#??#?#? 2,1,1,3\n????#.?????? 3,6\n????.?????? 1,1,2\n????#?????.?# 1,2,2,2\n.?#?????.??.? 3,1,1,1\n???#??.?#.??. 1,3,2,2\n?##???????#???????# 2,9,1\n?##?????????.?? 8,1\n.#???????.??#???? 1,4,4\n.?#?.#??.? 1,1,1\n??.?#??????#? 4,3\n??#?#??#??.?? 3,2,1\n.#?.???##? 1,5\n?????.#?.???#? 2,1,1,4\n##????#??? 4,1,1\n?????????# 1,2,3\n??#?#?????##? 4,3\n?#.???##?#????#?##. 1,12\n#.?##???#???..??.?? 1,6,1,2,1\n?#????#??#.#?.##?# 5,1,1,1,4\n?#????#.#??#..? 1,3,1,1,1\n??###?.?.????. 5,2\n.????????#.#? 5,2,1\n.?.#.???..??#.?? 1,1,1,3,1\n#????????.??????. 4,4,2,1,1\n?.??????#? 3,3\n...?#.#.???##? 2,1,1,2\n??????????#.???.?#?? 7,1,1,1\n.????##?#??.???#???? 7,5\n??.#?.???? 1,2,2\n?.#??#??#?? 1,4,2\n????#?????? 1,4,2\n??.???????? 1,1,2\n??#????????#??#???? 3,3,7\n?????????##?.??#?. 1,1,2,1,3,2\n??#????????????.??? 2,11\n??#?.?#???#?##????. 4,3,4,1\n????.???????.?? 1,3\n????#.##?? 1,1,4\n#?????#?????.##?## 2,7,5\n#??.??..?#?#.? 2,1,4\n.??.??.?.?????##? 1,1,1,4\n??.???????#??? 1,7,1\n.#.??.?##???#.? 1,1,3,2,1\n#??.??##??.?#?.#?#?? 3,4,1,4\n???..?????????.# 2,1,3,1,1\n??#.?????#?##.?#.# 2,6,2,1,1\n?#?.?.#??#?? 1,6\n?###????#?.? 6,2\n?.?????????????.?? 1,1,1,1,4,1\n????.?#?##??#??. 1,1,5,2\n???????.????# 1,1,1,3\n##???.????#???# 2,1,1,1,5\n.#?##???####?.??#.?? 4,5,2\n????????#?#?.?#?? 1,1,3,1,3\n?.?????#?. 2,2\n?#???????????#.????? 7,2,1,1,1\n????????#..##. 1,2,2,2\n#?#?##?#??. 3,5\n???#????###????????. 17,1\n.????#???## 1,3,4\n??####??#??#?#?#?#?? 6,6,4\n??????#????.?.?? 1,3,1,1,1\n..?##?.?.?. 3,1\n.???####?????#? 8,1\n.???????#?..??.?# 1,3,1,2,1\n??.?#?????? 1,2,2\n??#???#..?#?????#??? 4,1,5,1,2\n??#?...#?? 4,1\n??????.#?#?##??.?? 2,7\n.???????##???. 1,9\n?..#.????#??#???#?? 1,3,9\n?#??????????#???.#?? 4,3,1,1,3\n.?????#???.??#?.?. 4,1\n??#.?##?#??##??#?#? 1,1,12,1\n?##??#??##???#.?.. 2,9\n#??????#??? 3,4\n##???.?#..#.?# 5,2,1,2\n???.?.???# 2,1,3\n?.?????.?? 2,2\n???.?????#?.?????? 1,2,2\n.#????#????.? 1,6\n????.#.?#??????#???? 1,1,1,1,2,7\n?.???.#.??##???#?? 1,1,1,1,8\n??????.?#? 4,2\n#??..?????#? 2,1,2,1\n?##.#.????##?# 2,1,2,4\n????????#???. 9,1\n??..????.? 1,4\n????#???#?.? 9,1\n#???.??????? 3,1,2,1\n.??????.?##??#. 6,3,1\n#.?.?#????#??#? 1,2,1,2,2\n##??##?.??? 6,1\n?????.????#???? 1,1,6" <> ...}
+
```
+
+
```elixir
+
defmodule Day12 do
+
def parse_pattern(pattern) do
+
pattern
+
|> String.to_charlist()
+
|> Enum.map(&symbol_to_type/1)
+
|> do_chunking()
+
|> Enum.chunk_by(&(elem(&1, 0) == :gap))
+
|> Enum.reject(&match?([{:gap, _}], &1))
+
end
+
+
defp do_chunking([start | rest]), do: do_chunking(start, rest, 1)
+
+
defp do_chunking(curr, [], acc), do: [{curr, acc}]
+
defp do_chunking(curr, [curr | rest], acc), do: do_chunking(curr, rest, acc + 1)
+
defp do_chunking(curr, [next | rest], acc), do: [{curr, acc} | do_chunking(next, rest, 1)]
+
+
defp symbol_to_type(?.), do: :gap
+
defp symbol_to_type(??), do: :wild
+
defp symbol_to_type(?#), do: :lava
+
end
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:module, Day12, <<70, 79, 82, 49, 0, 0, 10, ...>>, {:symbol_to_type, 1}}
+
```
+
+
```elixir
+
puzzles =
+
puzzle_input
+
|> String.split("\n", trim: true)
+
|> Enum.map(fn line ->
+
[pattern, values] = String.split(line)
+
values = values |> String.split(",") |> Enum.map(&String.to_integer/1)
+
+
{Day12.parse_pattern(pattern), values}
+
end)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
[
+
{[[lava: 1, wild: 2], [lava: 1, wild: 2], [wild: 1]], [3, 1, 1, 1]},
+
{[[wild: 3], [lava: 2, wild: 2, lava: 1, wild: 6, lava: 1, wild: 3, lava: 1]], [1, 13, 1]},
+
{[[wild: 2, lava: 1], [wild: 1, lava: 1, wild: 2, lava: 1, wild: 4, lava: 1, wild: 2]],
+
[2, 4, 1, 1, 1]},
+
{[
+
[wild: 3, lava: 1, wild: 2, lava: 1],
+
[wild: 3, lava: 1],
+
[wild: 1, lava: 1, wild: 2, lava: 1, wild: 1, lava: 1]
+
], [4, 2, 1, 2, 1, 4]},
+
{[[wild: 4, lava: 1, wild: 1, lava: 2, wild: 3, lava: 1], [wild: 2], [wild: 1]], [2, 2, 6, 1]},
+
{[[wild: 5, lava: 1, wild: 3], [lava: 3], [lava: 2, wild: 1]], [7, 3, 2]},
+
{[[lava: 3, wild: 1], [lava: 1, wild: 6, lava: 1, wild: 4]], [4, 8, 1]},
+
{[[wild: 15]], [1, 1, 1, 2, 1]},
+
{[[wild: 3], [wild: 8, lava: 1, wild: 1]], [1, 3, 1, 1]},
+
{[
+
[wild: 3],
+
[lava: 1],
+
[wild: 1, lava: 1],
+
[wild: 1, lava: 1, wild: 1, lava: 1, wild: 2, lava: 1, wild: 1]
+
], [2, 1, 1, 5, 1]},
+
{[[wild: 1], [wild: 2, lava: 1], [wild: 4]], [1, 3, 1, 2]},
+
{[[lava: 1, wild: 1], [wild: 2, lava: 1, wild: 5, lava: 2], [lava: 1]], [1, 2, 1, 3, 1]},
+
{[[wild: 1, lava: 3, wild: 4], [lava: 1, wild: 2]], [5, 1, 2]},
+
{[[wild: 1, lava: 1, wild: 2], [wild: 5]], [2, 4]},
+
{[[wild: 1], [lava: 1, wild: 4, lava: 1, wild: 5, lava: 1, wild: 2, lava: 1, wild: 2]],
+
[1, 6, 1, 4, 1]},
+
{[[lava: 1, wild: 8, lava: 1, wild: 1, lava: 1, wild: 2]], [1, 7, 1, 1]},
+
{[[wild: 1, lava: 1, wild: 2], [wild: 6]], [3, 1, 1]},
+
{[[wild: 1], [wild: 2, lava: 1, wild: 1, lava: 3, wild: 2]], [1, 6]},
+
{[[wild: 3], [wild: 1], [wild: 2, lava: 1, wild: 2, lava: 2, wild: 2]], [1, 1, 1, 5, 1]},
+
{[[lava: 1, wild: 3, lava: 1], [wild: 6]], [2, 1, 3, 1]},
+
{[[wild: 1, lava: 3, wild: 2], [wild: 2], [wild: 1, lava: 1, wild: 3], [wild: 1]],
+
[4, 1, 2, 1, 1, 1]},
+
{[[wild: 1], [lava: 1, wild: 3, lava: 1, wild: 1], [wild: 2]], [2, 1, 1]},
+
{[[lava: 1, wild: 2, lava: 2, wild: 4, lava: 2, wild: 6, lava: 1, wild: 1]], [7, 5, 2]},
+
{[[wild: 4, lava: 1, wild: 12, lava: 1]], [1, 6, 1, 1, 2]},
+
{[[lava: 1, wild: 1], [wild: 1], [lava: 2, wild: 4]], [1, 1, 5]},
+
{[[wild: 5], [wild: 1, lava: 1, wild: 8]], [1, 2, 2, 2, 1]},
+
{[[lava: 1, wild: 2], [wild: 3, lava: 1, wild: 1], [wild: 5]], [2, 5, 1, 1]},
+
{[[wild: 9], [lava: 1, wild: 3]], [6, 2]},
+
{[[wild: 10]], [1, 1, 4]},
+
{[[wild: 1, lava: 1, wild: 2, lava: 1, wild: 2, lava: 1, wild: 1, lava: 2]], [1, 7]},
+
{[[wild: 4, lava: 1, wild: 1, lava: 2, wild: 3, lava: 1, wild: 1]], [1, 6, 1, 1]},
+
{[[wild: 2, lava: 1, wild: 2, lava: 1], [wild: 3, lava: 1, wild: 6]], [1, 1, 1, 7, 1]},
+
{[[wild: 5, lava: 2, wild: 1], [wild: 1, lava: 1, wild: 2]], [1, 2, 4]},
+
{[[wild: 3, lava: 2, wild: 4, lava: 3, wild: 4]], [4, 7]},
+
{[[wild: 1], [wild: 1], [wild: 1], [wild: 1, lava: 1, wild: 4]], [1, 1, 6]},
+
{[[wild: 3], [wild: 2], [wild: 4], [lava: 3, wild: 2]], [2, 2, 2, 5]},
+
{[[wild: 4, lava: 2, wild: 2, lava: 1, wild: 5]], [1, 7, 1, 1]},
+
{[[wild: 3], [wild: 4, lava: 1, wild: 3]], [2, 6]},
+
{[[wild: 2], [wild: 8]], [1, 2]},
+
{[[wild: 1], [lava: 1, wild: 1], [wild: 5]], [1, 2]},
+
{[[wild: 6], [lava: 1, wild: 3, lava: 1, wild: 1]], [2, 5]},
+
{[[wild: 5, lava: 1], [lava: 3, wild: 3, lava: 1], [wild: 3, lava: 1]], [6, 7, 1, 1]},
+
{[[lava: 2], [wild: 4, lava: 2], [lava: 1, wild: 2, lava: 1, ...]], [2, 6, 1, 1]},
+
{[[wild: 5], [wild: 2], [wild: 9]], [1, 6]},
+
{[[wild: 6], [lava: 1, wild: 1, ...]], [4, 3]},
+
{[[lava: 1, wild: 6, ...], [wild: 1, ...]], [10, 2]},
+
{[[wild: 1], [...], ...], [1, ...]},
+
{[[...]], [...]},
+
{[...], ...},
+
{...},
+
...
+
]
+
```
+
+
## Part 1
+
+
```elixir
+
defmodule Day12.Part1 do
+
def count_combinations([], []), do: 1
+
def count_combinations([[{:lava, lava} | _] | _], [segment | _]) when lava > segment, do: 0
+
def count_combinations(chunks, segments) when length(chunks) > length(segments), do: 0
+
+
def count_combinations([chunk | rest], [segment | srest]) do
+
chunk_length = chunk_length(chunk)
+
+
cond do
+
chunk_length < segment ->
+
0
+
+
chunk_length == segment ->
+
count_combinations(rest, srest) + 1
+
+
true ->
+
raise "Unimplemented"
+
end
+
end
+
+
defp chunk_length(list), do: Enum.reduce(list, 0, fn {_, val}, acc -> acc + val end)
+
+
defp chunk_splits(remaining, 0), do: {1, [remaining]}
+
defp chunk_splits([], segment) when segment > 0, do: {0, []}
+
defp chunk_splits([{:lava, n} | rest], segment), do: chunk_splits(rest, segment - n)
+
end
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
warning: variable "rest" is unused (if the variable is not meant to be used, prefix it with an underscore)
+
2023/day12.livemd#cell:h2soewijh5haeddpkqukqr3fug26rvi6:6: Day12.Part1.count_combinations/2
+
+
warning: variable "srest" is unused (if the variable is not meant to be used, prefix it with an underscore)
+
2023/day12.livemd#cell:h2soewijh5haeddpkqukqr3fug26rvi6:6: Day12.Part1.count_combinations/2
+
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:module, Day12.Part1, <<70, 79, 82, 49, 0, 0, 9, ...>>, {:chunk_length, 1}}
+
```
+
+
<!-- livebook:{"offset":10867,"stamp":{"token":"XCP.pErJuFAGcK1hyBg5n9FHQQCOc5uSp_xseil4UKha7AOJ2dF-diuCgS0T9sDTdi3bmDpRyQ3_9AYatfSZ6gVmYo8z2aHjDHdLDSoMb7a-ccykpMXbZIu3HqQdRGPO_mU6Fw","version":2}} -->
+303
2023/day13.livemd
···
+
<!-- livebook:{"persist_outputs":true} -->
+
+
# Day 13
+
+
```elixir
+
Mix.install([:kino_aoc])
+
```
+
+
## Setup
+
+
<!-- livebook:{"attrs":{"assign_to":"puzzle_input","day":"13","session_secret":"ADVENT_OF_CODE_SESSION","year":"2023"},"chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2023", "13", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:ok,
+
".#..#......\n..#.#......\n..#...#....\n#.##...####\n.#..#..####\n#.#.##.####\n###..#.#..#\n\n.#.##.#.###\n..####..##.\n#########..\n.##..##..##\n.##..##..##\n#########..\n..####..##.\n.#.##.#.###\n#.#..#.##.#\n..#####.###\n...##.....#\n..#..#..#..\n...##...#..\n\n..##.#.\n#...###\n#...###\n..##.##\n..#..#.\n....##.\n#.#.#..\n.#...##\n##.#...\n###.###\n###.###\n##.#...\n.#...##\n\n#.#.###\n..##.##\n...####\n##....#\n##....#\n...####\n..##.##\n#.#.###\n#.#####\n....##.\n.#...#.\n#.#####\n#....##\n#..##.#\n#..##.#\n#..#.##\n#.#####\n\n###...#...#.#..\n.#.##.#.....#..\n..###..#..#....\n..###..#..#....\n.#.##.#........\n###...#...#.#..\n###..#..##.#.##\n\n##.#.....\n##.#...#.\n..#.#..##\n..##....#\n#..#....#\n#.#..##..\n#.#..##..\n#..#....#\n..##....#\n..#.#..##\n##.#...#.\n##.#.....\n#.#..#.#.\n\n#..#..#..#.##\n..........###\n..........###\n#..#..#..#.##\n###....####.#\n....##......#\n##..##..##..#\n###....####..\n....##.....##\n.#......#.#.#\n.##....##..##\n..#.##.#....#\n####..######.\n.##..#.##.###\n..##..##...#.\n\n..#.###..#.\n####.#.....\n..#.##.##..\n...##...#.#\n###.#......\n#######.###\n..#.#...###\n###.###.##.\n###..#...##\n##....##.#.\n####...#.##\n..###......\n.###..#.#..\n##.##..#.#.\n##.##..#.#.\n\n#.##.###......#\n.#..#.#..##..##\n..##..#.#..#...\n#....##.#.#.#..\n#....##.######.\n######....###.#\n#.##.#...##.##.\n..##..#####.###\n..##..######..#\n..##..######..#\n..##..#####.###\n#.##.#...##.##.\n######....###.#\n#....##.######.\n#....##...#.#..\n\n......#....#...\n.####...##...#.\n######..##..###\n######..##..###\n......##..##...\n.####.######.##\n.#..#.######.#.\n\n#############..##\n.########...###.#\n.########...#.#.#\n#.##..##.###..##.\n..#.##.#....#.#..\n..#....#...####..\n#.#....#.##.#.#..\n.#......#......##\n.#......#......##\n#.#....#.##.#.##.\n..#....#...####..\n\n...#.###.#.\n....##.#.##\n..##..#.###\n..##..#.###\n....##.#.##\n...#.###.#.\n#.#.#.#.#..\n...##.#..##\n.#.####...#\n.#.#.##...#\n...##.#..##\n#.#.#.#.#..\n...#.###.#.\n....##.#.##\n..##..#.###\n\n.#.##.#.#.#..#.\n.........######\n###..####.#..#.\n##.##.##.......\n..#..#..##....#\n.#.##.#...####.\n##.....#..####.\n..####..#..##..\n##....##...##..\n\n....####.####..\n.#..####.####..\n#.#.##..#####..\n##..#.#.#######\n.#.#.##.##.##..\n..##..#.##..#..\n####....#...#..\n..#.#....##.#..\n#..#..#..##.#..\n.#.......#.####\n..........##...\n#.....####.#.##\n##....##....###\n.....#.##.#####\n.#..#.##....#..\n#.....###...#..\n#....##........\n\n#..##..#....###\n#..#.#......###\n.....#..####...\n.##.##.##...###\n.....##.###..##\n.##..##....#.#.\n.##...#.#.#.#..\n\n.###.....##\n..#......#.\n..####.####\n#.##...#.#.\n#..#...####\n##.#.#..###\n##.#.#..###\n#..#...####\n#.##...#.#.\n..####.####\n..#......#.\n.###.....##\n.#.##.#..#.\n..#...###..\n..#...###..\n.#.#..#..#.\n.###.....##\n\n###..##\n...####\n.#..#.#\n#.##...\n#...#..\n#...#..\n#.##...\n\n..#......#.....\n#.#......#.#..#\n.#..####..#....\n.#.#....#.#.##.\n..########..##.\n..#.####.#.....\n..###..###..##.\n#..######..####\n.#####.####.##.\n#..#....#..#..#\n##........##..#\n.....##.....##.\n.##.#..#.##....\n\n...#.##\n...#...\n#..####\n#..####\n...#...\n...#.##\n#.###.#\n.##.#.#\n.#.###.\n.##.##.\n.##..#.\n.#.###.\n.##.#.#\n\n..#...##.\n..###..##\n...##.#..\n###.#.##.\n..##..##.\n###..###.\n..#.#.#..\n####..#..\n...#####.\n##.####..\n###.#..##\n..#######\n..#######\n###.#...#\n##.####..\n...#####.\n####..#..\n\n.##...##.\n#..##..#.\n###..####\n#..##.##.\n.##..##..\n#..###.##\n.##.##.##\n....##.##\n.##.##..#\n.##.##...\n.##.##...\n.##.##..#\n....##.##\n\n#...#.##.##..#.##\n##..#.###...#####\n##..#.###...###.#\n#...#.##.##..#.##\n...#.....###..##.\n..####.#.#.####.#\n..####.#.#.####.#\n...#.....###..##.\n#...#.##.##..#.##\n\n.##..####.#####\n.##..####.####.\n.##.#.##..#.###\n#..#.######.#.#\n.#....##..##...\n##..#.####..##.\n.....#......##.\n##..##..#.#.###\n...##..#.#.#.#.\n...#..##.###...\n...#..##.###...\n\n#..##.#.#.#\n######..##.\n#..#...#..#\n#..#...#..#\n######..##.\n#..##.#.#.#\n#..#..##..#\n#...##.#.##\n######.##.#\n....#..####\n####..##.#.\n\n##.##..##.#.##.#.\n....##.###..##..#\n.##.#.##..######.\n.##.#.##..######.\n....##.###..##..#\n##.##..##.#.##.#.\n#####..#...####..\n..##....###.##.##\n.####...##.#..#.#\n.####....#......#\n##..#...#........\n.##.#..#..##...#.\n#####..#.##....##\n#.#.#.#..#.####.#\n##.######........\n\n....#.#..\n....#.##.\n##.##.#..\n##...#.#.\n#.##..###\n#.##..###\n##...#.#.\n\n##....###.####..#\n" <> ...}
+
```
+
+
```elixir
+
# puzzle_input =
+
"""
+
#.##..##.
+
..#.##.#.
+
##......#
+
##......#
+
..#.##.#.
+
..##..##.
+
#.#.##.#.
+
+
#...##..#
+
#....#..#
+
..##..###
+
#####.##.
+
#####.##.
+
..##..###
+
#....#..#
+
"""
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
"#.##..##.\n..#.##.#.\n##......#\n##......#\n..#.##.#.\n..##..##.\n#.#.##.#.\n\n#...##..#\n#....#..#\n..##..###\n#####.##.\n#####.##.\n..##..###\n#....#..#\n"
+
```
+
+
```elixir
+
defmodule Day13 do
+
def find_axes(list) do
+
reversed = Enum.reverse(list)
+
+
len = length(list)
+
+
back = dbg(do_find(list, 0))
+
front = dbg(do_find(reversed, 0))
+
+
[
+
if(back, do: div(len - back, 2) + back),
+
if(front, do: div(len - front, 2))
+
]
+
|> Enum.filter(& &1)
+
end
+
+
defp do_find([_], _), do: nil
+
+
defp do_find([_ | a], n) when rem(n, 2) == 0, do: do_find(a, n + 1)
+
+
defp do_find(a, n) do
+
if palindrome?(a) do
+
n
+
else
+
do_find(tl(a), n + 1)
+
end
+
end
+
+
def palindrome?(list) do
+
list == Enum.reverse(list)
+
end
+
+
def print_mirror({rows, cols, _, _}) do
+
width = length(cols)
+
+
display =
+
for row <- rows do
+
for digit <- Integer.digits(row, 2) do
+
if digit == 1, do: "#", else: "."
+
end
+
|> List.to_string()
+
|> String.pad_leading(width, ".")
+
end
+
+
IO.puts(Enum.intersperse(display, "\n"))
+
end
+
end
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:module, Day13, <<70, 79, 82, 49, 0, 0, 20, ...>>, {:print_mirror, 1}}
+
```
+
+
```elixir
+
mirrors =
+
puzzle_input
+
|> String.split("\n\n", trim: true)
+
|> Enum.map(fn grid ->
+
mirror =
+
grid
+
|> String.split("\n", trim: true)
+
|> Enum.map(fn line ->
+
for <<c <- line>>, do: if(c == ?#, do: 1, else: 0)
+
end)
+
+
rows = Enum.map(mirror, &Integer.undigits(&1, 2))
+
cols = Enum.zip_with(mirror, &Integer.undigits(&1, 2))
+
+
row = Day13.find_axes(rows)
+
col = Day13.find_axes(cols)
+
+
{rows, cols, row, col}
+
end)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
[
+
{[576, 320, 272, 1423, 591, 1391, 1833], [11, 69, 59, 8, 102, 3, 16, 15, 14, 14, 15], [], ~c"\t"},
+
{[727, 486, 2044, 819, 819, 2044, 486, 727, 1325, 503, 193, 292, 196],
+
[1168, 6048, 4058, 7405, 7405, 4058, 6056, 1168, 7419, 7016, 4924], [4], []},
+
{[26, 71, 71, 27, 18, 6, 84, 35, 104, 119, 119, 104, 35],
+
[3166, 63, 4940, 4626, 3276, 8109, 3629], ~c"\n", []},
+
{[87, 27, 15, 97, 97, 15, 27, 87, 95, 6, 34, 95, 67, 77, 77, 75, 95],
+
[78655, 12352, 100129, 52527, 84909, 118771, 130879], [4], []},
+
{[28948, 11524, 7312, 7312, 11520, 28948, 29291],
+
[67, 103, 91, 60, 60, 1, 102, 24, 1, 1, 90, 1, 98, 1, 1], [], [14]},
+
{[416, 418, 83, 97, 289, 332, 332, 289, 97, 83, 418, 416, 330],
+
[6631, 6150, 1753, 6966, 1032, 193, 192, 3085, 1848], [6], []},
+
{[4683, 7, 7, 4683, 7229, 385, 6553, 7228, 387, 2069, 3123, 1441, 7806, 3255, 1634],
+
[19844, 1462, 1183, 18437, 840, 842, 18437, 1183, 1462, 19844, 13478, 30807, 32634], [2], []},
+
{[370, 1952, 364, 197, 1856, 2039, 327, 1910, 1827, 1562, 1931, 448, 916, 1738, 1738],
+
[9971, 9975, 30684, 10783, 24459, 29376, 17060, 4147, 7044, 17395, 2896], [14], []},
+
{[23425, 9523, 6472, 17236, 17278, 32285, 23094, 6647, 6649, 6649, 6647, 23094, 32285, 17278,
+
17172],
+
[20239, 8708, 21500, 21500, 8708, 20239, 31987, 16624, 7410, 9722, 12287, 5734, 3999, 9626,
+
25332], [], [3]},
+
{[264, 15458, 32359, 32359, 408, 15867, 9722],
+
[24, 59, 58, 58, 59, 24, 71, 7, 59, 59, 7, 71, 24, 59, 26], [], [3]},
+
{[131059, 65309, 65301, 91878, 23060, 16956, 82644, 33027, 33027, 82646, 16956],
+
[1170, 1804, 2035, 1920, 1856, 1856, 1920, 2035, 1804, 1170, 1170, 1185, 1907, 545, 1011, 1166,
+
1804], [], [5]},
+
{[186, 107, 407, 407, 107, 186, 1364, 211, 753, 689, 211, 1364, 186, 107, 407],
+
[264, 96, 6409, 23285, 9690, 26214, 23549, 26118, 6409, 32407, 15603], [3], []},
+
{[11602, 63, 29650, 28032, 4705, 11550, 24734, 7756, 24972],
+
[101, 365, 82, 298, 298, 82, 361, 101, 338, 144, 460, 143, 143, 460, 144], [], ~c"\f"},
+
{[1980, 10172, 22140, 25983, 11116, 6500, 30788, 5172, 18740, 8239, 24, 16875, 24967, 735, 9604,
+
16836, 17152],
+
[25907, 46228, 19968, 7424, 123396, 118793, 112951, 98366, 31786, 129952, 123720, 127208, 130974,
+
8376, 8376], [], [14]},
+
{[19591, 18951, 632, 14023, 883, 13066, 12628],
+
[96, 11, 11, 96, 72, 62, 7, 72, 29, 20, 21, 18, 105, 110, 108], [], [2]},
+
{[899, 258, 495, 1418, 1167, 1703, 1703, 1167, 1418, 495, 258, 899, 722, 284, 284, 658, 899],
+
[16128, 68659, 123373, 98227, 16528, 19584, 30, 29580, 24204, 131059, 89761], [6], []},
+
{[115, 15, 37, 88, 68, 68, 88], ~c"OPI)6`p", [5], []},
+
{[4128, 20521, 10128, 10326, 8166, 6048, 7398, 20431, 16118, 18505, 24601, 774, 13488],
+
[2092, 1557, 6609, 888, 1521, 1458, 1442, 1521, 888, 6609, 1557, 2092, 882, 882, 2092], [],
+
~c"\r"},
+
{~c"\v\bOO\b\v]5.62.5", [1600, 63, 109, 8146, 1659, 5790, 5857], [3], []},
+
{[70, 115, 52, 470, 102, 462, 84, 484, 62, 444, 467, 127, 127, 465, 444, 62, 484],
+
[10957, 10957, 114297, 54199, 58878, 2486, 98231, 113010, 32888], [], [1]},
+
{[198, 306, 463, 310, 204, 315, 219, 27, 217, 216, 216, 217, 27],
+
[3712, 5470, 5470, 2688, 2815, 1535, 5888, 7905, 1267], ~c"\n", []},
+
{[71371, 104223, 104221, 71371, 8422, 31421, 31421, 8422, 71371],
+
[481, 192, 12, 30, 493, 12, 481, 493, 192, 319, 307, 30, 204, 493, 222, 435, 493], [6], []},
+
{[13279, 13278, 13719, 19445, 8600, 26086, 518, 26199, 3242, 2488, 2488],
+
[168, 1896, 1792, 135, 300, 1688, 2019, 2023, 1704, 167, 1995, 1607, 1976, 1852, 1416], ~c"\n",
+
[]},
+
{[1237, 2022, 1161, 1161, 2022, 1237, 1177, 1131, 2029, 79, 1946],
+
[2045, 581, 581, 2037, 1646, 588, 1073, 415, 1638, 587, 1470], [3], []},
+
{[111450, 7065, 54910, 54910, 7065, 111450, 127548, 25051, 61861, 61569, 102656, 53858, 127683,
+
87229, 114432],
+
[17175, 23421, 6638, 17381, 32639, 9217, 6147, 32525, 26321, 9446, 23180, 6474, 32642, 32642,
+
6466, 23180, 9446], [3], []},
+
{[20, 22, 436, 394, 359, 359, 394], [31, 25, 6, 22, 112, 9, 118, 47, 6], [5], []},
+
{[100217, 100217, 46111, 64677, 64959, 18555, 64861, 131030, 388, 112431, 66318, 67525, 118470],
+
[6191, 8041, 993, 1896, 1896, 993, 8043, 6191, 6526, 819, 6371, 7048, 7648, 7628, 1919, 1453,
+
8138], [1], []},
+
{[291, 1, 24, 28, 1, 291, 492], [67, 1, 1, 67, 24, 25, 9, 66, 102], [], [2]},
+
{~c"2aa2\n}|\n2", [204, 493, 301, 30, 12, 307, 200], [2], []},
+
{[3115, 4616, 3100, 4656, 4643, 1344, 167], [44, 80, 82, 44, 2, 1, 2, 77, 24, 112, 17, 69, 69],
+
[], ~c"\f"},
+
{[67339, 92194, 8007, 70176, 4382, 5406, 70176, 8007, 92194, 67339, 55372, 10833, 123746, 57569,
+
57569],
+
[26980, 23, 8279, 8271, 8080, 12504, 21152, 22956, 22180, 3, 4255, 10567, 1544, 17968, 5776,
+
30436, 20651], [14], []},
+
{[6424, 26178, 346, 6490, 23485, 15384, 14592, 9703, 26392, 23515, 32280, 32475, 15706, 32358,
+
9471, 23320, 17254],
+
[37355, 36732, 81146, 81146, 35708, 37355, 96147, 4772, 58045, 4621, 96758, 96758, 4621, 58045,
+
4772], [], ~c"\v"},
+
{[75457, 7450, 103542, 100685, 20575, 20575, 117069, 103542, 7450, 75457, 75457, 7450, 103542,
+
117069, 20575],
+
[22966, 6534, 1795, 16432, 14029, 10570, 28924, 16432, 10570, 16432, 24503, 4228, 14029, 12107,
+
8071, ...], ~c"\n", []},
+
{[114654, 1118, 92031, 101299, 101299, 92031, 1118, 114654, 31935, 80545, 20702, 1480, 17953,
+
69836, 60269, ...],
+
[96904, 78341, 18775, 84868, 66504, 78725, 118578, 96919, 96805, 78826, 118382, 31124, 130880,
+
118637, ...], [4], []},
+
{[14474, 14474, 17870, 27951, 39, 7069, 240, 31399, 31655, 240, 7069],
+
[396, 1676, 1581, 1709, 384, 45, 421, 1855, 274, 222, 51, 1953, 493, ...], [1], []},
+
{[36, 36, 84, 53, 75, 28, 32, 126, 125, 125, 126, 36, 28, ...],
+
[5362, 27129, 6901, 1782, 31485, 1170, 3171], [1], []},
+
{[4259, 8068, 7, 8168, 4551, 6595, 1584, 4292, 84],
+
[442, 168, 164, 164, 184, 442, 59, 292, 5, 32, 211, ...], [], ~c"\f"},
+
{[130987, 86, 74905, 93, 126, 56186, 81145, 81094, 23097, 81025, 124915, ...],
+
[20924, 16916, 16980, 20924, 17386, 17386, 20924, 16980, 16916, 20924, ...], [], [5]},
+
{[38804, 125056, 92872, 151, 1196, 129732, 62279], [50, 99, 51, 51, 67, 50, 68, 83, 65, ...], [],
+
[16]},
+
{[54, 11, 393, 54, 127, 127, 54, 393, 11, ...],
+
[1056, 1057, 388, 5069, 5071, 3510, 5066, 7130, ...], [5], []},
+
{[391, 2025, 404, 2039, 188, 1629, 1605, 1894, ...],
+
[44902, 44902, 123750, 127129, 44866, 45628, 31078, ...], [], [1]},
+
{[1658, 1655, 26, 2019, 1637, 1649, 1655, ...], [446, 444, 34, 34, 444, 446, ...], [], [3]},
+
{[365, 1438, 1069, 780, 1216, 1664, ...], [14332, 2892, 27071, 10003, 17863, ...], [14], []},
+
{[7917, 64, 436, 297, 7982, ...], [70857, 70889, 70889, 70857, ...], [], [2]},
+
{[7224, 12736, 21104, 27923, ...], [32323, 42255, 121795, ...], [5], []},
+
{[203, 313, 1753, ...], [5527, 5527, ...], [], [...]},
+
{[41, 73, ...], [685, ...], [], ...},
+
{[116426, ...], [...], ...},
+
{[...], ...},
+
{...},
+
...
+
]
+
```
+
+
## Part 1
+
+
```elixir
+
Enum.map(mirrors, fn {_, _, row, col} ->
+
List.first(col, 0) + List.first(row, 0) * 100
+
end)
+
|> Enum.sum()
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
40006
+
```
+
+
## Part 2
+
+
```elixir
+
defmodule Day13.Part2 do
+
import Bitwise
+
+
def alternatives(list, a, n) do
+
l = length(list)
+
+
list =
+
for i <- 0..n,
+
d = bsl(1, i),
+
j <- 0..l,
+
desmudged = List.update_at(list, j, &bxor(&1, d)),
+
v <- Day13.find_axes(desmudged),
+
v not in a,
+
do: v
+
+
Enum.dedup(list)
+
end
+
end
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:module, Day13.Part2, <<70, 79, 82, 49, 0, 0, 11, ...>>, {:alternatives, 3}}
+
```
+
+
```elixir
+
mirrors
+
|> Enum.with_index()
+
|> Enum.map(fn {{rows, cols, row, col}, _idx} ->
+
row = List.first(Day13.Part2.alternatives(rows, row, length(cols)), 0)
+
col = List.first(Day13.Part2.alternatives(cols, col, length(rows)), 0)
+
+
row * 100 + col
+
end)
+
|> Enum.sum()
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
28627
+
```
+
+
<!-- livebook:{"offset":14833,"stamp":{"token":"XCP.8-i47duAdnzdKS-qi8IVDyDE21kJUyqTX55xsBPltOjjVtrJUuw2vu5-Ufhj9sPB_IGriiYKDwSN8h0k2cz2-dY78-3ZRE77glupVo5cCwEbWm4pbp6TLRefkSB06zCZdQ","version":2}} -->
+430
2023/day14.livemd
···
+
<!-- livebook:{"persist_outputs":true} -->
+
+
# Day 14
+
+
```elixir
+
Mix.install([:kino_aoc])
+
```
+
+
## Section
+
+
<!-- livebook:{"attrs":{"assign_to":"puzzle_input","day":"14","session_secret":"ADVENT_OF_CODE_SESSION","year":"2023"},"chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2023", "14", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:ok,
+
"####....#..O#O..#.....OO.O#..O.......O.#OO.#...O.O..O..O..OO.##.O#...........#....##O#..O#.O.O......\n....#..#.........O.O#..OO#OO....O.....#O.#.O##..#...OO#OOO.O...#...O..#.O.#....##.....#O............\n...#O..#........#....O...O.......O#.##.O.......O..O#O#.#OO....O..O.......#O.........#O.#.O...#...#..\n#O...O...O.O..O..OO.#...O.O#....##O.##..#.OOO#...OO.#...OOO.#.O.#....#....O..##.....OO....#..O...#O.\n.#.......##.#...#...O............O...#......#..#.OO...O#....O.#..........O..O.OOO#.#O#....OO..#.#O.#\n..#..........#..O.O#.....O.OOO.#.##...##...OO..#..#.O#..OO.O#..#O..#O.O#.O.O#..#.#OOO..#OO.O.##..#..\n#..#....O.#O.O.#...O......O...###O.#...OOO#..#.O..#O.O..O.#OO...O...#..#OOO.....O...O...OO..##....O.\n...##....#..#.O#..#O...#.#......##.OO.O.......O....#O#..OOOO#....O.#OO.#O....#...O#O#..O.#.....O....\n...#O....#.#O........O.O#O....O...#.O....#....#...#O.....O.O.O.#.#.......#.........#O#........O.....\n...O...#.O#....#O#O.....O..O#...#O........O.#.##.....O.#...O..#...##O.#.#O#..O..##......#O.#...O#..#\n#..OO#.#.........O#......#O.##.O#...O..#.#.#.OO........#......#....#..#.......O.#O.##.###.####....O.\nO..O...#O..O..##.O..............#O......OOO#...#.#.#.........OO....OO....O#.#.O#.O.........#.......O\n..O#.#....O..#....#OO..##...#..#...O..##O...##.O..O.OO.#.###...O..#.OO..O#...#......#.....O.#..O..#.\nO..####.O..O.OO##.O...O..O#.#O..O...O..........#O.#..#..O..O#..O##O.O.#O.#..O.OO.O..#...O.#O..O.O.#.\n.......O..........#...OO.O#.#.#OOOO...OO#O..O.#.#......#O.#.#...#.O#......O.O.OO...#.##..#.O.#..O..#\n.#.....#O........#.O...#........O............#O......##.O..O..#.#......O#O..O...O..O.#.O...O.#..OOOO\n.......O#...O...OO#.....#..O.#O..##..#O.#....OO.##.#O#......O#..O....OO..#...#O...O...##O..O###..OOO\n...O...#..O..O..#O.O......#.O...#..O#..#..O.OO...O....O.#O#..###O....O..##OOO.#O.....#...#.....#...O\nO...OO.#...#...O.O..#O.OO..O.#.#.#O#.O.#.O..O#O.....##O..O#.O..O........O...#.......O#.#...#.#..OO..\n..OO..#.#.O#.OOO.....##.O..OOO##O#.O..O.##OOO...O..##.O......#O.##..#O..O....#.##.O###...##..O......\n.......O..OO....##......O..O#O.O.O#....#O.....#....O..O.OO...#.O.#..#....#.O..#O....O......##O.....#\n......O..#...O..O#O.#.O.......#.O#.....O.O#..#.#...O..##......O.O..O#.#.#..#.O.#O.O#.O.#......#.O...\n....O.....O..O.......#.O.OO.....O##....##.#OO..#O..#.#...##..O#O.O...O..OO..##....O#O..O....#...O.#O\n.......O.##O.#O#.........O#.OO....###.OO..O.#..#.....OO.O.O...O......O..O..O....O...#.#....#....#O..\nO..#O......#.O..#O.O.#......O#..#.O##..#.#.O.....#.O...O..OO..####.#...##......#.....#O#......OO.O.#\n...OOO.#O....O#O...O.##OO..#....OO...O.#.....OO.#OOO.#.........#....O....#.#..O.#O#.#...O.O...O.#...\n..O.#.OOO..O.#...#OO.#.O.##OO..O..####.#....#.OO##O..#.O..O#..O#....#..O#..#.O.O..O...O...O.....O.O.\n.#.#O.O..#.O.O##.....O#..#..#..OO##...OOO.#O...#.O#...#O....#OO.OO..#.OO#.OO#O#............O......#.\nO#..#....O...#.#.O....#.OOO.#.OO.....OO###.O..#..#.O..#...#.#....O#.O#....#.#.O.#.....#....O.....O#.\nO..O.#.....#.....OOO..O..OOO.#..#.##.O..O.......#..O.##O#...#.#.......#.#....#.O.O..OO..#.O..#..O#O.\n...O...O#....#O.......#........#.O.O..O.#O#...O...#..O.#..OO#O...#........O...#.....OO.#...#.O...#.#\nO.#.O#...O#....#OO.O.##......O...##..#..O#.#.#O.....OOO..#O....#...O..O#O....#.#....OO.#..#.....OO.#\n...O#..O.#.#..O........O.....#.........#.....O.......O......#..#.#O....#O.O#O.#..##O#....#O...O.O...\n#..O.O...O#..O.O.#O..#...O#....#..#...O..#O...O.....O..OO#OOO#OOO...#.O...#.OO#O.....#O.#.........O.\nO.O...#....O#OO...O.OO..#..OO...#..O..O.O....#...#..O..OOO#.....#..OO.#O....O.#.O.OOO.#OO....##OO..O\n.#O#.#.##...###O..O#...#.O.#.O...O#.O.....O....O..OOO....#...O...OO.....#.#O#O..#O......#.O.....#.#O\nO.#O.OO......##......O..OOO##.OOO.#..O...O.O#..#O.#O.O......#................##..#....#O......#.....\n........#.....##...OO.O......#..#.......#O.....O....O....#O.##..OO...O...O..........#..O.....OO...#.\n#..O.#.......O......O#.O..........#O#.O#.#..#..O..O#.O.O..O.O........O......O..O.O..O.O..#O....O#.#.\n...#...OO#..#..##.O.....O...........O.#O#O...##...O..#..#..O....#..O#O.##..O##......OOO....##..###.#\n.#..#....OOO......O#O...##O..O.OO...O..#.....#.O..##...." <> ...}
+
```
+
+
```elixir
+
puzzle_input =
+
"""
+
O....#....
+
O.OO#....#
+
.....##...
+
OO.#O....O
+
.O.....O#.
+
O.#..O.#.#
+
..O..#O..O
+
.......O..
+
#....###..
+
#OO..#....
+
"""
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
"O....#....\nO.OO#....#\n.....##...\nOO.#O....O\n.O.....O#.\nO.#..O.#.#\n..O..#O..O\n.......O..\n#....###..\n#OO..#....\n"
+
```
+
+
```elixir
+
map =
+
puzzle_input
+
|> String.split("\n", trim: true)
+
|> Enum.with_index(0)
+
|> Enum.flat_map(fn {line, y} ->
+
line
+
|> String.to_charlist()
+
|> Enum.with_index()
+
|> Enum.filter(fn {p, _} -> p != ?. end)
+
|> Enum.map(fn
+
{?#, x} -> {{x, y}, :cube}
+
{?O, x} -> {{x, y}, :round}
+
end)
+
end)
+
|> Map.new()
+
+
{width, height} = Enum.reduce(map, {0, 0}, fn {{x, y}, _}, {w, h} -> {max(x, w), max(y, h)} end)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{9, 9}
+
```
+
+
## Part 1
+
+
```elixir
+
defmodule Day14 do
+
def weight(map, width, height) do
+
for(col <- 0..width, do: Day14.column_weight(map, col, height))
+
|> Enum.sum()
+
end
+
+
def column_weight(map, col, height) do
+
do_column_weight(map, col, height, 0, 0, height)
+
end
+
+
defp do_column_weight(_map, _col, -1, stack, sum, height) do
+
sum + sum(height + 1, stack)
+
end
+
+
defp do_column_weight(map, col, row, stack, sum, height) do
+
case Map.fetch(map, {col, row}) do
+
:error ->
+
do_column_weight(map, col, row - 1, stack, sum, height)
+
+
{:ok, :cube} ->
+
do_column_weight(map, col, row - 1, 0, sum + sum(height - row, stack), height)
+
+
{:ok, :round} ->
+
do_column_weight(map, col, row - 1, stack + 1, sum, height)
+
end
+
end
+
+
def sum(_, 0), do: 0
+
def sum(s, n), do: div((2 * s - n + 1) * n, 2)
+
+
def print(map, width, height) do
+
for y <- 0..height do
+
row =
+
for x <- 0..width do
+
case Map.get(map, {x, y}) do
+
nil -> "โ€ƒ"
+
:cube -> "#"
+
:round -> "O"
+
end
+
end
+
+
["#{y}\t", row, "\n"]
+
end
+
|> IO.puts()
+
end
+
end
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:module, Day14, <<70, 79, 82, 49, 0, 0, 15, ...>>, {:print, 3}}
+
```
+
+
```elixir
+
Day14.print(map, width, height)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
0 Oโ€ƒโ€ƒโ€ƒโ€ƒ#โ€ƒโ€ƒโ€ƒโ€ƒ
+
1 Oโ€ƒOO#โ€ƒโ€ƒโ€ƒโ€ƒ#
+
2 โ€ƒโ€ƒโ€ƒโ€ƒโ€ƒ##โ€ƒโ€ƒโ€ƒ
+
3 OOโ€ƒ#Oโ€ƒโ€ƒโ€ƒโ€ƒO
+
4 โ€ƒOโ€ƒโ€ƒโ€ƒโ€ƒโ€ƒO#โ€ƒ
+
5 Oโ€ƒ#โ€ƒโ€ƒOโ€ƒ#โ€ƒ#
+
6 โ€ƒโ€ƒOโ€ƒโ€ƒ#Oโ€ƒโ€ƒO
+
7 โ€ƒโ€ƒโ€ƒโ€ƒโ€ƒโ€ƒโ€ƒOโ€ƒโ€ƒ
+
8 #โ€ƒโ€ƒโ€ƒโ€ƒ###โ€ƒโ€ƒ
+
9 #OOโ€ƒโ€ƒ#โ€ƒโ€ƒโ€ƒโ€ƒ
+
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
:ok
+
```
+
+
```elixir
+
Day14.weight(map, width, height)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
136
+
```
+
+
## Part 2
+
+
```elixir
+
defmodule Day14.Part2 do
+
def round(map, width, height) do
+
map
+
|> move(width, height)
+
|> rotate(height)
+
|> move(height, width)
+
|> rotate(width)
+
|> move(width, height)
+
|> rotate(height)
+
|> move(height, width)
+
|> rotate(width)
+
end
+
+
def move(map, width, height) do
+
for(x <- 0..width, col = move_column(map, x, height), c <- col, into: %{}, do: c)
+
end
+
+
def move_column(map, col, height) do
+
do_move(map, col, height, 0, [])
+
end
+
+
defp do_move(_map, col, -1, stack, acc) do
+
expand_stack(0, col, stack) ++ acc
+
end
+
+
defp do_move(map, col, row, stack, acc) do
+
case Map.fetch(map, {col, row}) do
+
:error ->
+
do_move(map, col, row - 1, stack, acc)
+
+
{:ok, :cube} ->
+
do_move(
+
map,
+
col,
+
row - 1,
+
0,
+
expand_stack(row + 1, col, stack) ++ [{{col, row}, :cube} | acc]
+
)
+
+
{:ok, :round} ->
+
do_move(map, col, row - 1, stack + 1, acc)
+
end
+
end
+
+
defp expand_stack(start, col, len) do
+
for y <- 0..(len - 1)//1, do: {{col, start + y}, :round}
+
end
+
+
def rotate(map, height) do
+
Map.new(map, fn {{x, y}, v} ->
+
{{height - y, x}, v}
+
end)
+
end
+
+
def rounds_with_memoisation(map, width, height) do
+
Stream.iterate(map, &round(&1, width, height))
+
end
+
end
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:module, Day14.Part2, <<70, 79, 82, 49, 0, 0, 17, ...>>, {:rounds_with_memoisation, 3}}
+
```
+
+
```elixir
+
{nmap, _, _} =
+
Day14.Part2.rounds_with_memoisation(map, width, height)
+
|> Stream.with_index()
+
|> Enum.reduce_while(%{}, fn {map, idx}, set ->
+
case Map.fetch(set, map) do
+
:error -> {:cont, Map.put(set, map, idx)}
+
{:ok, prev} -> {:halt, {map, idx, prev}}
+
end
+
end)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{%{
+
{9, 8} => :round,
+
{4, 6} => :round,
+
{9, 9} => :round,
+
{7, 7} => :round,
+
{9, 7} => :round,
+
{1, 5} => :round,
+
{7, 5} => :cube,
+
{8, 1} => :round,
+
{0, 8} => :cube,
+
{9, 5} => :cube,
+
{4, 1} => :cube,
+
{9, 6} => :round,
+
{5, 9} => :cube,
+
{8, 7} => :round,
+
{6, 4} => :round,
+
{5, 4} => :round,
+
{9, 1} => :cube,
+
{5, 6} => :cube,
+
{5, 2} => :cube,
+
{4, 9} => :round,
+
{2, 5} => :cube,
+
{3, 9} => :round,
+
{0, 9} => :cube,
+
{4, 8} => :round,
+
{6, 2} => :cube,
+
{7, 8} => :cube,
+
{6, 5} => :round,
+
{6, 8} => :cube,
+
{2, 3} => :round,
+
{5, 0} => :cube,
+
{5, 8} => :cube,
+
{7, 4} => :round,
+
{3, 3} => :cube,
+
{8, 4} => :cube,
+
{2, 9} => :round
+
}, 10, 3}
+
```
+
+
```elixir
+
Day14.Part2.rounds_with_memoisation(map, width, height)
+
|> Enum.take(11)
+
|> Stream.each(&Day14.print(&1, width, height))
+
|> Enum.map(&Day14.weight(&1, width, height))
+
|> IO.inspect(charlists: :as_lists)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
0 Oโ€ƒโ€ƒโ€ƒโ€ƒ#โ€ƒโ€ƒโ€ƒโ€ƒ
+
1 Oโ€ƒOO#โ€ƒโ€ƒโ€ƒโ€ƒ#
+
2 โ€ƒโ€ƒโ€ƒโ€ƒโ€ƒ##โ€ƒโ€ƒโ€ƒ
+
3 OOโ€ƒ#Oโ€ƒโ€ƒโ€ƒโ€ƒO
+
4 โ€ƒOโ€ƒโ€ƒโ€ƒโ€ƒโ€ƒO#โ€ƒ
+
5 Oโ€ƒ#โ€ƒโ€ƒOโ€ƒ#โ€ƒ#
+
6 โ€ƒโ€ƒOโ€ƒโ€ƒ#Oโ€ƒโ€ƒO
+
7 โ€ƒโ€ƒโ€ƒโ€ƒโ€ƒโ€ƒโ€ƒOโ€ƒโ€ƒ
+
8 #โ€ƒโ€ƒโ€ƒโ€ƒ###โ€ƒโ€ƒ
+
9 #OOโ€ƒโ€ƒ#โ€ƒโ€ƒโ€ƒโ€ƒ
+
+
0 โ€ƒโ€ƒโ€ƒโ€ƒโ€ƒ#โ€ƒโ€ƒโ€ƒโ€ƒ
+
1 โ€ƒโ€ƒโ€ƒโ€ƒ#โ€ƒโ€ƒโ€ƒO#
+
2 โ€ƒโ€ƒโ€ƒOO##โ€ƒโ€ƒโ€ƒ
+
3 โ€ƒOO#โ€ƒโ€ƒโ€ƒโ€ƒโ€ƒโ€ƒ
+
4 โ€ƒโ€ƒโ€ƒโ€ƒโ€ƒOOO#โ€ƒ
+
5 โ€ƒO#โ€ƒโ€ƒโ€ƒO#โ€ƒ#
+
6 โ€ƒโ€ƒโ€ƒโ€ƒO#โ€ƒโ€ƒโ€ƒโ€ƒ
+
7 โ€ƒโ€ƒโ€ƒโ€ƒโ€ƒโ€ƒOOOO
+
8 #โ€ƒโ€ƒโ€ƒO###โ€ƒโ€ƒ
+
9 #โ€ƒโ€ƒOO#โ€ƒโ€ƒโ€ƒโ€ƒ
+
+
0 โ€ƒโ€ƒโ€ƒโ€ƒโ€ƒ#โ€ƒโ€ƒโ€ƒโ€ƒ
+
1 โ€ƒโ€ƒโ€ƒโ€ƒ#โ€ƒโ€ƒโ€ƒO#
+
2 โ€ƒโ€ƒโ€ƒโ€ƒโ€ƒ##โ€ƒโ€ƒโ€ƒ
+
3 โ€ƒโ€ƒO#โ€ƒโ€ƒโ€ƒโ€ƒโ€ƒโ€ƒ
+
4 โ€ƒโ€ƒโ€ƒโ€ƒโ€ƒOOO#โ€ƒ
+
5 โ€ƒO#โ€ƒโ€ƒโ€ƒO#โ€ƒ#
+
6 โ€ƒโ€ƒโ€ƒโ€ƒO#โ€ƒโ€ƒโ€ƒO
+
7 โ€ƒโ€ƒโ€ƒโ€ƒโ€ƒโ€ƒโ€ƒOOO
+
8 #โ€ƒโ€ƒOO###โ€ƒโ€ƒ
+
9 #โ€ƒOOO#โ€ƒโ€ƒโ€ƒO
+
+
0 โ€ƒโ€ƒโ€ƒโ€ƒโ€ƒ#โ€ƒโ€ƒโ€ƒโ€ƒ
+
1 โ€ƒโ€ƒโ€ƒโ€ƒ#โ€ƒโ€ƒโ€ƒO#
+
2 โ€ƒโ€ƒโ€ƒโ€ƒโ€ƒ##โ€ƒโ€ƒโ€ƒ
+
3 โ€ƒโ€ƒO#โ€ƒโ€ƒโ€ƒโ€ƒโ€ƒโ€ƒ
+
4 โ€ƒโ€ƒโ€ƒโ€ƒโ€ƒOOO#โ€ƒ
+
5 โ€ƒO#โ€ƒโ€ƒโ€ƒO#โ€ƒ#
+
6 โ€ƒโ€ƒโ€ƒโ€ƒO#โ€ƒโ€ƒโ€ƒO
+
7 โ€ƒโ€ƒโ€ƒโ€ƒโ€ƒโ€ƒโ€ƒOOO
+
8 #โ€ƒโ€ƒโ€ƒO###โ€ƒO
+
9 #โ€ƒOOO#โ€ƒโ€ƒโ€ƒO
+
+
0 โ€ƒโ€ƒโ€ƒโ€ƒโ€ƒ#โ€ƒโ€ƒโ€ƒโ€ƒ
+
1 โ€ƒโ€ƒโ€ƒโ€ƒ#โ€ƒโ€ƒโ€ƒO#
+
2 โ€ƒโ€ƒโ€ƒโ€ƒโ€ƒ##โ€ƒโ€ƒโ€ƒ
+
3 โ€ƒโ€ƒO#โ€ƒโ€ƒโ€ƒโ€ƒโ€ƒโ€ƒ
+
4 โ€ƒโ€ƒโ€ƒโ€ƒโ€ƒOOO#โ€ƒ
+
5 โ€ƒO#โ€ƒโ€ƒโ€ƒO#โ€ƒ#
+
6 โ€ƒโ€ƒโ€ƒโ€ƒO#โ€ƒโ€ƒโ€ƒO
+
7 โ€ƒโ€ƒโ€ƒโ€ƒโ€ƒโ€ƒโ€ƒOOO
+
8 #โ€ƒโ€ƒโ€ƒO###โ€ƒO
+
9 #โ€ƒโ€ƒOO#โ€ƒโ€ƒOO
+
+
0 โ€ƒโ€ƒโ€ƒโ€ƒโ€ƒ#โ€ƒโ€ƒโ€ƒโ€ƒ
+
1 โ€ƒโ€ƒโ€ƒโ€ƒ#โ€ƒโ€ƒโ€ƒO#
+
2 โ€ƒโ€ƒโ€ƒโ€ƒโ€ƒ##โ€ƒโ€ƒโ€ƒ
+
3 โ€ƒโ€ƒโ€ƒ#โ€ƒโ€ƒโ€ƒโ€ƒโ€ƒโ€ƒ
+
4 โ€ƒโ€ƒโ€ƒโ€ƒโ€ƒOOO#โ€ƒ
+
5 โ€ƒO#โ€ƒโ€ƒโ€ƒO#โ€ƒ#
+
6 โ€ƒโ€ƒโ€ƒโ€ƒO#โ€ƒโ€ƒโ€ƒO
+
7 โ€ƒโ€ƒโ€ƒโ€ƒโ€ƒโ€ƒOOOO
+
8 #โ€ƒโ€ƒโ€ƒO###โ€ƒO
+
9 #โ€ƒโ€ƒOO#โ€ƒโ€ƒOO
+
+
0 โ€ƒโ€ƒโ€ƒโ€ƒโ€ƒ#โ€ƒโ€ƒโ€ƒโ€ƒ
+
1 โ€ƒโ€ƒโ€ƒโ€ƒ#โ€ƒโ€ƒโ€ƒO#
+
2 โ€ƒโ€ƒโ€ƒโ€ƒโ€ƒ##โ€ƒโ€ƒโ€ƒ
+
3 โ€ƒโ€ƒโ€ƒ#โ€ƒโ€ƒโ€ƒโ€ƒโ€ƒโ€ƒ
+
4 โ€ƒโ€ƒโ€ƒโ€ƒโ€ƒOOO#โ€ƒ
+
5 โ€ƒO#โ€ƒโ€ƒโ€ƒO#โ€ƒ#
+
6 โ€ƒโ€ƒโ€ƒโ€ƒO#โ€ƒโ€ƒโ€ƒO
+
7 โ€ƒโ€ƒโ€ƒโ€ƒโ€ƒโ€ƒOOOO
+
8 #โ€ƒโ€ƒโ€ƒโ€ƒ###โ€ƒO
+
9 #โ€ƒOOO#โ€ƒโ€ƒOO
+
+
0 โ€ƒโ€ƒโ€ƒโ€ƒโ€ƒ#โ€ƒโ€ƒโ€ƒโ€ƒ
+
1 โ€ƒโ€ƒโ€ƒโ€ƒ#โ€ƒโ€ƒโ€ƒO#
+
2 โ€ƒโ€ƒโ€ƒโ€ƒโ€ƒ##โ€ƒโ€ƒโ€ƒ
+
3 โ€ƒโ€ƒO#โ€ƒโ€ƒโ€ƒโ€ƒโ€ƒโ€ƒ
+
4 โ€ƒโ€ƒโ€ƒโ€ƒโ€ƒโ€ƒOO#โ€ƒ
+
5 โ€ƒO#โ€ƒโ€ƒโ€ƒO#โ€ƒ#
+
6 โ€ƒโ€ƒโ€ƒโ€ƒO#โ€ƒโ€ƒโ€ƒO
+
7 โ€ƒโ€ƒโ€ƒโ€ƒโ€ƒโ€ƒOOOO
+
8 #โ€ƒโ€ƒโ€ƒโ€ƒ###โ€ƒO
+
9 #โ€ƒOOO#โ€ƒโ€ƒOO
+
+
0 โ€ƒโ€ƒโ€ƒโ€ƒโ€ƒ#โ€ƒโ€ƒโ€ƒโ€ƒ
+
1 โ€ƒโ€ƒโ€ƒโ€ƒ#โ€ƒโ€ƒโ€ƒO#
+
2 โ€ƒโ€ƒโ€ƒโ€ƒโ€ƒ##โ€ƒโ€ƒโ€ƒ
+
3 โ€ƒโ€ƒO#โ€ƒโ€ƒโ€ƒโ€ƒโ€ƒโ€ƒ
+
4 โ€ƒโ€ƒโ€ƒโ€ƒโ€ƒโ€ƒOO#โ€ƒ
+
5 โ€ƒO#โ€ƒโ€ƒโ€ƒO#โ€ƒ#
+
6 โ€ƒโ€ƒโ€ƒโ€ƒO#โ€ƒโ€ƒโ€ƒโ€ƒ
+
7 โ€ƒโ€ƒโ€ƒโ€ƒโ€ƒโ€ƒOOOO
+
8 #โ€ƒโ€ƒโ€ƒO###โ€ƒO
+
9 #โ€ƒOOO#โ€ƒโ€ƒOO
+
+
0 โ€ƒโ€ƒโ€ƒโ€ƒโ€ƒ#โ€ƒโ€ƒโ€ƒโ€ƒ
+
1 โ€ƒโ€ƒโ€ƒโ€ƒ#โ€ƒโ€ƒโ€ƒO#
+
2 โ€ƒโ€ƒโ€ƒโ€ƒโ€ƒ##โ€ƒโ€ƒโ€ƒ
+
3 โ€ƒโ€ƒO#โ€ƒโ€ƒโ€ƒโ€ƒโ€ƒโ€ƒ
+
4 โ€ƒโ€ƒโ€ƒโ€ƒโ€ƒOOO#โ€ƒ
+
5 โ€ƒO#โ€ƒโ€ƒโ€ƒO#โ€ƒ#
+
6 โ€ƒโ€ƒโ€ƒโ€ƒO#โ€ƒโ€ƒโ€ƒโ€ƒ
+
7 โ€ƒโ€ƒโ€ƒโ€ƒโ€ƒโ€ƒOOOO
+
8 #โ€ƒโ€ƒโ€ƒO###โ€ƒO
+
9 #โ€ƒOOO#โ€ƒโ€ƒโ€ƒO
+
+
0 โ€ƒโ€ƒโ€ƒโ€ƒโ€ƒ#โ€ƒโ€ƒโ€ƒโ€ƒ
+
1 โ€ƒโ€ƒโ€ƒโ€ƒ#โ€ƒโ€ƒโ€ƒO#
+
2 โ€ƒโ€ƒโ€ƒโ€ƒโ€ƒ##โ€ƒโ€ƒโ€ƒ
+
3 โ€ƒโ€ƒO#โ€ƒโ€ƒโ€ƒโ€ƒโ€ƒโ€ƒ
+
4 โ€ƒโ€ƒโ€ƒโ€ƒโ€ƒOOO#โ€ƒ
+
5 โ€ƒO#โ€ƒโ€ƒโ€ƒO#โ€ƒ#
+
6 โ€ƒโ€ƒโ€ƒโ€ƒO#โ€ƒโ€ƒโ€ƒO
+
7 โ€ƒโ€ƒโ€ƒโ€ƒโ€ƒโ€ƒโ€ƒOOO
+
8 #โ€ƒโ€ƒโ€ƒO###โ€ƒO
+
9 #โ€ƒOOO#โ€ƒโ€ƒโ€ƒO
+
+
[136, 129, 114, 110, 110, 105, 103, 106, 111, 114, 110]
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
[136, 129, 114, 110, 110, 105, 103, 106, 111, 114, 110]
+
```
+
+
<!-- livebook:{"offset":13089,"stamp":{"token":"XCP.6NDtt8fJ01JLOq3nTevL25H4mHLTDc6Od4j4bkK8EzYDIEbnkcC_afNOcboznLxeJd_Vr-eQOTfSeVj0rfhlPWRbNSo_OLjTWZxTnB_TdqgAr5J0iWjRjf2BDccO40DsHw","version":2}} -->
+130
2023/day15.livemd
···
+
<!-- livebook:{"persist_outputs":true} -->
+
+
# Day 15
+
+
```elixir
+
Mix.install([:kino_aoc])
+
```
+
+
## Section
+
+
<!-- livebook:{"attrs":{"assign_to":"puzzle_input","day":"15","session_secret":"ADVENT_OF_CODE_SESSION","year":"2023"},"chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2023", "15", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:ok,
+
"kv-,lmv-,zlg=4,hn=2,qp=8,dxd-,pk=3,pxfnc-,jgjch-,dp=3,lffh-,sprsl=1,hns=6,fl=1,hn-,ltgg-,hl-,gx-,sv-,lz-,qqxd-,jxgxjv-,hvlh=2,tnf=8,sprsl=1,tbxjmh=7,cv=3,zl-,tbcz=3,gcknh=6,jqzcc=2,gdx-,kqfg=5,lrc=1,gqq-,ztl-,cct-,ktb=8,vs-,cnpx=4,hsq=3,ht-,nb-,mqv=1,vvhsz-,bhqq=6,tdc=6,zf=6,qxh=6,th-,ltl-,rpk=9,krn=3,mqh=9,zt-,hm=9,tbxjmh=7,rmc-,qvsq=9,gdr-,czq-,jk-,lnrsql=7,fqqz-,kfrtbv-,bmm=7,psxz=3,qkr=7,ckf=5,dl-,psfh-,qqrmbj=5,tnvl-,ffnx-,ttd-,tg-,hhhk-,qx-,ldx=1,gr=6,tvj-,jqzcc=4,gvk=3,nft=2,rc=4,hk=5,tbxjmh=8,mlxs-,lmv=3,ht=7,jgb-,tbxjmh-,gmfc=2,bxg-,tmqp-,gld-,kcvf-,ggdr-,psxz=1,lt-,cm-,pxfnc-,sdmhxq-,brr=6,bjv-,th-,td=1,jsvc-,rkjbzv=1,cbbq-,nqpsc-,cgvvt-,vtm-,vk=3,tjr=9,pbm=7,gjl-,fkrl-,js=2,zjn=2,sprsl=9,rk=7,hpd=8,bgmhj-,czq-,xxcfk=9,qdxb-,ns=1,mx-,dhs-,xf-,ttd=9,tvj=8,kng-,hm-,rpk=5,hrk-,lpbk-,lbzxd=8,vmcj-,mmb-,ks-,ks=6,mx=6,xq=8,mkn-,cnpx-,rx=3,vfpj-,zl-,tgt=4,krn=7,hmr=4,gcknh-,rg=9,nb=3,jc-,qdxb=2,lffh-,ksclkb=6,pxrflz-,kkxp-,tbcz-,zt-,ltn-,rmc=1,cpscb-,zsrpq-,snnd-,kg=6,fbhvr-,kng=9,mck=3,xtz=7,bbsn=9,ht=9,zgq-,bh-,spv=5,rjg=7,tsc=1,dbvmr=3,hk-,nkg-,vzlvs-,bcxgj=1,sqhb=6,tv-,tlt-,vqm=4,vmcj=6,rx=3,hmr-,jzpt-,pmq-,hrk-,jx=2,bq=4,dxn=3,tgsr-,xlkg-,nrj-,lz-,bnlk=2,jxp=1,hfztr=8,gt=2,lgn=7,dpmt-,xj-,pj-,nzx-,jn=8,hpd-,dfgm-,qkr-,qqrmbj=1,tpn=5,rc=8,hnhm=1,vzlvs=6,bt=8,mhzf=2,hrk-,vzlvs-,sfg-,jzpt-,jqzcc=3,vvt-,ffnx=6,btt-,pbm-,hzkpq-,gdr-,mx=6,rn=9,qkr=6,ks-,zf-,nkg=2,ptrtg-,dxn-,xf-,cv-,vf=5,qk=4,zlg=8,sfg=3,sn-,hsq=5,tg=8,dn=2,jn=1,spv=9,hhhk=9,nkc=7,rm=3,hrhmdx-,zdtxcq=3,chb-,jxb-,psfh=9,pn-,jgb=2,clh=9,crg-,vgxg-,kq=3,qfz=6,rq=3,qvz=2,dl-,vtm-,rn-,kng=5,jv-,cgz=7,fff=7,gmfc=6,jgb=4,zf-,bt-,lqkmtd-,xlv=3,pjn=6,bstf-,rn-,kb-,tcp-,bx-,gkj-,vpp-,fznq-,xlg=8,qdq=2,hk=1,gdr=6,qd-,nsc=3,vfpj=7,qjjnq-,sstlb-,zs=6,qhm-,pmq-,gqblq-,pnnd=9,ztl=1,bmmdqk-,fkpd-,mm-,gs-,bnlk-,sstlb-,ct=6,hstx-,khq=9,gjd=3,fbhvr-,qqxd-,hrhmdx-,vnj=3,lrc-,hnhm=7,lsr=4,gqblq-,sprsl=7,gfm-,dg-,fmf=5,tsc=9,sz=1,tpn=6,gld-,rmc=4,spv-,xhs=2,hn-,sfv=8,rhg-,dd-,fzl-,hlq=3,czq=4,nvm-,fhgz=1,jzrz=4,jntz-,jj=2,rpk=8,bjv=3,lgn=7,hzj-,xhd=8,nnx-,gdr-,hzls=9,kdt-,vvt-,bgmhj=1,ldx=7,tcp-,kntk=9,brv-,xd=6,cn-,pdb-,jk-,qh-,vmcj-,jj=6,dn=9,mdzv-,pvk=4,gmfc-,rmj-,sh-,cl=6,pvk=1,mk=7,hx=5,gqq=5,jc-,qf-,tmqp-,srtm-,fqqz=1,rjkvz=4,nff=4,vs=6,zsrpq-,bpkc-,qqxd-,lsbk-,gcknh=9,gmfc-,nxrcnk-,gjl=5,th-,tsc-,pdqkq=6,zk-,zt=6,bp-,hn-,pd=5,jqjdg=6,pjm=7,dh-,mlnc-,psfh-,rm-,nndl=2,tnf=5,gt-,dfm-,rlr=2,pmbfzf-,lt-,vgxg-,xlv-,qr=6,xqst-,pjm-,prj=8,ztgp-,zt-,lrc=2,pln-,bd-,cmnj-,xp=5,cm-,bcqvf=9,gp=8,bd=4,hvlh=4,bpkc=9,ld-,vj-,lnrsql-,vsp-,prj=8,fbhvr-,bd=8,qf=2,zjn-,tbxjmh-,xhs-,kcvf=4,tgsr=4,zk-,sxz-,hmr=4,pj=9,hl-,sgl-,jz-,mbm-,gjl=8,sstlb-,vdd=7,nb=5,snvxq-,fz=3,bh=6,db-,vdd=2,bmmdqk-,qsbf=2,tv=1,prj=5,kqp-,vzlvs-,lplqhd-,tqtqg=5,ddq=4,mmz-,vfdtt=4,vvhsz=8,zq=3,pn=7,lgn-,tzpv-,zqq-,fzc-,rl-,srtm-,tpn-,cl=7,fz=7,tnvl-,dhx-,td-,hzkpq-,kqfg-,xbz=5,rpk-,nbhcs=5,jj-,xp=2,kp=8,rfxck-,vj=8,bvfl-,hft=8,jj=4,qtd-,bcqvf-,dh=3,xt-,mbc-,msd=7,zqq=7,pdqkq-,qr=4,rhg=2,vzlvs=9,dh=2,hrhmdx-,vvt-,zs=8,dxd-,gkxmlj-,tgsr=1,tf=5,qdxb-,kq=7,mlxs-,jjxlh=8,lplqhd-,rjkvz=3,fph=6,lmv-,mdx-,kcvf=5,vtd-,khq-,gqblq-,hzj=1,mkn-,bxg=7,qtd-,bnlk=9,ltn-,vnz=8,mk-,xnrnz=7,skmhp=3,ddq-,rc=5,vnj=6,sz=5,cl=6,qvz=1,vdd=4,hft=6,rmq=9,jntz=5,qs-,zqq-,mqh-,qh-,hh-,dbnrnp-,nrj-,mqv-,rmj-,nqpsc-,tq=5,cnk-,qctz=4,xfdh=9,ptrtg=7,nvm-,xlkg-,psgp=6,ns-,rrxq-,bcxgj-,xhs-,jgmn=6,mcs=9,gs-,kntk-,fp-,xd-,pn=8,tzpv=3,rrxq=4,vdd=1,xhd-,rmj-,mx-,spq=8,qqkv=8,mjpb=5,vgxg=8,sfv-,gld-,qqkv=7,rh-,tj=3,snnd=8,bd-,vgxg=6,kng-,gvk=3,jjxlh=5,jgm=5,qvsq-,nkc-,bqntx-,cfn=6,crg=1,kng-,hvlh-,xtxc=1,qqxd-,fzl=3,hjs=4,nvm-,hzkpq-,rk-,jv-,rjkvz-,cjq-,lkmj-,vtj-,xhp=1,qf=2,cnpx=9,psxz-,mcs-,jx=6,hx-,bt-,nsc=2,qctz-,rx-,kdt-,dbvmr-,ctn=8,lrc-,xmvfk-,xh-,vqm=8,mlnc=4,jgb-,cbbq-,vk-,csg-,jntz-,pcdffj-,xt-,xj-,fp-,bt-,kntk=1,ztl-,qkr-,clh-,bq=8,ztgp-,mk-,xfdh-,ncsm-,zhj-,tlt-,ncsm=1,mbc-,tqtqg-,pb-,bqgs=5,fhgz-,ksb-,lsr-,qvz-,tk=5,hns=5,pbxm=8,ct-,lrc-,flrj-,zd-,pg-,pdqkq=1,gxxk-,ffnx=4,zlg-,ts=5,bgmhj-,jjx=7,vl-,hx=1,jgmn-,lkmj-,rrgf-,qphsv=9,xj=1,cx-,prj=6,jndqj-,dxd=6,mcs-,rhg=2,jk=3,qsn-,jmfhs-,hk-,ts=7,pk=9,vmcj-,nzx-,bt-,mqh-,ctc-,nkg=4,rpk-,pdb=" <> ...}
+
```
+
+
```elixir
+
# puzzle_input = "rn=1,cm-,qp=3,cm=2,qp-,pc=4,ot=9,ab=5,pc-,pc=6,ot=7"
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
nil
+
```
+
+
```elixir
+
defmodule Day15 do
+
def hash(binary) do
+
for <<c <- binary>>, reduce: 0, do: (acc -> Bitwise.band((c + acc) * 17, 0xFF))
+
end
+
end
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:module, Day15, <<70, 79, 82, 49, 0, 0, 7, ...>>, {:hash, 1}}
+
```
+
+
```elixir
+
segments =
+
puzzle_input
+
|> String.split(",")
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
["kv-", "lmv-", "zlg=4", "hn=2", "qp=8", "dxd-", "pk=3", "pxfnc-", "jgjch-", "dp=3", "lffh-",
+
"sprsl=1", "hns=6", "fl=1", "hn-", "ltgg-", "hl-", "gx-", "sv-", "lz-", "qqxd-", "jxgxjv-",
+
"hvlh=2", "tnf=8", "sprsl=1", "tbxjmh=7", "cv=3", "zl-", "tbcz=3", "gcknh=6", "jqzcc=2", "gdx-",
+
"kqfg=5", "lrc=1", "gqq-", "ztl-", "cct-", "ktb=8", "vs-", "cnpx=4", "hsq=3", "ht-", "nb-",
+
"mqv=1", "vvhsz-", "bhqq=6", "tdc=6", "zf=6", "qxh=6", "th-", ...]
+
```
+
+
## Part 1
+
+
```elixir
+
segments
+
|> Enum.map(&Day15.hash/1)
+
|> Enum.sum()
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
506869
+
```
+
+
## Part 2
+
+
```elixir
+
segments
+
|> Enum.map(fn step ->
+
[_, label, action] = Regex.run(~r/([a-z]+)(-|=\d+)/, step)
+
+
box = Day15.hash(label)
+
+
case action do
+
"-" -> {box, label, :rm}
+
"=" <> rest -> {box, label, {:add, String.to_integer(rest)}}
+
end
+
end)
+
|> Enum.reduce(%{}, fn {box, label, action}, map ->
+
curr = map[box] || []
+
+
next =
+
case action do
+
{:add, f} ->
+
if Enum.any?(curr, &(elem(&1, 0) == label)) do
+
List.keyreplace(curr, label, 0, {label, f})
+
else
+
[{label, f} | curr]
+
end
+
+
:rm ->
+
List.keydelete(curr, label, 0)
+
end
+
+
Map.put(map, box, next)
+
end)
+
|> Enum.map(fn {box, lenses} ->
+
box = box + 1
+
+
lenses
+
|> Enum.reverse()
+
|> Enum.with_index(1)
+
|> Enum.map(fn {{_, f}, id} -> box * id * f end)
+
|> Enum.sum()
+
end)
+
|> Enum.sum()
+
|> dbg()
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
271384
+
```
+
+
<!-- livebook:{"offset":6563,"stamp":{"token":"XCP.ikIQAzWaCpMFzPgSppGb8erUqNQTiTQKVT4Z8-snaHPxRPHLJ4FSFvjZQhOg5ALkY4RVu78B3ZYCWSkqZ0vt8iql9ZvmaUtNNTG10v5VUIi3Jt0IgRmOCL0PL47Vn3f_gQ","version":2}} -->
+178
2023/day16.livemd
···
+
<!-- livebook:{"persist_outputs":true} -->
+
+
# Day 16
+
+
```elixir
+
Mix.install([:kino_aoc])
+
```
+
+
## Section
+
+
<!-- livebook:{"attrs":{"assign_to":"puzzle_input","day":"16","session_secret":"ADVENT_OF_CODE_SESSION","year":"2023"},"chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2023", "16", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:ok,
+
"\\\\.......\\.............../-........|......................-......../..................../......./....|........\n\\.................\\....\\...../........|........|....../.\\....-....-..................|../...|...\\./...........\n../...-.....................\\./-.....-.........................../...........\\|......\\......--............/...\n.......|........\\...\\.........../|...../.........../...../..../...../.................\\.././..................\n...........\\|..........-.................|.|.............|.............|....|..|-...........-..-......./......\n.............................-../.......\\.........\\..........................\\.......|....|.........-.........\n..................../......................-......-...................................../...\\...........|.....\n..|..............................\\......................|....-................................................\n..........\\........./.........................|.................../....-|...../............./.....|.........//\n.-./../.................|....................|................../................\\....|..|..../|.......-./....\n................/........................\\...|.....-.....-...-........\\.............../.......-|-./...........\n.......\\|.........|..-.........................|../...../.\\.../............../.........|.....|../........\\....\n..............-./.............../...........................|....-....-..../......\\....-.......\\........./....\n...............././.-.......|/...................../..-..-..\\...\\.-.-..-................../...................\n..-......../.-.......\\..............................\\/....................................-...................\n.........................................\\....\\.........\\.-......-.|.....\\.......................\\............\n./.........\\.-.-/.............................................|/......|........-\\-............................\n-.....................|.........................|..\\..........|..--....\\..\\........./.........................\n...............\\............../............\\.........................-...............|................/....\\..\n.-.........-...........-|......../...............|.........-...-...|....................-.....................\n.\\./...............|......\\..........-..\\.................-...........................././../.-............/.-\n...-/..............-..|........................|..../.......-..........-/...............\\............../......\n|..........-\\..........\\......../.................\\.|.......-............../.......|.................../......\n.....\\...............|................/........\\.....\\..................-.../........................./.......\n..............................-..\\.../.........-..-........-.......-.............-......................|.../.\n.........../../.|.......-/-.|.|...-...............................\\\\./....|................/.\\................\n.........-..............................|.||......................./........\\..-..../.................|...../.\n.............\\...../\\.............../...-......../.....\\.....................................-/........\\..|..\\\n...............-.-../.-./....|.......\\................/...|................................................|.|\n........-.................-.........................-................\\......|.....\\......-........-...........\n|../.......|......\\............|....../..|.......|../.........................................................\n....................................../..\\....\\\\.............\\...................||/.../.../........\\.........\n............./..../....-...|........../-.............\\......................................\\/........-..-....\n.................\\\\...............|\\\\...........\\.........../......-.......-............\\..............-..-..\\\n...|..../..|../..|........./.../.-..............................\\.........-........................|.\\....||..\n......................./..|....-..............................-........................././../................\n../.\\.............//.\\.|..................-.....\\...........|..././............/...................." <> ...}
+
```
+
+
```elixir
+
# puzzle_input =
+
~S"""
+
.|...\....
+
|.-.\.....
+
.....|-...
+
........|.
+
..........
+
.........\
+
..../.\\..
+
.-.-/..|..
+
.|....-|.\
+
..//.|....
+
"""
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
".|...\\....\n|.-.\\.....\n.....|-...\n........|.\n..........\n.........\\\n..../.\\\\..\n.-.-/..|..\n.|....-|.\\\n..//.|....\n"
+
```
+
+
```elixir
+
lines = String.split(puzzle_input, "\n", trim: true)
+
+
map =
+
for {line, y} <- Enum.with_index(lines),
+
{char, x} <- line |> String.to_charlist() |> Enum.with_index(),
+
char not in ~c".",
+
into: %{},
+
do: {{y, x}, <<char>>}
+
+
{height, width} = {byte_size(hd(lines)) - 1, length(lines) - 1}
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{109, 109}
+
```
+
+
```elixir
+
defmodule Day16 do
+
defguard in_map(yx, hw) when elem(yx, 0) in 0..elem(hw, 0) and elem(yx, 1) in 0..elem(hw, 1)
+
+
def traverse(map, wh, start \\ {{0, 0}, :right}),
+
do: do_traverse(map, wh, start, _acc = MapSet.new(), _visited = MapSet.new())
+
+
defp do_traverse(map, hw, {xy, dir} = pos, acc, visited) when in_map(xy, hw) do
+
if pos not in visited do
+
acc = MapSet.put(acc, xy)
+
+
case Map.fetch(map, xy) do
+
:error ->
+
do_traverse(map, hw, next(xy, dir), acc, visited)
+
+
{:ok, "|"} when dir in ~w[up down]a ->
+
do_traverse(map, hw, next(xy, dir), acc, visited)
+
+
{:ok, "-"} when dir in ~w[left right]a ->
+
do_traverse(map, hw, next(xy, dir), acc, visited)
+
+
{:ok, mirror} when mirror in ~w[/ \\] ->
+
next = mirror(mirror, dir)
+
do_traverse(map, hw, next(xy, next), acc, MapSet.put(visited, pos))
+
+
{:ok, "|"} when dir in ~w[left right]a ->
+
# Add both sides to visited, as it will result in the same outcome
+
visited =
+
visited
+
|> MapSet.put({xy, :left})
+
|> MapSet.put({xy, :right})
+
+
{acc, visited} = do_traverse(map, hw, next(xy, :up), acc, visited)
+
do_traverse(map, hw, next(xy, :down), acc, visited)
+
+
{:ok, "-"} when dir in ~w[up down]a ->
+
# Add both sides to visited, as it will result in the same outcome
+
visited =
+
visited
+
|> MapSet.put({xy, :up})
+
|> MapSet.put({xy, :down})
+
+
{acc, visited} = do_traverse(map, hw, next(xy, :left), acc, visited)
+
do_traverse(map, hw, next(xy, :right), acc, visited)
+
end
+
else
+
{acc, visited}
+
end
+
end
+
+
defp do_traverse(_, _wh, _pos, acc, visited) do
+
{acc, visited}
+
end
+
+
defp mirror("/", :up), do: :right
+
defp mirror("/", :left), do: :down
+
defp mirror("/", :down), do: :left
+
defp mirror("/", :right), do: :up
+
+
defp mirror("\\", :up), do: :left
+
defp mirror("\\", :left), do: :up
+
defp mirror("\\", :down), do: :right
+
defp mirror("\\", :right), do: :down
+
+
defp next({y, x}, :up), do: {{y - 1, x}, :up}
+
defp next({y, x}, :left), do: {{y, x - 1}, :left}
+
defp next({y, x}, :down), do: {{y + 1, x}, :down}
+
defp next({y, x}, :right), do: {{y, x + 1}, :right}
+
end
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:module, Day16, <<70, 79, 82, 49, 0, 0, 28, ...>>, {:next, 2}}
+
```
+
+
## Part 1
+
+
```elixir
+
{path, _} = Day16.traverse(map, {height, width})
+
+
MapSet.size(path)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
7242
+
```
+
+
## Part 2
+
+
```elixir
+
start_points =
+
Enum.concat([
+
Enum.flat_map(0..height, &[{{&1, 0}, :right}, {{&1, width}, :left}]),
+
Enum.flat_map(0..width, &[{{0, &1}, :down}, {{height, &1}, :up}])
+
])
+
+
start_points
+
|> Task.async_stream(&Day16.traverse(map, {height, width}, &1))
+
|> Stream.map(fn {:ok, {path, _}} -> MapSet.size(path) end)
+
|> Enum.max()
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
7572
+
```
+
+
<!-- livebook:{"offset":8394,"stamp":{"token":"XCP.G2qkGI0iiEpXKpxgmF3X_dOzQWYnfJes3P9XQazzqVafzbVljgd42sRxbC_RC5Nc9-rrcx45UodmXf17HwB9X_4sZz6up_iLXNZDUxXQ0eGyvZkk_NcBMt5FRaALMHBiHw","version":2}} -->
+310
2023/day18.livemd
···
+
<!-- livebook:{"persist_outputs":true} -->
+
+
# Day 18
+
+
```elixir
+
Mix.install([:kino_aoc])
+
```
+
+
## Section
+
+
<!-- livebook:{"attrs":{"assign_to":"puzzle_input","day":"18","session_secret":"ADVENT_OF_CODE_SESSION","year":"2023"},"chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2023", "18", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:ok,
+
"L 5 (#0760b2)\nU 4 (#058b53)\nL 3 (#d05a12)\nD 4 (#058b51)\nL 6 (#12ee82)\nU 6 (#63c403)\nL 4 (#065a12)\nU 8 (#a44373)\nL 7 (#7581c2)\nU 7 (#334ec3)\nL 3 (#35e792)\nU 5 (#079963)\nL 3 (#1737b0)\nU 4 (#29a7a3)\nL 2 (#705a02)\nU 5 (#7151e3)\nL 4 (#705a00)\nU 4 (#43f5a3)\nL 5 (#1737b2)\nU 8 (#61a8c3)\nL 5 (#6005d2)\nD 3 (#20f4c1)\nL 3 (#4aa812)\nD 3 (#8163b1)\nL 4 (#80ac22)\nD 4 (#5e64c1)\nL 7 (#cb5430)\nD 5 (#7ac2d1)\nR 7 (#920132)\nD 6 (#a44371)\nL 6 (#944582)\nU 3 (#bc3423)\nL 5 (#71c1b2)\nU 4 (#88e6f3)\nL 4 (#0e35f2)\nU 5 (#11fa31)\nL 8 (#6ab312)\nU 5 (#5c3df1)\nR 8 (#40be22)\nU 3 (#5c3df3)\nR 9 (#42e412)\nU 6 (#11fa33)\nR 5 (#178f02)\nU 10 (#88e6f1)\nL 2 (#cff5f2)\nU 6 (#41fb73)\nL 5 (#247782)\nU 4 (#8d6d73)\nL 5 (#139492)\nU 8 (#6360d3)\nR 4 (#1688c2)\nU 2 (#28eb43)\nR 5 (#7d6230)\nU 6 (#769093)\nR 3 (#7d6232)\nU 5 (#487383)\nL 5 (#4fe4c2)\nU 4 (#784971)\nL 7 (#649a42)\nU 3 (#81c8d1)\nL 6 (#3e8422)\nU 5 (#2e26f3)\nL 5 (#880bd2)\nU 4 (#cbeb53)\nL 6 (#3c3a82)\nU 3 (#990203)\nL 8 (#18ce92)\nU 6 (#3bd723)\nL 10 (#8b17c2)\nU 5 (#931f03)\nR 7 (#56b4b2)\nU 3 (#1c3d03)\nR 2 (#693490)\nU 7 (#a5d813)\nL 4 (#693492)\nU 7 (#454523)\nR 8 (#749e20)\nU 3 (#b6ecd3)\nL 8 (#1e69b0)\nU 6 (#0cd813)\nR 4 (#a286d0)\nU 8 (#8249a3)\nR 6 (#c431e0)\nU 10 (#64b5d3)\nR 3 (#26fee0)\nU 7 (#3a6403)\nR 7 (#44c0a2)\nU 8 (#574291)\nR 2 (#9bf502)\nU 5 (#574293)\nR 5 (#0a7b22)\nU 8 (#12e553)\nR 2 (#67c0e0)\nU 3 (#ab6f63)\nR 7 (#922b60)\nD 6 (#680283)\nR 5 (#637c90)\nD 5 (#b10343)\nR 3 (#954ed0)\nD 8 (#254333)\nL 8 (#3f16a0)\nD 3 (#55f2c3)\nR 4 (#2465e0)\nD 9 (#6b7461)\nR 6 (#8b2b00)\nD 7 (#6b7463)\nR 5 (#7ae9f0)\nD 3 (#584e33)\nR 3 (#4fd2d2)\nD 4 (#30e451)\nR 3 (#682c22)\nD 3 (#30e453)\nR 4 (#727be2)\nD 8 (#85b173)\nL 4 (#3a8c50)\nD 3 (#004a23)\nR 2 (#6eef60)\nD 3 (#92b8d3)\nR 5 (#bdb140)\nU 8 (#8500b3)\nR 5 (#2e42f2)\nD 8 (#531953)\nR 3 (#9358a2)\nD 5 (#14d4b3)\nR 6 (#b19aa2)\nD 8 (#14d4b1)\nR 8 (#3e0d32)\nU 8 (#274023)\nR 3 (#b2d1a2)\nU 3 (#274021)\nR 8 (#206d02)\nU 6 (#2d02d3)\nR 4 (#0bd782)\nU 3 (#483403)\nR 9 (#7d6fc0)\nU 5 (#717513)\nR 9 (#5e63a0)\nU 6 (#614071)\nR 6 (#6df500)\nU 9 (#6f14e1)\nR 5 (#9229d0)\nU 5 (#6f14e3)\nL 5 (#0993b0)\nU 4 (#614073)\nL 3 (#aad3a0)\nU 7 (#2aed13)\nL 7 (#117f30)\nU 8 (#b185d3)\nL 3 (#a39640)\nU 10 (#a408b1)\nL 5 (#1e31b0)\nU 4 (#5af491)\nL 3 (#43ff50)\nU 4 (#125121)\nR 5 (#2321b0)\nU 4 (#4a6de1)\nR 6 (#80c430)\nU 5 (#4a6de3)\nL 5 (#8fe3b0)\nU 4 (#483d91)\nR 8 (#012050)\nU 3 (#3730e1)\nR 5 (#d36d12)\nU 8 (#7d5761)\nR 7 (#d36d10)\nU 7 (#21b1c1)\nR 9 (#8ea5e2)\nU 7 (#602a01)\nR 8 (#aae3f2)\nU 5 (#8d2981)\nR 5 (#263f72)\nU 5 (#2a3471)\nR 7 (#263f70)\nU 2 (#88ea21)\nR 3 (#3f5f62)\nU 6 (#5e1cc1)\nR 5 (#adffb0)\nU 6 (#104941)\nR 5 (#073230)\nU 4 (#25be03)\nL 9 (#1a2fd0)\nU 5 (#3d1233)\nR 9 (#879540)\nU 4 (#5c9671)\nL 2 (#6ad9e0)\nU 8 (#5c9673)\nL 7 (#3bb750)\nU 3 (#3d1231)\nR 11 (#080ca0)\nU 4 (#25be01)\nR 4 (#50a100)\nU 5 (#163541)\nL 5 (#27ff80)\nU 3 (#ab8481)\nR 4 (#549890)\nU 7 (#010511)\nL 4 (#749c72)\nU 4 (#46cfe1)\nL 5 (#a03822)\nD 5 (#594361)\nL 2 (#12a9f0)\nD 9 (#509f91)\nL 3 (#c051f0)\nU 3 (#509f93)\nL 7 (#41d8b0)\nD 3 (#80af51)\nL 3 (#549892)\nD 9 (#29c701)\nL 5 (#58fe00)\nD 5 (#4ef833)\nR 5 (#4ad860)\nD 7 (#aa4b13)\nL 7 (#6d6810)\nD 8 (#774e21)\nL 6 (#631140)\nU 8 (#4c9b31)\nL 4 (#4a8a50)\nD 3 (#61b9d1)\nL 6 (#665fd0)\nD 5 (#4edd51)\nR 6 (#46f5d0)\nD 3 (#109bd1)\nL 6 (#896f50)\nD 5 (#3ab8e1)\nL 3 (#6f6ce0)\nD 4 (#5acd11)\nL 5 (#1d15b2)\nU 4 (#032e23)\nL 10 (#8d6c92)\nU 3 (#032e21)\nR 10 (#4e59f2)\nU 5 (#70a541)\nL 5 (#1102a0)\nU 8 (#8b66f1)\nL 5 (#871710)\nU 10 (#be4e51)\nR 3 (#871712)\nU 11 (#1182c1)\nR 3 (#1102a2)\nD 9 (#493441)\nR 8 (#7a6b80)\nD 4 (#c3daa1)\nR 3 (#8a38d0)\nU 3 (#07ac71)\nR 4 (#131b90)\nU 5 (#34c6e1)\nR 4 (#914cf2)\nU 5 (#0e9af1)\nR 3 (#6c62d2)\nU 3 (#3af801)\nL 6 (#0018c0)\nU 7 (#2b7361)\nL 4 (#55fb20)\nU 5 (#8a33c1)\nR 4 (#a79be0)\nU 4 (#59acf1)\nR 7 (#bb8240)\nD 5 (#77ca71)\nR 7 (#894bd0)\nU 5 (#a12ff1)\nR 3 (#437630)\nD 4 (#1dbba1)\nR 10 (#4c87b0)\nU 6 (#9ea131)\nR 2 (#4c87b2)\nU 4 (#19f7e1)\nL 11 (#85c770)\nU 4 (#220631)\nL 9 (#224540)\nU 5 (#d4ac83)\nL 4 (#421610)\nU 3 (#23ae63)\nL 9 (#8259c0)\nD 4 (#1b4b51)\nR 6 (#b84e80)\nD 11 (#9b8e41)\nL 6 (#29c310)\nD 4 (#9cba93)\nL 6 (#2e33e0)\nU 10 (#1d8b03)\nL 5 (#2578e2)\nU 7 (#0c7911)\nL 2 (#6112e2)\nU 2 (#0c7913)\nL 7 (#621cb2)\nD 8 (#4164f3)\nL 4 (#080dd2)\nU 11 (#574773)\nR 7 (#6ab252)\nU 3 (#4224b3)\nR 3 (#898930)\nU 2 (#c8" <> ...}
+
```
+
+
```elixir
+
# puzzle_input =
+
"""
+
R 6 (#70c710)
+
D 5 (#0dc571)
+
L 2 (#5713f0)
+
D 2 (#d2c081)
+
R 2 (#59c680)
+
D 2 (#411b91)
+
L 5 (#8ceee2)
+
U 2 (#caa173)
+
L 1 (#1b58a2)
+
U 2 (#caa171)
+
R 2 (#7807d2)
+
U 3 (#a77fa3)
+
L 2 (#015232)
+
U 2 (#7a21e3)
+
"""
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
"R 6 (#70c710)\nD 5 (#0dc571)\nL 2 (#5713f0)\nD 2 (#d2c081)\nR 2 (#59c680)\nD 2 (#411b91)\nL 5 (#8ceee2)\nU 2 (#caa173)\nL 1 (#1b58a2)\nU 2 (#caa171)\nR 2 (#7807d2)\nU 3 (#a77fa3)\nL 2 (#015232)\nU 2 (#7a21e3)\n"
+
```
+
+
```elixir
+
commands =
+
puzzle_input
+
|> String.split("\n", trim: true)
+
|> Enum.map(fn <<dir>> <> " " <> rest ->
+
{len, " (#" <> <<hex::binary-6>> <> ")"} = Integer.parse(rest)
+
{dir, len, hex}
+
end)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
[
+
{76, 5, "0760b2"},
+
{85, 4, "058b53"},
+
{76, 3, "d05a12"},
+
{68, 4, "058b51"},
+
{76, 6, "12ee82"},
+
{85, 6, "63c403"},
+
{76, 4, "065a12"},
+
{85, 8, "a44373"},
+
{76, 7, "7581c2"},
+
{85, 7, "334ec3"},
+
{76, 3, "35e792"},
+
{85, 5, "079963"},
+
{76, 3, "1737b0"},
+
{85, 4, "29a7a3"},
+
{76, 2, "705a02"},
+
{85, 5, "7151e3"},
+
{76, 4, "705a00"},
+
{85, 4, "43f5a3"},
+
{76, 5, "1737b2"},
+
{85, 8, "61a8c3"},
+
{76, 5, "6005d2"},
+
{68, 3, "20f4c1"},
+
{76, 3, "4aa812"},
+
{68, 3, "8163b1"},
+
{76, 4, "80ac22"},
+
{68, 4, "5e64c1"},
+
{76, 7, "cb5430"},
+
{68, 5, "7ac2d1"},
+
{82, 7, "920132"},
+
{68, 6, "a44371"},
+
{76, 6, "944582"},
+
{85, 3, "bc3423"},
+
{76, 5, "71c1b2"},
+
{85, 4, "88e6f3"},
+
{76, 4, "0e35f2"},
+
{85, 5, "11fa31"},
+
{76, 8, "6ab312"},
+
{85, 5, "5c3df1"},
+
{82, 8, "40be22"},
+
{85, 3, "5c3df3"},
+
{82, 9, "42e412"},
+
{85, 6, "11fa33"},
+
{82, 5, "178f02"},
+
{85, 10, "88e6f1"},
+
{76, 2, "cff5f2"},
+
{85, 6, "41fb73"},
+
{76, 5, "247782"},
+
{85, 4, ...},
+
{76, ...},
+
{...},
+
...
+
]
+
```
+
+
## Part 1
+
+
```elixir
+
dirs = %{
+
?U => {0, -1},
+
?D => {0, 1},
+
?L => {-1, 0},
+
?R => {1, 0}
+
}
+
+
{points, {_, circ}} =
+
Enum.map_reduce(commands, {{0, 0}, 0}, fn
+
{dir, d, _}, {{x, y}, l} ->
+
{dx, dy} = dirs[dir]
+
{{x, y}, {{x + dx * d, y + dy * d}, l + d}}
+
end)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{[
+
{0, 0},
+
{-5, 0},
+
{-5, -4},
+
{-8, -4},
+
{-8, 0},
+
{-14, 0},
+
{-14, -6},
+
{-18, -6},
+
{-18, -14},
+
{-25, -14},
+
{-25, -21},
+
{-28, -21},
+
{-28, -26},
+
{-31, -26},
+
{-31, -30},
+
{-33, -30},
+
{-33, -35},
+
{-37, -35},
+
{-37, -39},
+
{-42, -39},
+
{-42, -47},
+
{-47, -47},
+
{-47, -44},
+
{-50, -44},
+
{-50, -41},
+
{-54, -41},
+
{-54, -37},
+
{-61, -37},
+
{-61, -32},
+
{-54, -32},
+
{-54, -26},
+
{-60, -26},
+
{-60, -29},
+
{-65, -29},
+
{-65, -33},
+
{-69, -33},
+
{-69, -38},
+
{-77, -38},
+
{-77, -43},
+
{-69, -43},
+
{-69, -46},
+
{-60, -46},
+
{-60, -52},
+
{-55, -52},
+
{-55, -62},
+
{-57, -62},
+
{-57, -68},
+
{-62, ...},
+
{...},
+
...
+
], {{0, 0}, 3518}}
+
```
+
+
```elixir
+
area =
+
points
+
|> Enum.chunk_every(2, 1, [{0, 0}])
+
|> Enum.map(fn [{x1, y1}, {x2, y2}] ->
+
x1 * y2 - x2 * y1
+
end)
+
|> Enum.sum()
+
|> abs()
+
|> div(2)
+
+
area + div(circ, 2) + 1
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
49897
+
```
+
+
## Part 2
+
+
```elixir
+
dirs = %{
+
?3 => {0, -1},
+
?1 => {0, 1},
+
?2 => {-1, 0},
+
?0 => {1, 0}
+
}
+
+
{points, {_, circ}} =
+
Enum.map_reduce(commands, {{0, 0}, 0}, fn
+
{_, _, <<d::binary-5, dir>>}, {{x, y}, l} ->
+
{dx, dy} = dirs[dir]
+
d = String.to_integer(d, 16)
+
{{x, y}, {{x + dx * d, y + dy * d}, l + d}}
+
end)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{[
+
{0, 0},
+
{-30219, 0},
+
{-30219, -22709},
+
{-883628, -22709},
+
{-883628, 0},
+
{-961172, 0},
+
{-961172, -408640},
+
{-987189, -408640},
+
{-987189, -1081463},
+
{-1468497, -1081463},
+
{-1468497, -1291619},
+
{-1689290, -1291619},
+
{-1689290, -1322745},
+
{-1594191, -1322745},
+
{-1594191, -1493363},
+
{-2054383, -1493363},
+
{-2054383, -1957521},
+
{-1594191, -1957521},
+
{-1594191, -2235883},
+
{-1689290, -2235883},
+
{-1689290, -2635895},
+
{-2082599, -2635895},
+
{-2082599, -2500907},
+
{-2388392, -2500907},
+
{-2388392, -1970928},
+
{-2915434, -1970928},
+
{-2915434, -1584292},
+
{-2082599, -1584292},
+
{-2082599, -1081463},
+
{-2680634, -1081463},
+
{-2680634, -408640},
+
{-3287954, -408640},
+
{-3287954, -1179522},
+
{-3753901, -1179522},
+
{-3753901, -1740273},
+
{-3812108, -1740273},
+
{-3812108, -1666638},
+
{-4249149, -1666638},
+
{-4249149, -1288815},
+
{-4514335, -1288815},
+
{-4514335, -1666638},
+
{-4788320, -1666638},
+
{-4788320, -1740273},
+
{-4884816, -1740273},
+
{-4884816, -1179522},
+
{-5736623, -1179522},
+
{-5736623, -1449785},
+
{-5885991, ...},
+
{...},
+
...
+
], {{0, 0}, 237488828}}
+
```
+
+
```elixir
+
area =
+
points
+
|> Enum.chunk_every(2, 1, [{0, 0}])
+
|> Enum.map(fn [{x1, y1}, {x2, y2}] ->
+
x1 * y2 - x2 * y1
+
end)
+
|> Enum.sum()
+
|> abs()
+
|> div(2)
+
+
area + div(circ, 2) + 1
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
194033958221830
+
```
+
+
<!-- livebook:{"offset":9828,"stamp":{"token":"XCP.PxtVRuGOoJbRBg9li_V5edaJPAIM1giG8b7fnblLM45DtgF15Jzd6NlUMPxbzksg6acUzlzFjYTBEN2LSqNSG1-GyFTIi-SNpma9KQLCo3vK0DZWQEcIQo44tSdMuxRx5A","version":2}} -->
+167
2023/day19.livemd
···
+
<!-- livebook:{"persist_outputs":true} -->
+
+
# Day 19
+
+
```elixir
+
Mix.install([:kino_aoc])
+
```
+
+
## Section
+
+
<!-- livebook:{"attrs":{"assign_to":"puzzle_input","day":"19","session_secret":"ADVENT_OF_CODE_SESSION","year":"2023"},"chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2023", "19", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:ok,
+
"xn{x>3251:R,x>2998:R,kxq}\nfzx{a<1013:A,a>1206:A,s<3847:A,R}\nxjm{a<406:R,A}\nmzl{m<755:R,a>679:R,A}\nfnv{x>2143:sxm,m<2895:A,gh}\nhx{x<2183:A,s>3619:A,A}\nkvr{s>3669:A,a>584:R,m>2806:R,R}\nngd{s<3561:R,a<2595:R,a>3464:kch,hx}\nqvh{s<1945:R,fng}\nsr{s<3808:A,R}\nrbs{m>562:A,a<333:A,A}\npsg{a>561:shp,s>2745:vk,jtr}\ndl{s<2761:hvq,fbg}\nzfh{m<2326:szm,m<2485:A,R}\npt{a<2937:R,s<3935:A,x>3021:R,A}\nrk{x<476:ljz,a<1937:jvg,R}\nps{m<3555:R,s>3909:zrm,R}\nrv{s>795:R,s>480:A,R}\nlnh{a>2617:gz,fm}\nsqb{x>3735:gfv,a<1477:msq,zv}\nmd{x<1096:A,x<1619:A,s<217:R,R}\nztr{x>767:R,R}\nsq{m>1364:A,s>244:A,a<3577:A,R}\nrpc{m<420:A,R}\nhs{x<554:R,R}\nvdl{s<3309:A,a>1384:R,R}\njl{x<1879:mt,A}\nzbc{m>1502:dl,rf}\nljr{a<3187:R,A}\nbvv{x>2910:bpz,s>3676:qzt,x>2015:R,A}\nzfd{m<3356:vgj,a>3007:zzt,gfm}\nzq{a>2708:A,R}\nfh{a>2705:R,jqg}\nmhv{m<813:R,R}\nkq{a>2126:R,A}\nvk{x>2866:A,jxl}\npbs{a<3509:R,sq}\npkx{x>2891:A,A}\ndv{x>326:A,R}\nlgv{m<3070:fh,s<1467:mgh,a<2929:pj,nft}\nhhb{m>3097:qmt,a>2942:bfr,dkx}\npxc{x<3132:R,m<1265:R,R}\ncd{m>3540:A,R}\ncq{s>211:A,s<106:A,A}\nvqv{a>1867:R,x>3706:A,R}\nnb{x>2068:fk,x>1696:svc,R}\nth{x<3593:R,s<2701:cf,vjk}\nsfs{m<252:gfq,a<618:R,m<353:hkq,cvz}\nfzz{a>637:jvq,x<1757:A,x<2008:gxn,nr}\ncxd{x<1726:A,x>1873:A,a>2383:A,R}\ngtz{m>3441:R,A}\nnh{s>2751:A,s<2708:R,s>2735:A,R}\nlq{a>1765:R,R}\nrzv{a<1448:cjn,gg}\ncf{s<2626:R,x<3812:R,A}\nmbf{a>2789:A,a>2651:R,m<1004:R,A}\ncb{m<1452:R,m<3092:R,s<3880:A,R}\npd{x>2406:A,a<2484:R,m>3832:R,A}\nqzt{x>2426:A,a<2554:R,A}\nvf{a>1506:mgn,m<2895:cj,a>506:ps,dtx}\ndzz{m>3559:A,R}\nmr{s<2133:A,s<2292:R,a<2700:A,A}\nrn{s>901:A,m>3204:bb,spv}\ntnf{x>2142:A,x>1748:R,s>3539:A,R}\ncs{s<2710:A,a<3268:R,R}\nqc{x>1358:ftl,a>2473:kk,x>799:xsf,xht}\nqdm{s>341:A,A}\nglr{x<686:dfr,x>1172:vl,R}\ncn{m<3652:cxd,A}\ncm{m<151:R,s>3876:R,s<3842:A,A}\ngfm{x>1439:cn,m<3716:tks,m<3855:jn,jcr}\nbf{m<963:A,A}\nvlh{m<3510:A,x>2910:R,A}\nlpv{s<3981:A,a<1739:R,A}\nvjd{m>3232:A,m>3185:A,R}\ncbx{m>1016:A,R}\nxnc{a>3100:A,R}\nqkg{a>1138:R,x>1239:A,m<725:A,R}\nstl{m>947:bm,s<3931:A,s<3956:A,pkx}\nrf{s>2880:kcz,x>644:xk,zh}\nxpd{x>3710:A,s<3512:R,R}\ndt{x<3732:R,a<2881:A,a<3307:R,A}\njqg{s<1267:A,x>2703:R,R}\nstr{x<2942:vzf,x<3428:gl,a<2665:sqb,vt}\nnl{m>3788:A,s>1087:A,s>683:R,A}\nfc{s<3884:R,x>2689:R,R}\ngxt{m>426:ll,m>178:R,x<1350:tmf,st}\nzvg{a>3345:R,A}\nrkr{a>1171:R,A}\nvjv{s>2771:tv,dtz}\nfvp{a<1356:sfs,s>928:ss,rsf}\nnbf{s<611:R,a<1809:R,A}\njn{a>2068:A,nl}\nfzm{a>2076:bpk,x>876:kdd,m<400:jf,tsv}\nqvv{a<773:A,m>764:A,A}\nhhq{x<921:pks,x>988:cl,qr}\nin{s<2529:ntc,xz}\ndh{s<3515:R,R}\ndc{s>2919:A,R}\nmgh{m<3466:rv,a<2753:R,R}\nnm{m<3214:A,m<3302:qlm,x>3194:A,A}\nspq{m>3854:zvg,x>1467:tfn,s>1060:A,R}\nxh{s>2565:A,s>2547:mm,m>597:xkx,qq}\ncv{s>2058:R,A}\nlfp{m<3165:gdt,xnf}\njv{x>403:R,A}\nbqh{m>2771:A,A}\npb{a<1100:A,A}\njcr{s<1408:A,m>3905:cng,x>1043:A,hns}\nccd{s>790:R,kd}\ndtx{s<3858:sr,x>3627:R,R}\njfn{m<1123:A,s>3574:R,m>1296:R,A}\nrrc{x>2142:R,x>1904:R,R}\njdp{x<3059:R,a>2402:R,A}\npks{s>1682:zpz,R}\nppj{x>304:R,a>1076:A,s<2714:A,R}\njf{x>487:ptd,zvr}\nll{m<826:R,a<714:R,m>1017:A,A}\nlvd{m<1464:R,a<2106:tr,a<2987:fzc,js}\nkk{a>3251:mbb,pp}\nsg{m>2670:R,A}\nssj{m<515:R,x>660:R,A}\nzxr{a<1482:tlg,x>1965:gsl,x>841:zfd,qdl}\nqvl{m<3128:A,m<3608:A,a>1356:A,R}\nbdc{s>3857:R,R}\nvxf{s>3540:xtp,bvr}\nzfk{m>2828:R,R}\nrr{a<901:A,qvl}\nvgj{x>1312:bpj,x>1146:lkq,x>1035:sz,rgc}\nkb{m>2576:lsc,A}\nthg{a>248:hm,s<3241:R,R}\ndj{s<3857:A,R}\nzc{s<1965:ht,x>1083:fzz,s>2211:dmb,gd}\ncng{s<2122:A,m<3953:R,m<3974:A,R}\npg{s>878:R,R}\ngp{a>1793:R,x<2223:R,s>3362:R,A}\nkxq{x<2775:R,x>2923:A,A}\nhsg{s<3226:A,s<3330:A,R}\nqlj{a<1311:mv,A}\npr{x>494:mxk,a<2936:kmm,bht}\ngpv{x<1269:R,x>1381:R,m>2765:R,R}\nvt{m<2555:qst,xtv}\nhfl{x<2629:A,a>3143:A,m<290:R,A}\nzb{s<1697:A,A}\nxrq{s<2864:A,a>2201:A,a>1934:R,A}\nfm{m>3529:A,R}\nxb{s<2818:A,a<3522:A,m>2849:A,dlx}\nbx{a>2926:R,a<2074:R,A}\nqmt{s>2887:ls,x>2904:th,dzz}\nvp{x>2532:A,a>2417:R,R}\nmxk{x<1016:ztr,a<2922:tf,nt}\nvg{a>707:fbh,ndl}\nmf{a<2235:A,a>3265:fc,vm}\nghh{m<945:A,x<2100:R,R}\nmt{x>1602:R,a<2587:A,A}\ndlz{s<2689:A,s<2755:rxh,x>3417:nhr,fv}\nmbb{s>1105:zb,s>554:pg,a<3688:pbs,bn}\nkch{m>2412:R,R}\nrc{a<1071:A,m>1532:A,R}\nhvq{s<2609:zs,A}\ntfn{x>1675:R,R}\nshp{a>885:R,A}\njtr{s>2671:jft,R}\nkdd{a>1297:jzz,x>1193:gxt,fph}\nq" <> ...}
+
```
+
+
```elixir
+
defmodule Day19 do
+
def always, do: fn _ -> true end
+
+
def match(<<field::binary-1, cmp>> <> value) do
+
value = String.to_integer(value)
+
+
case cmp do
+
?> -> fn map -> map[field] > value end
+
?< -> fn map -> map[field] < value end
+
end
+
end
+
+
def walk("A", value, _), do: value |> Map.values() |> Enum.sum()
+
def walk("R", _, _), do: 0
+
+
def walk(curr, value, ruleset) do
+
rules = ruleset[curr]
+
+
Enum.find_value(rules, fn {f, next} ->
+
if f.(value), do: next
+
end)
+
|> walk(value, ruleset)
+
end
+
end
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:module, Day19, <<70, 79, 82, 49, 0, 0, 13, ...>>, {:walk, 3}}
+
```
+
+
```elixir
+
[rules, inputs] = String.split(puzzle_input, "\n\n")
+
+
ruleset =
+
rules
+
|> String.split("\n", trim: true)
+
|> Map.new(fn line ->
+
[name, rest] = String.split(line, "{")
+
+
rules =
+
rest
+
|> String.trim_trailing("}")
+
|> String.split(",")
+
|> Enum.map(fn rule ->
+
case String.split(rule, ":") do
+
[next] -> {Day19.always(), next}
+
[rule, next] -> {Day19.match(rule), next}
+
end
+
end)
+
+
{name, rules}
+
end)
+
+
inputs =
+
inputs
+
|> String.split("\n", trim: true)
+
|> Enum.map(fn "{" <> data ->
+
data = String.trim_trailing(data, "}")
+
+
data
+
|> String.split(",")
+
|> Map.new(fn <<field::binary-1>> <> "=" <> value ->
+
{field, String.to_integer(value)}
+
end)
+
end)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
[
+
%{"a" => 2402, "m" => 2238, "s" => 929, "x" => 1},
+
%{"a" => 205, "m" => 654, "s" => 508, "x" => 1167},
+
%{"a" => 35, "m" => 2051, "s" => 1791, "x" => 1057},
+
%{"a" => 2726, "m" => 502, "s" => 178, "x" => 633},
+
%{"a" => 845, "m" => 2315, "s" => 2005, "x" => 3343},
+
%{"a" => 111, "m" => 2081, "s" => 499, "x" => 987},
+
%{"a" => 799, "m" => 1999, "s" => 1982, "x" => 464},
+
%{"a" => 518, "m" => 3195, "s" => 1247, "x" => 801},
+
%{"a" => 285, "m" => 2075, "s" => 1, "x" => 1506},
+
%{"a" => 384, "m" => 1366, "s" => 697, "x" => 1075},
+
%{"a" => 371, "m" => 1008, "s" => 1901, "x" => 33},
+
%{"a" => 115, "m" => 43, "s" => 14, "x" => 426},
+
%{"a" => 979, "m" => 2121, "s" => 2493, "x" => 595},
+
%{"a" => 3003, "m" => 3576, "s" => 3096, "x" => 557},
+
%{"a" => 921, "m" => 1269, "s" => 1983, "x" => 837},
+
%{"a" => 3300, "m" => 230, "s" => 909, "x" => 1367},
+
%{"a" => 130, "m" => 1878, "s" => 508, "x" => 1713},
+
%{"a" => 675, "m" => 1098, "s" => 886, "x" => 531},
+
%{"a" => 2121, "m" => 2018, "s" => 1761, "x" => 508},
+
%{"a" => 19, "m" => 399, "s" => 226, "x" => 1579},
+
%{"a" => 243, "m" => 35, "s" => 1169, "x" => 163},
+
%{"a" => 309, "m" => 221, "s" => 1305, "x" => 913},
+
%{"a" => 1685, "m" => 164, "s" => 239, "x" => 1780},
+
%{"a" => 2727, "m" => 208, "s" => 132, "x" => 86},
+
%{"a" => 2300, "m" => 2703, "s" => 386, "x" => 842},
+
%{"a" => 57, "m" => 454, "s" => 2120, "x" => 556},
+
%{"a" => 875, "m" => 1273, "s" => 1067, "x" => 1711},
+
%{"a" => 434, "m" => 939, "s" => 3341, "x" => 862},
+
%{"a" => 1666, "m" => 417, "s" => 203, "x" => 842},
+
%{"a" => 213, "m" => 1955, "s" => 2849, "x" => 93},
+
%{"a" => 62, "m" => 103, "s" => 104, "x" => 636},
+
%{"a" => 1917, "m" => 2014, "s" => 3128, "x" => 3715},
+
%{"a" => 225, "m" => 477, "s" => 579, "x" => 225},
+
%{"a" => 1176, "m" => 2243, "s" => 420, "x" => 556},
+
%{"a" => 62, "m" => 1556, "s" => 275, "x" => 10},
+
%{"a" => 368, "m" => 2498, "s" => 305, "x" => 1649},
+
%{"a" => 1488, "m" => 1148, "s" => 2419, "x" => 437},
+
%{"a" => 2488, "m" => 540, "s" => 174, "x" => 2918},
+
%{"a" => 1089, "m" => 3207, "s" => 2740, "x" => 3431},
+
%{"a" => 441, "m" => 560, "s" => 439, "x" => 661},
+
%{"a" => 310, "m" => 59, "s" => 109, "x" => 292},
+
%{"a" => 691, "m" => 452, "s" => 2012, "x" => 497},
+
%{"a" => 1182, "m" => 1424, "s" => 1228, "x" => 227},
+
%{"a" => 159, "m" => 418, "s" => 64, "x" => 225},
+
%{"a" => 38, "m" => 216, "s" => 1582, "x" => 1490},
+
%{"a" => 840, "m" => 2919, "s" => 973, "x" => 483},
+
%{"a" => 183, "m" => 1362, "s" => 589, ...},
+
%{"a" => 2028, "m" => 455, ...},
+
%{"a" => 2024, ...},
+
%{...},
+
...
+
]
+
```
+
+
## Part 1
+
+
```elixir
+
inputs
+
|> Enum.map(&Day19.walk("in", &1, ruleset))
+
|> Enum.sum()
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
575412
+
```
+
+
<!-- livebook:{"offset":8997,"stamp":{"token":"XCP.3mLPPPAFmjyMyS1G8kuPg81u2xWiHEqMWIEJie5Cub-RqAtUePx4xByO_bbzZmbk0fucCfAAzGCebPJTo1sxtCCZWiS2f_1WHfwLTeKQ-A3TtNs0-62JkPMIEOcsxBwvcw","version":2}} -->
+135
2023/day21.livemd
···
+
# Day 21
+
+
```elixir
+
Mix.install([:kino_aoc])
+
```
+
+
## Section
+
+
<!-- livebook:{"attrs":{"assign_to":"puzzle_input","day":"21","session_secret":"ADVENT_OF_CODE_SESSION","year":"2023"},"chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2023", "21", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
```elixir
+
# puzzle_input =
+
"""
+
...........
+
.....###.#.
+
.###.##..#.
+
..#.#...#..
+
....#.#....
+
.##..S####.
+
.##..#...#.
+
.......##..
+
.##.#.####.
+
.##..##.##.
+
...........
+
"""
+
```
+
+
```elixir
+
lines =
+
puzzle_input
+
|> String.split("\n", trim: true)
+
+
map =
+
for {line, y} <- Enum.with_index(lines),
+
{char, x} <- Enum.with_index(to_charlist(line)),
+
char != ?.,
+
do: {char, {x, y}}
+
+
%{?# => obstacles, ?S => [start]} = Enum.group_by(map, &elem(&1, 0), &elem(&1, 1))
+
+
height = length(lines)
+
width = byte_size(hd(lines))
+
+
obstacles = MapSet.new(obstacles)
+
{sx, sy} = start
+
```
+
+
```elixir
+
defmodule Day21 do
+
def build_distance_map(width, height, start, obstacles) do
+
distances =
+
for x <- 0..width,
+
y <- 0..height,
+
{x, y} not in obstacles,
+
into: %{},
+
do: {{x, y}, nil}
+
+
do_build(Map.put(distances, start, 0), neighbours(start, width, height), width, height)
+
end
+
+
defp do_build(distances, [], _w, _h), do: distances
+
+
defp do_build(distances, [{x, y} | rest], w, h)
+
when is_nil(:erlang.map_get({x, y}, distances)) do
+
{min, next} =
+
Enum.reduce(neighbours({x, y}, w, h), {nil, []}, fn
+
{nx, ny}, {min, acc} ->
+
case Map.fetch(distances, {nx, ny}) do
+
{:ok, nil} -> {min, [{nx, ny} | acc]}
+
{:ok, val} -> {min(min, val), acc}
+
:error -> {min, acc}
+
end
+
end)
+
+
distances
+
|> Map.put({x, y}, min + 1)
+
|> do_build(rest ++ next, w, h)
+
end
+
+
defp do_build(distances, [_ | rest], w, h), do: do_build(distances, rest, w, h)
+
+
defp neighbours({x, y}, w, h),
+
do:
+
Enum.filter(
+
[
+
{x + 1, y},
+
{x - 1, y},
+
{x, y + 1},
+
{x, y - 1}
+
],
+
&in_map?(&1, w, h)
+
)
+
+
def in_map?({x, y}, w, h), do: x in 0..w and y in 0..h
+
end
+
```
+
+
```elixir
+
dist = Day21.build_distance_map(width, height, start, obstacles)
+
```
+
+
## Part 1
+
+
```elixir
+
radius = 64
+
+
potential_positions =
+
for dx <- -radius..radius,
+
dy <- -radius..radius,
+
rem(dx + dy, 2) == 0,
+
p = {sx + dx, sy + dy},
+
dist[p] <= radius,
+
do: {sx + dx, sy + dy}
+
```
+
+
```elixir
+
length(potential_positions)
+
```
+
+
## Part 2
+
+
```elixir
+
{width, height}
+
```
+
+
```elixir
+
radius = 26_501_365
+
```
+
+
<!-- livebook:{"offset":2664,"stamp":{"token":"XCP.IMvv8hCgLT5Uhw7XM98joJcCpiLODkv-dad_ZINIVpWiR15rOQ16JvnrIbZyWUgwLtcUNcu0O_o0fM9c_SHVKVz5kQtylMQU9zFIW02WoyY4Mif4i-dzdI_vkWqFZENooA","version":2}} -->
+83
2024/day01.livemd
···
+
<!-- livebook:{"persist_outputs":true} -->
+
+
# Day 01
+
+
```elixir
+
Mix.install([:kino_aoc])
+
```
+
+
## Section
+
+
<!-- livebook:{"attrs":"eyJhc3NpZ25fdG8iOiJwdXp6bGVfaW5wdXQiLCJkYXkiOiIxIiwic2Vzc2lvbl9zZWNyZXQiOiJBRFZFTlRfT0ZfQ09ERV9TRVNTSU9OIiwieWVhciI6IjIwMjQifQ","chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2024", "1", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:ok,
+
"28186 35627\n51854 34597\n19211 51032\n79370 53096\n68126 40302\n43284 25771\n80565 99650\n83151 70796\n91092 74579\n70740 98650\n45166 53096\n24309 45165\n62950 26641\n23291 91017\n56683 53851\n22308 81625\n83150 34155\n87443 91017\n56834 91784\n35159 67595\n10722 83450\n92257 23419\n15995 96671\n89901 39216\n25104 76669\n37075 56652\n15874 66083\n33493 35627\n87420 31838\n11269 91386\n92604 83450\n34888 99650\n49759 40926\n38211 27379\n93866 22096\n88205 66217\n55772 60776\n83556 78255\n22292 50829\n22487 78358\n27260 79702\n74570 90319\n27532 14353\n40720 67595\n99885 65688\n25733 53752\n12466 14411\n88402 40165\n63328 13804\n45165 62461\n24913 94225\n32251 76669\n91004 40165\n48939 45165\n98082 34561\n74569 42932\n99641 54600\n42748 22021\n23376 54490\n38706 69865\n64985 87783\n14431 78715\n37671 94814\n27425 60776\n21801 76669\n96975 33493\n56680 31838\n41265 71129\n99081 32487\n53077 82615\n54490 55624\n22649 60776\n82601 25943\n93133 96412\n77182 78358\n67827 76838\n45976 89107\n20352 89034\n28891 23800\n87739 76669\n47802 99650\n18060 28437\n65882 93980\n53343 13764\n84301 93604\n62547 93479\n79067 45165\n70139 54490\n28158 76669\n71631 39775\n36521 57540\n78928 37888\n75943 39076\n28462 60107\n95828 94225\n49768 73181\n40545 97945\n18963 74260\n17934 63046\n73054 13454\n43170 60924\n90257 28180\n99765 33493\n41380 50296\n24225 62945\n66579 73961\n73361 54622\n26339 91017\n84080 62041\n89322 54600\n84610 18344\n58420 87051\n12253 83450\n25631 91017\n71764 63533\n52908 40165\n56578 46636\n99876 61946\n43934 64469\n78242 11111\n97629 28916\n21477 91017\n97639 64456\n90978 53077\n94412 73836\n49249 96113\n92750 14411\n12961 13764\n84319 22230\n83435 78146\n48951 86109\n40258 13764\n54600 65577\n51432 53096\n11527 20394\n68196 94225\n14939 91017\n13158 39216\n62120 93587\n20939 71764\n58436 28038\n37198 31838\n59152 17554\n52958 44145\n64236 18285\n63763 56578\n40304 99650\n86564 78910\n45684 52760\n43139 61946\n99974 76669\n44698 86004\n19940 22021\n29106 78358\n60431 91386\n50880 76451\n96595 42193\n40966 73961\n64515 61946\n31081 39834\n87614 70892\n82663 54622\n73537 62994\n14125 56652\n51361 35627\n26084 35817\n82915 20069\n72409 22021\n22834 20071\n93476 83787\n63719 53096\n41505 48056\n56055 20404\n37255 99650\n33468 60776\n70472 22598\n66290 53077\n91071 67595\n30888 33173\n60826 29871\n12334 78358\n62744 69424\n85449 79500\n22333 16295\n67621 18455\n12605 90059\n32490 25835\n96639 75870\n82412 39747\n76964 60153\n60776 60776\n68837 39216\n35635 67595\n85239 14964\n15278 83450\n63581 35178\n77006 18285\n88570 80424\n61499 81689\n57466 47392\n78524 84304\n11821 53989\n62425 28916\n36264 50872\n38567 13061\n16357 45165\n17202 94451\n64290 31838\n76075 55071\n87325 40165\n93961 99650\n49866 65601\n91725 14411\n44721 18285\n44065 33493\n22521 56578\n28070 54600\n45621 54600\n54677 26913\n79647 24298\n89613 31415\n86493 13764\n16243 64218\n12832 21187\n43847 35189\n75859 54600\n69276 75826\n43251 14411\n96012 41446\n35482 35817\n45380 82383\n66801 31838\n79199 92341\n33087 70511\n40619 28916\n67655 80670\n22431 60776\n62731 54622\n29873 25771\n99354 63481\n36415 61946\n29742 94919\n64872 53077\n93028 55635\n32784 18285\n87488 68734\n56652 18285\n49968 80712\n82653 53096\n30377 24784\n40120 45165\n88404 70120\n69179 45165\n99645 67595\n44883 45165\n76320 43595\n29057 90019\n28502 61946\n73459 84304\n96354 54622\n77589 14301\n51381 54490\n40490 95808\n36023 27135\n13434 63807\n27250 35627\n13764 32845\n28229 34954\n56430 76669\n98593 63811\n11192 60776\n81601 72265\n86908 77116\n25484 82383\n31115 42206\n75124 70148\n96785 53096\n59814 85995\n17024 57255\n81701 41971\n43938 33493\n91646 33599\n96616 81828\n73270 87775\n75876 35817\n53007 83450\n39527 33975\n35936 17039\n95194 23302\n96876 80147\n68136 91386\n31253 19760\n98767 " <> ...}
+
```
+
+
```elixir
+
{left, right} =
+
puzzle_input
+
|> String.split("\n", trim: true)
+
|> Enum.map(fn line ->
+
line
+
|> String.split(" ", trim: true)
+
|> Enum.map(&String.to_integer/1)
+
|> List.to_tuple()
+
end)
+
|> Enum.unzip()
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{[28186, 51854, 19211, 79370, 68126, 43284, 80565, 83151, 91092, 70740, 45166, 24309, 62950, 23291,
+
56683, 22308, 83150, 87443, 56834, 35159, 10722, 92257, 15995, 89901, 25104, 37075, 15874, 33493,
+
87420, 11269, 92604, 34888, 49759, 38211, 93866, 88205, 55772, 83556, 22292, 22487, 27260, 74570,
+
27532, 40720, 99885, 25733, 12466, 88402, 63328, ...],
+
[35627, 34597, 51032, 53096, 40302, 25771, 99650, 70796, 74579, 98650, 53096, 45165, 26641, 91017,
+
53851, 81625, 34155, 91017, 91784, 67595, 83450, 23419, 96671, 39216, 76669, 56652, 66083, 35627,
+
31838, 91386, 83450, 99650, 40926, 27379, 22096, 66217, 60776, 78255, 50829, 78358, 79702, 90319,
+
14353, 67595, 65688, 53752, 14411, 40165, ...]}
+
```
+
+
## Part 1
+
+
```elixir
+
left
+
|> Enum.sort()
+
|> Enum.zip_with(Enum.sort(right), &abs(&1 - &2))
+
|> Enum.sum()
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
1603498
+
```
+
+
## Part 2
+
+
```elixir
+
freq_left = Enum.frequencies(left)
+
freq_right = Enum.frequencies(right)
+
+
freq_left
+
|> Enum.map(fn {id, n} -> id * n * Map.get(freq_right, id, 0) end)
+
|> Enum.sum()
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
25574739
+
```
+
+
<!-- livebook:{"offset":6294,"stamp":{"token":"XCP.Sz2iSQavADDpvtEa1kPPKXU2FJX4whRA8o-9s7dVkXuAtZgcWAfkz84tbAfwi7Uwo2ZHGidQtTuQgV-kqNBK-CR04hZZSMuvCDJWvO3n-0VLRe9_gxnirhNs2i3h2ydu0JE","version":2}} -->
+141
2024/day02.livemd
···
+
<!-- livebook:{"persist_outputs":true} -->
+
+
# Day 02
+
+
```elixir
+
Mix.install([:kino_aoc])
+
```
+
+
## Section
+
+
<!-- livebook:{"attrs":"eyJhc3NpZ25fdG8iOiJwdXp6bGVfaW5wdXQiLCJkYXkiOiIyIiwic2Vzc2lvbl9zZWNyZXQiOiJBRFZFTlRfT0ZfQ09ERV9TRVNTSU9OIiwieWVhciI6IjIwMjQifQ","chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2024", "2", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:ok,
+
"75 76 77 80 82 85 84\n49 52 53 55 58 59 61 61\n54 57 60 62 66\n4 6 8 10 11 14 19\n82 85 86 83 85 87 89\n85 86 87 86 89 88\n69 72 73 76 77 74 75 75\n4 6 4 5 8 11 15\n6 9 10 12 15 16 15 20\n41 43 43 45 48 51\n48 51 53 53 56 58 59 58\n67 69 71 74 74 77 77\n82 83 85 85 89\n21 24 26 26 29 31 36\n4 7 10 11 15 18 20 21\n56 58 60 63 65 69 70 68\n24 26 30 32 33 35 35\n12 13 15 17 20 24 25 29\n52 53 54 57 58 59 63 68\n43 46 48 55 58 59\n15 16 23 26 27 28 26\n49 50 53 56 59 64 64\n56 58 59 65 69\n3 5 6 8 13 18\n45 44 46 47 50 52 54\n37 35 36 37 34\n53 50 51 53 54 56 56\n80 78 79 80 81 83 86 90\n32 31 34 37 40 45\n76 75 77 79 77 80\n26 25 22 24 23\n27 26 23 24 25 25\n96 93 96 93 97\n37 34 35 36 39 36 38 45\n68 65 66 67 67 70 72\n41 39 42 42 43 40\n88 86 89 90 90 91 93 93\n24 23 25 26 26 28 32\n79 77 77 80 83 88\n50 48 50 52 55 58 62 63\n39 38 39 41 45 47 48 45\n40 38 41 42 44 45 49 49\n50 49 53 56 60\n74 73 77 80 86\n40 37 38 39 42 48 49 50\n12 11 17 20 22 23 25 23\n74 71 73 75 80 83 83\n20 17 23 25 29\n32 30 37 39 42 48\n80 80 83 86 87\n73 73 76 78 80 83 85 82\n19 19 22 25 28 30 32 32\n43 43 46 49 53\n69 69 72 75 80\n24 24 25 22 25 27\n60 60 58 61 64 65 62\n52 52 50 51 53 55 55\n56 56 59 56 60\n37 37 38 36 38 45\n7 7 9 12 12 13 14 16\n52 52 55 57 57 56\n89 89 89 91 91\n7 7 7 10 13 15 17 21\n43 43 44 47 50 50 52 58\n4 4 5 9 10 11 14 17\n11 11 13 17 15\n7 7 11 14 14\n55 55 58 62 64 66 70\n75 75 78 79 81 85 88 94\n56 56 63 64 67\n5 5 7 10 12 13 18 16\n32 32 38 41 43 44 47 47\n36 36 43 44 48\n9 9 12 17 22\n11 15 16 18 20 21 23 26\n50 54 55 57 60 62 64 61\n86 90 92 94 95 95\n84 88 90 93 97\n3 7 9 12 15 21\n36 40 41 44 47 46 47 50\n39 43 45 43 46 47 50 47\n84 88 90 87 90 90\n2 6 7 4 6 10\n31 35 34 35 36 39 45\n11 15 15 16 18\n1 5 7 9 11 14 14 13\n54 58 60 60 63 63\n52 56 58 60 60 64\n61 65 65 66 71\n48 52 55 56 60 61\n77 81 84 88 89 86\n58 62 63 66 67 71 74 74\n71 75 78 81 82 84 88 92\n82 86 87 91 98\n41 45 48 50 55 58 61\n70 74 77 78 83 86 88 85\n71 75 82 84 84\n19 23 30 31 35\n59 63 70 72 77\n45 51 53 55 56\n8 14 16 19 17\n46 52 55 58 58\n71 77 79 82 84 87 88 92\n68 75 77 80 87\n29 35 38 35 36 38 39\n34 39 38 41 43 45 42\n26 33 35 34 36 39 41 41\n85 92 95 92 96\n33 38 40 39 40 41 48\n83 89 92 93 93 94 95 96\n85 92 95 95 97 96\n54 59 59 60 61 62 64 64\n27 34 35 37 37 41\n69 75 77 79 81 81 86\n25 30 31 32 36 38\n51 58 62 63 64 63\n54 61 62 65 69 72 74 74\n59 66 68 69 73 76 79 83\n14 19 20 24 30\n33 40 42 48 51 52\n28 33 36 37 42 45 43\n44 50 55 58 58\n14 21 22 29 30 34\n35 40 43 49 52 53 59\n63 61 58 56 54 51 53\n52 49 46 45 45\n74 72 69 68 67 63\n80 77 74 73 72 67\n77 74 76 73 70 68 67\n20 17 16 15 17 19\n45 42 41 38 36 35 38 38\n55 54 56 53 49\n20 18 17 15 14 16 10\n17 14 14 12 10 8 6\n72 71 69 68 66 66 63 65\n31 30 30 27 26 25 24 24\n51 49 48 48 47 43\n26 24 24 21 20 14\n19 18 14 13 10 8\n84 81 80 76 78\n47 45 41 38 35 35\n68 67 64 60 56\n74 71 68 66 62 60 54\n43 41 38 36 33 27 26\n63 60 53 51 54\n29 28 23 20 17 16 14 14\n46 45 42 39 34 31 30 26\n23 21 19 13 11 5\n27 29 26 24 23 22 19\n86 88 86 83 81 79 81\n57 59 57 54 52 50 47 47\n21 24 21 18 14\n61 63 62 61 59 57 50\n96 99 97 98 96 95 92\n66 69 71 69 71\n41 43 42 39 37 40 37 37\n79 82 85 84 80\n77 79 77 78 73\n22 24 24 22 20\n63 66 64 64 66\n19 22 22 21 18 18\n95 97 97 95 93 91 87\n32 33 31 29 29 28 25 18\n42 44 43 39 38 36 34 31\n27 29 27 24 22 18 20\n20 22 18 15 15\n68 69 65 63 59\n79 81 77 76 73 72 67\n68 70 69 63 62 60 59 56\n42 44 39 36 33 36\n88 90 87 82 81 79 79\n66 69 66 59 58 54\n70 71 70 68 66 60 54\n77 77 76 74 72 71 69 66\n43 43 40 37 34 33 36\n21 21 20 18 18\n34 34 32 29 27 25 22 18\n79 79 78 76 73 66\n89 89 92 90 88\n77 77 75 73 72 73 76\n84 84 83 85 85\n30 30 28 26 23 22 25 21\n22 22 25 23 21 20 15\n66 66 66 64 63 62 60 57\n75 75 73 70 67 67 68\n33 33 33 30 27 25 22 22\n55 55 52 50 50 46\n40 40 38 38 37 32\n63 63 62 58 55\n95 95 94 90 92\n87 87 85 82 78 78\n88 88 84 83 79\n85 85 83 79 73\n53 53 51 44 42\n12 12 7 5 4 6\n53 53 48 47 44 44\n35 35 32 25 22 18\n46 46 39 36 34 27\n26 22 21 19 18 15\n91 87 86 85 83 85\n24 20 17 15 14 14\n66 62 60 57 54 50\n67 63 62 60 59 57 51\n41 37 35 38 37 36 33 31\n18 14 15 12 9 8 5 8\n37 33 32 30 29 30 30\n70 66 64 63 60 61 58 54\n34 30 28 26 23 26 24 18\n28 24 22 19 16 16 15\n54 50 50 48 47 44 41 43\n82 78 75 75 75\n38 34 34 33 30 29 25\n52 48" <> ...}
+
```
+
+
```elixir
+
inputs =
+
puzzle_input
+
|> String.split("\n", trim: true)
+
|> Enum.map(fn row ->
+
row
+
|> String.split(" ", trim: true)
+
|> Enum.map(&String.to_integer/1)
+
end)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
[
+
~c"KLMPRUT",
+
~c"1457:;==",
+
~c"69<>B",
+
[4, 6, 8, 10, 11, 14, 19],
+
~c"RUVSUWY",
+
~c"UVWVYX",
+
~c"EHILMJKK",
+
[4, 6, 4, 5, 8, 11, 15],
+
[6, 9, 10, 12, 15, 16, 15, 20],
+
~c")++-03",
+
~c"03558:;:",
+
~c"CEGJJMM",
+
~c"RSUUY",
+
[21, 24, 26, 26, 29, 31, 36],
+
[4, 7, 10, 11, 15, 18, 20, 21],
+
~c"8:<?AEFD",
+
[24, 26, 30, 32, 33, 35, 35],
+
[12, 13, 15, 17, 20, 24, 25, 29],
+
~c"4569:;?D",
+
~c"+.07:;",
+
[15, 16, 23, 26, 27, 28, 26],
+
~c"1258;@@",
+
~c"8:;AE",
+
[3, 5, 6, 8, 13, 18],
+
~c"-,./246",
+
~c"%#$%\"",
+
~c"5235688",
+
~c"PNOPQSVZ",
+
[32, 31, 34, 37, 40, 45],
+
~c"LKMOMP",
+
[26, 25, 22, 24, 23],
+
[27, 26, 23, 24, 25, 25],
+
~c"`]`]a",
+
~c"%\"#$'$&-",
+
~c"DABCCFH",
+
~c")'**+(",
+
~c"XVYZZ[]]",
+
[24, 23, 25, 26, 26, 28, 32],
+
~c"OMMPSX",
+
~c"20247:>?",
+
~c"'&')-/0-",
+
~c"(&)*,-11",
+
~c"2158<",
+
~c"JIMPV",
+
~c"(%&'*012",
+
[12, 11, 17, 20, ...],
+
~c"JGIKPSS",
+
[20, 17, ...],
+
[32, ...],
+
~c"PPSVW",
+
...
+
]
+
```
+
+
```elixir
+
defmodule Day02 do
+
def correct?([a, b | _] = input) do
+
cmp = if a > b, do: &>/2, else: &</2
+
valid? = fn [c, d] -> abs(c - d) in 1..3 and cmp.(c, d) end
+
+
input
+
|> Enum.chunk_every(2, 1, :discard)
+
|> Enum.all?(valid?)
+
end
+
end
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:module, Day02, <<70, 79, 82, 49, 0, 0, 9, ...>>, {:correct?, 1}}
+
```
+
+
## Part 1
+
+
```elixir
+
Enum.count(inputs, &Day02.correct?/1)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
479
+
```
+
+
## Part 2
+
+
```elixir
+
Enum.count(inputs, fn row ->
+
Enum.any?(0..length(row), fn idx ->
+
row |> List.delete_at(idx) |> Day02.correct?()
+
end)
+
end)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
531
+
```
+
+
<!-- livebook:{"offset":6719,"stamp":{"token":"XCP.G9JOBFd6jltWt-jkW37gzAIiay7brKZPFEBwgZCNOwBJpPmDyHp2GNGrNOADiSuyHghh61GSONlBGBUhRAPkPyonpwEHNjQtjnNbJGdA9f5v976Ir8CzhrtsvgWjFZ82wsQ","version":2}} -->
+59
2024/day03.livemd
···
+
<!-- livebook:{"persist_outputs":true} -->
+
+
# Day 03
+
+
```elixir
+
Mix.install([:kino_aoc])
+
```
+
+
## Section
+
+
<!-- livebook:{"attrs":"eyJhc3NpZ25fdG8iOiJwdXp6bGVfaW5wdXQiLCJkYXkiOiIzIiwic2Vzc2lvbl9zZWNyZXQiOiJBRFZFTlRfT0ZfQ09ERV9TRVNTSU9OIiwieWVhciI6IjIwMjQifQ","chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2024", "3", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:ok,
+
"(%%from() when()mul(73,623)when()mul(793,458)'~where()how()?how(569,237)/[mul(709,198)mul(395,622)$!what()select()^@/what()+mul(970,343)mul(75,7)^))mul(61,40)select()~why())'>where()%+mul(892,307),!(mul(412,807):*&what()+^why()<^why()mul(706,931)'{who())why()^?mul(953,62)(mul(461,410)when()don't()>^@<%who()'mul(365,15)(<^<# (where()mul(802,710)why()*[( where()where()mul(684,352)&)&what()^<[>mul(246,913)+select()?how(489,271)when() }why(627,30);don't()+&<@where()when()mul(636,990)]/mul(767,759):mul(328,474)([^,-select()?(mul(825,353)select()where()*where()what()*-@mul(765,991)where(786,744)'--where()mul(990,947) mul(547,706)from()?mul(229,193)where(617,453)+@&where()]@%}/mul(128,550)<%mul(3,636)don't()^(+#>+mul(66,503) select()#when()%from()mul(59,150)how(),when()^:mul(614,438)where()*<[where();(mul(434,344) /how()$ (%?~when()mul(659,534)mul(809,367) where(42,397),);? ++select()mul(858,771)<*mul(106,962)^>@;# @?,*mul(208,462)'',)mul(762,748)+[?}>][^mul(126,384))@]): /(('mul(966,704)who()what()~%*]from()mul(825,633)~$)+ &mul(634,698)(how()<@why(102,647)mul(661,112)]&<(%&mul(25,649)who()select();mul(267,405)why(356,766)why()(where(),select()^)mul(552,557){!from()^&>>+mul(493,578)select(742,239):how(){^mul(836,239)who()/)-mul(259,726)how()-;where()[#@from()~mul(495,301);>[;mul(478,953)$#[*why(),{mul(774,653)how()^mul(469,614)!what();-->>;mul(369,74)$who()who()mul(311,382)< ![>?$mul(909,70)!+$how(257,485)<mul(278,404)] where()':mul(824,974)when(),;&@-?~>mul(377,363)where()&why()-/:(mul(285,466)where()(what()why()[where()&who()mul(701,477)(where(),-why(){mul(624,21)where()[,why()-!?+mul(937,219) mul(604,90)how()(')]why()/mul(627,697)*;what()/$select()do()~<from()%-^mul(605,52)>@%!&select()>['mul(597,962)why()where()mul(903,469); &,do()when(937,722)((~why();^mul(588,272);}?[mul(295,621)from(645,893)>]>#mul(900,24)>,;mul(574,932):}(-do()from()-+<'$how()mul(694where())select()){how()how() (mul(350,308)/{)}why()what(987,719)}!#don't();<how()[from()/-'mul(438,672)}!@who() }?)mul(952,413#>:}-: 'when()select()mul(547,749)$#mul(869,866)@{mul(334,736';'select(330,146)[~ :>mul(511,40)(mul(11,3 mul(547,132)[!>select();who()mul(424,102)*!~mul(725,298)~:{^?%*mul(514,355%'],,: -)mul(116,719)select()?/@;when()<who();!mul(352,211)+#$;{$>]mul(820,414)&when(),!?[:?don't()when()?>}+#how()mul(159$$},:]why()-mul(689,30)@^mul(310,593)where(800,717)^(/*/! from()<mul(7,727)select()&mul(259,310)where()^select()#@how(49,595)what(){>]mul(429,841)(-+#[mul(579,668)>what()&+,mul(850,283)don't()#?mul(758,673)^;)select(856,890)%:how(550,676)<,)mul(667,314)>:[;+mul(760,374)select();}*select()#how()$*mul(347,822)who()how(){mul(497,700):where(){what()mul(851,789)^:}when()why()where()(:mul(991,536)-mul(711,63)',( who()]mul(798,573)>mul(190,153)$]from()!mul(592,256)-$-]mul(734?mul(482,742)#;mul(939,69)how()([how()<what()$$who()why()mul(149,831))/'when()mul(152,123)+* ','$where()mul(774,252) ;@?,;don't()how()>(mul(933,652)}mul(882,656),?how()#%}do()!select()>}>mul(981,750)mul(927,646)!what()$mul(380why()$]/[*?+)mul(67,435)>select()@-mul(819,795)?/? how())mul(215,234){,#/>how(513,708)'~>do()#}^^mul#how()how()how()+when():mul(992,63)mul(526,962)where()}who()who()+&'<,mul(730,728)}/,select()what()*who())[mul(687,974)-<:mul(259,420)\nwho()(&?>'+:?mul(483,827)*!what()[!/*mul(368,168)!&;^)?mul(629,217)]^{what()!,who()mul(83,255)^)mul(500,689)!-mul(592,556)%select()}from()-+mul(946*who()?,from()%/'~from(619,712){mul(747,249)/@+%when())mul(762,891)what(),when()?,#<:[mul(873,69)+ :what()+how()&[}who()mul(591,81){when()mul(151,432)@<what()-@]do()/mul(233,269)%&![+where()what()-why()mul(402,497):@from()where()':(how()mul(520,79)!]^$<select()when(478,105)mul(340,948),(mul(410,461)select()from()]-(@who()who())]mul(511,538)!who(6,403)do()<(where()what()mul(443,727)when()where()?&where()~mul(302,402)&mul(599,23))[how()[+!{mul(823,16)#%#]+~who(942,742))how()mul(502,890)^;<where()from()!~;+;mul*$<;mul(25,421)/:where() {^who()mul(652,45)#?from()^~; ,<mul(783,401)?who()what()mul(828,237)!]^when(126,561)mul(724,536){<*?don't()])why()/mul(974,752)%]$})mul(688,4)!'#:'@$mul(115,891)['w" <> ...}
+
```
+
+
## Part 1
+
+
```elixir
+
Regex.scan(~r/mul\((\d{1,3}),(\d{1,3})\)/, puzzle_input)
+
|> Enum.reduce(0, fn [_, a, b], acc ->
+
acc + String.to_integer(a) * String.to_integer(b)
+
end)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
175615763
+
```
+
+
## Part 2
+
+
```elixir
+
Regex.scan(~r/do(n't)?\(\)|mul\((\d{1,3}),(\d{1,3})\)/, puzzle_input)
+
|> Enum.reduce({true, 0}, fn
+
["do()" | _], {_, sum} -> {true, sum}
+
["don't()" | _], {_, sum} -> {false, sum}
+
[_, _, a, b], {true, sum} -> {true, sum + String.to_integer(a) * String.to_integer(b)}
+
_, {false, sum} -> {false, sum}
+
end)
+
|> elem(1)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
74361272
+
```
+
+
<!-- livebook:{"offset":5260,"stamp":{"token":"XCP.aQCtuOA8woZ8_dCh-CI-OBSmlZ8-Kijxv-o6-KCS1J1zV2Ss2XT0dAkjFQeBxaoOH4bK9wrXdti0oBVzJ_CMqYHK_tz9j2KoN0reYeRd-HZeaNGz06-DbmfbvmwyNem79PU","version":2}} -->
+204
2024/day04.livemd
···
+
<!-- livebook:{"persist_outputs":true} -->
+
+
# Day 04
+
+
```elixir
+
Mix.install([:kino_aoc, :nx])
+
```
+
+
## Section
+
+
<!-- livebook:{"attrs":"eyJhc3NpZ25fdG8iOiJwdXp6bGVfaW5wdXQiLCJkYXkiOiI0Iiwic2Vzc2lvbl9zZWNyZXQiOiJBRFZFTlRfT0ZfQ09ERV9TRVNTSU9OIiwieWVhciI6IjIwMjQifQ","chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2024", "4", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:ok,
+
"MASAMXMSSXXMAMXXMXMASXMASXMMSMSMMMAXMASASMMSSMSXAXMASMMSMMMSSMSASMSSSSMSMSMXXMXMAXAMXMSMSSXSAMXMSSXSXSXMASXMSASXMMXSXMSSSSSXSAMMAMXSXXMAAXSA\nMASMMXMASAXASMSMMMSAMXSMSAMXAAAAAXAMXASXAMAAAAMMSMMMMMASXAAAAMMAMAMMASAAAAXMXMSSSSSSMMSAMAXAXXSMAMSAMXASAXXASAMXASAMAXXMASAAAMAMAXXMASXSXSXS\nMMXAXMMMSXMAMAAXAAXAAAXXSMMSMSMSMXAXMXSMMMMSSMXAMXAAXMAMMMMSSMMAMAMMAMMMMMXSAAXAAMMAXXSAMXMSMAXMAMSMSSXMASMMMSXSXMAXMMSMMMMMMSASMSXMAMAXXSAM\nSXSAMASASMSXMSMSMSSMMMMMMXAMXMMXMASMMMMAXXAAAMMMSSSSSMASXXAAXASMSXXMXSXSXSASMSMMSMSAMMMAMXAAMASXMMSXMXMMMXASAXMSAASAMXSAAMXSXMASAXMMXSMSMMAM\nAAAXXXMASASXMXMAXXMMASAASMXSASASXAAAAMSSMMMSXMAAMMMMMXAXMMMMSAMXAMASAMXSAMASXXAXAAMAMXSAMXSXSMMASAMSMASAAMSMMSSXMAXASASMMSAMASAMAMSMAAXMASXM\nMSMMXXMMMAMAMMMMMMXSAXXAMMMMXSAXMMXXAMXAAMMXMASXMAAASMMXAAMXAXAMMMAMAMAMAMXMASXMMXMAAXMAXMAMXMSAMASXMAXMSXMAMXXXMASAMAMAXMMMAAXXAAAMXSXMMMAS\nMXAXAMXXMMMMSAMAASMMMSMMASASAMAMAXMSXMSMMXAMXAXMMSSXSASXSSSMAMSMXMXSAMSSSMAMXMXAMAXXMMSAXAXMMXMASMMMMSSMMASAMMAMSMMAMAXSMXXMSSSSSSMXAXMSSMMM\nASXMMXSAMXAASXXMXSAAAXASAMMMASMSSSMAAMMXMMSSMASAMAMMMAMMAXMAXMASXMAXMSAAASASAMXSSMXSAAXSSMXAAXXAXMAMXMAMSMMAXMAAAAMXMAMXASXAMAMXMXMMAXAAXAXS\nMAASMAMMSSMMSMSSXSMMXSMMASMSXMAAASMMMMAAMAMAMXAXAASMSSMMMMXSMSXSMXSXMXMXMSXMASAMAAAMMMMMMXXXSXMASMXMXMMMSXMSAMASMSMAXMASAAMXMMSSMASXXMXMAXMA\nSAMXMXSAXAMASMXAASXSMMAXXMASAMMMMMMXXXSXMASAMXMASXSAAMXXXMMXMXAXMAMAMXXAAMAXAMASMMMSMMXSMMMXMAAMXXAXSXSASASXSMAMAAXMMSMMXMAXSAAAMXSASMSSXSAS\nMMXSSXMXSAMASXXMXMAXAXXMSMMMXSAMXXMSXMMASXSXSXXAXMMMMMXMAXAMXMMMMASAMXSMSSSMSMMMMMAXXMAXAAAAXXSXXSASXAMAXXMAXMAMSMMSASXMAXMXMMSXSAMXMAAXASAM\nASAMXAMXSXMAMMMXAMSSSMSAXXXMSXASASXXAASAMXMAMAMSXXAXASASASXXSAAAMASAMAXXAAAMXASXSMXXAMASMMSMSAMAMXXXMMMSMXMMMXMXAAAMXSASXSSSXAAAMMAMMMMMAMAM\nMMMSSXMXMAMXMSMXMSAAAAMMMXMSMSMMAAMSSMXAMMMAMXMXXSXSMSAMXSMAMSXSXAXAMSMMMSMMSAMAXAMXXAXXXAAAMXXMMSMMMSAMXXSASASXSMMXMSAMAAAAMMSXMAAMAMAMXMAM\nXXAXMASMSAMAAAAASMMMMXMASMMAAAXMAMAAMMMSAMSAMSAXMAAMMMAMXMMMMAXXAMXSMMSMAXXXXAMSMMSASMMMMSMXMSMMAAAAAMMMXMMAMASAMAAAXMSMMMMMXXMASXSSSSXSASAS\nSASAMXMAMMSASMSMXASMMASXSASMSSXSAMMXAAAASASAMXMXAXMSASASMXAAMMSMMSAMXAAMASMMSMMXAXMXXAAXXAAASAAMSSSMSXMXSAMAMAMASMSMSAMXMMASMMXMMAAAAXASMSSM\nXAMASXSXSASAXMXMSXMASAXASMSAAXXMAMSSSMSAXMMMSAMXMSASASAMAMMMSAAMAMASMSXSAXAMAMXMXMASXSMMSXSXMAXMAAXAMASXMAMXSXMXMXAXMAMAMAAAXMSXMMMMMMXMXXXM\nMMMASMAAMMMAMASASAMXMASMMAMMMMMXMMXAMAMXMAAXMAXXXMAMXMMMSSMAMMXMXSXMAXMMMSSSXSMSAMXSAXMASMMMASXMXSXXXAMAXAMMSASMSSSMSASASMXSAMAMXXAASXMMSASX\nAXMAXXMXMXSAMMMAMAMXMXAMXSMSXASASMMAMXMSSXMSXSAMXMXMMXSXAAXMASXMXAMSXSAAXXAXXXAAXAAMMMXXMAMMAMAAAMMSMSSMMSSMSAMAAAAASASASAMXXAXMMSAXSAAXMASX\nSXMASXXXMAXASMMMMMSXMMASXAAXSXSXSASMMASMSAXMAXAMXXMAMASMSSMMAXAAASASASMMAAMMXMSMSMXSAMXMXSXMASMMMSAXMMAXSMAMMXMMMSMMMAMAMXMAMXMAMAMMSXMXMXMX\nMAMMAMXAMXSSMMXAAXAMASAMXMMASXSXSAMMSMSAXMASASAMMMAAMAXAMXXMMSMMAASMAMMXMMXSAAAAXMASASMMAMXXMAAAXMXSSMXMAXAMXAMSMMMSMSMSMAMMSAXMASAAXMMASAAX\nSAXSAXSXSXMMASMSSMXMMMASXXAAMMMAMAMAAMMMMAMMMMAMAASXMSSSXMAXMAXAXMXMSMAXXAASMMMSMXMSAMXMASMSSSSMMSAXMASAMSMSXMMAAAAAXAAXSAMMMMXXXMMXSMSASMSM\nMAMAXMMMXAASAMAMMMMMSSMSXSMXSAMSMMMSXSASAAXAAMAMSMMAMAAMAMXMSASXSXXXXAMXMMXSMSMXMAMMAMXSASAAXAAAXMAMSAMAXAMSASMSSMSSSMMMSMSAAXSSSXSMXAMXSXMX\nMSMSMMXSMSMMAXMASAMSAMXMASAAMXSAAXAMXSMSSSSSXSAXXXXAMMSMXXSXMASAXXMASAMXMSXXAAAASAXMAMMMMMMMMSAMMAMXMMXSMXMSAMAAAAXXMAXMXMSMMSAMAAMXSAMXXASM\nAMAMAXAMXXXSXMXAXMXMASAMXMMMSMSXSMMSAMXXAXAAXAXMASMSMSMXXXAMMMMMMSMXSMMSAMXMSMSMSMSSMMMASXSSMMXSMAXMASAMXXXMMMMMMXMMSMMSAMXASMAMMSMMAAXXMASM\nXMAMMMXSAMASMAMXSXXSAMAMSMMAAASMXXMAAASMXMMMMMXXXAAAMAMMMXMAAMAMAMXASAAAAMAAAAAMXMMASXSXMAMAAMAMXSXSAMXMAMXSXAMSMSAMAXAXAMAMMSSMXMXAXXMSAMXM\nSMXSAAAMAMAMMSMAXAMMXSAMAAXSMXXASXSMSMAMXAAXMXMMMMSMMAMSAAXSXSAMAMXXSMMSASXSMSMSAMSAMMSAMXMSAMXSAXMMXMAXAMAAMAMAAAXSASMSSMXSAAXMASASAMXSAASM\nAAAAMMSSXMASAAMSXSAMXSXSXSMXMASASAMXMAASASXMXAAXAXAASAXASXMMASXSASMMMXAXXMAAMXXXMMMXMAMAMXMXAMXSAXAXSXMXAMMXSAMMSMMMMSMAMXMMMSSMXAAXAAAMXMXM\nMMMSAAXMMMSMMSSMAMMMMMMMMXAXSXSAMXMAXXXSXAAMSSSXMXSXMXSMMSAMAMAMXSAAAMXMAMMMMMSMSXSMMMXMMAXSAMAMASMXMASXSMMASXSAMXSAMXMAMAXASXXMMMMMMMXMMSSM\nSAMAMMSMSMXAMMXMAMMSASASASAMMAMMMMMXMSAMXMXMAAMASMMXSMAXAXMMMMSMMMXSMSSSSSMAAAMMSAMMAMASXSMSAMXSASAXMAMAMAMMSAMXSASASXSMSMSXSXAMAAAAXSASAAXX\nSMSMXXA" <> ...}
+
```
+
+
```elixir
+
# puzzle_input
+
search_box =
+
puzzle_input
+
|> String.split("\n", trim: true)
+
|> Enum.map(&String.to_charlist/1)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
[~c"MASAMXMSSXXMAMXXMXMASXMASXMMSMSMMMAXMASASMMSSMSXAXMASMMSMMMSSMSASMSSSSMSMSMXXMXMAXAMXMSMSSXSAMXMSSXSXSXMASXMSASXMMXSXMSSSSSXSAMMAMXSXXMAAXSA",
+
~c"MASMMXMASAXASMSMMMSAMXSMSAMXAAAAAXAMXASXAMAAAAMMSMMMMMASXAAAAMMAMAMMASAAAAXMXMSSSSSSMMSAMAXAXXSMAMSAMXASAXXASAMXASAMAXXMASAAAMAMAXXMASXSXSXS",
+
~c"MMXAXMMMSXMAMAAXAAXAAAXXSMMSMSMSMXAXMXSMMMMSSMXAMXAAXMAMMMMSSMMAMAMMAMMMMMXSAAXAAMMAXXSAMXMSMAXMAMSMSSXMASMMMSXSXMAXMMSMMMMMMSASMSXMAMAXXSAM",
+
~c"SXSAMASASMSXMSMSMSSMMMMMMXAMXMMXMASMMMMAXXAAAMMMSSSSSMASXXAAXASMSXXMXSXSXSASMSMMSMSAMMMAMXAAMASXMMSXMXMMMXASAXMSAASAMXSAAMXSXMASAXMMXSMSMMAM",
+
~c"AAAXXXMASASXMXMAXXMMASAASMXSASASXAAAAMSSMMMSXMAAMMMMMXAXMMMMSAMXAMASAMXSAMASXXAXAAMAMXSAMXSXSMMASAMSMASAAMSMMSSXMAXASASMMSAMASAMAMSMAAXMASXM",
+
~c"MSMMXXMMMAMAMMMMMMXSAXXAMMMMXSAXMMXXAMXAAMMXMASXMAAASMMXAAMXAXAMMMAMAMAMAMXMASXMMXMAAXMAXMAMXMSAMASXMAXMSXMAMXXXMASAMAMAXMMMAAXXAAAMXSXMMMAS",
+
~c"MXAXAMXXMMMMSAMAASMMMSMMASASAMAMAXMSXMSMMXAMXAXMMSSXSASXSSSMAMSMXMXSAMSSSMAMXMXAMAXXMMSAXAXMMXMASMMMMSSMMASAMMAMSMMAMAXSMXXMSSSSSSMXAXMSSMMM",
+
~c"ASXMMXSAMXAASXXMXSAAAXASAMMMASMSSSMAAMMXMMSSMASAMAMMMAMMAXMAXMASXMAXMSAAASASAMXSSMXSAAXSSMXAAXXAXMAMXMAMSMMAXMAAAAMXMAMXASXAMAMXMXMMAXAAXAXS",
+
~c"MAASMAMMSSMMSMSSXSMMXSMMASMSXMAAASMMMMAAMAMAMXAXAASMSSMMMMXSMSXSMXSXMXMXMSXMASAMAAAMMMMMMXXXSXMASMXMXMMMSXMSAMASMSMAXMASAAMXMMSSMASXXMXMAXMA",
+
~c"SAMXMXSAXAMASMXAASXSMMAXXMASAMMMMMMXXXSXMASAMXMASXSAAMXXXMMXMXAXMAMAMXXAAMAXAMASMMMSMMXSMMMXMAAMXXAXSXSASASXSMAMAAXMMSMMXMAXSAAAMXSASMSSXSAS",
+
~c"MMXSSXMXSAMASXXMXMAXAXXMSMMMXSAMXXMSXMMASXSXSXXAXMMMMMXMAXAMXMMMMASAMXSMSSSMSMMMMMAXXMAXAAAAXXSXXSASXAMAXXMAXMAMSMMSASXMAXMXMMSXSAMXMAAXASAM",
+
~c"ASAMXAMXSXMAMMMXAMSSSMSAXXXMSXASASXXAASAMXMAMAMSXXAXASASASXXSAAAMASAMAXXAAAMXASXSMXXAMASMMSMSAMAMXXXMMMSMXMMMXMXAAAMXSASXSSSXAAAMMAMMMMMAMAM",
+
~c"MMMSSXMXMAMXMSMXMSAAAAMMMXMSMSMMAAMSSMXAMMMAMXMXXSXSMSAMXSMAMSXSXAXAMSMMMSMMSAMAXAMXXAXXXAAAMXXMMSMMMSAMXXSASASXSMMXMSAMAAAAMMSXMAAMAMAMXMAM",
+
~c"XXAXMASMSAMAAAAASMMMMXMASMMAAAXMAMAAMMMSAMSAMSAXMAAMMMAMXMMMMAXXAMXSMMSMAXXXXAMSMMSASMMMMSMXMSMMAAAAAMMMXMMAMASAMAAAXMSMMMMMXXMASXSSSSXSASAS",
+
~c"SASAMXMAMMSASMSMXASMMASXSASMSSXSAMMXAAAASASAMXMXAXMSASASMXAAMMSMMSAMXAAMASMMSMMXAXMXXAAXXAAASAAMSSSMSXMXSAMAMAMASMSMSAMXMMASMMXMMAAAAXASMSSM",
+
~c"XAMASXSXSASAXMXMSXMASAXASMSAAXXMAMSSSMSAXMMMSAMXMSASASAMAMMMSAAMAMASMSXSAXAMAMXMXMASXSMMSXSXMAXMAAXAMASXMAMXSXMXMXAXMAMAMAAAXMSXMMMMMMXMXXXM",
+
~c"MMMASMAAMMMAMASASAMXMASMMAMMMMMXMMXAMAMXMAAXMAXXXMAMXMMMSSMAMMXMXSXMAXMMMSSSXSMSAMXSAXMASMMMASXMXSXXXAMAXAMMSASMSSSMSASASMXSAMAMXXAASXMMSASX",
+
~c"AXMAXXMXMXSAMMMAMAMXMXAMXSMSXASASMMAMXMSSXMSXSAMXMXMMXSXAAXMASXMXAMSXSAAXXAXXXAAXAAMMMXXMAMMAMAAAMMSMSSMMSSMSAMAAAAASASASAMXXAXMMSAXSAAXMASX",
+
~c"SXMASXXXMAXASMMMMMSXMMASXAAXSXSXSASMMASMSAXMAXAMXXMAMASMSSMMAXAAASASASMMAAMMXMSMSMXSAMXMXSXMASMMMSAXMMAXSMAMMXMMMSMMMAMAMXMAMXMAMAMMSXMXMXMX",
+
~c"MAMMAMXAMXSSMMXAAXAMASAMXMMASXSXSAMMSMSAXMASASAMMMAAMAXAMXXMMSMMAASMAMMXMMXSAAAAXMASASMMAMXXMAAAXMXSSMXMAXAMXAMSMMMSMSMSMAMMSAXMASAAXMMASAAX",
+
~c"SAXSAXSXSXMMASMSSMXMMMASXXAAMMMAMAMAAMMMMAMMMMAMAASXMSSSXMAXMAXAXMXMSMAXXAASMMMSMXMSAMXMASMSSSSMMSAXMASAMSMSXMMAAAAAXAAXSAMMMMXXXMMXSMSASMSM",
+
~c"MAMAXMMMXAASAMAMMMMMSSMSXSMXSAMSMMMSXSASAAXAAMAMSMMAMAAMAMXMSASXSXXXXAMXMMXSMSMXMAMMAMXSASAAXAAAXMAMSAMAXAMSASMSSMSSSMMMSMSAAXSSSXSMXAMXSXMX",
+
~c"MSMSMMXSMSMMAXMASAMSAMXMASAAMXSAAXAMXSMSSSSSXSAXXXXAMMSMXXSXMASAXXMASAMXMSXXAAAASAXMAMMMMMMMMSAMMAMXMMXSMXMSAMAAAAXXMAXMXMSMMSAMAAMXSAMXXASM",
+
~c"AMAMAXAMXXXSXMXAXMXMASAMXMMMSMSXSMMSAMXXAXAAXAXMASMSMSMXXXAMMMMMMSMXSMMSAMXMSMSMSMSSMMMASXSSMMXSMAXMASAMXXXMMMMMMXMMSMMSAMXASMAMMSMMAAXXMASM",
+
~c"XMAMMMXSAMASMAMXSXXSAMAMSMMAAASMXXMAAASMXMMMMMXXXAAAMAMMMXMAAMAMAMXASAAAAMAAAAAMXMMASXSXMAMAAMAMXSXSAMXMAMXSXAMSMSAMAXAXAMAMMSSMXMXAXXMSAMXM",
+
~c"SMXSAAAMAMAMMSMAXAMMXSAMAAXSMXXASXSMSMAMXAAXMXMMMMSMMAMSAAXSXSAMAMXXSMMSASXSMSMSAMSAMMSAMXMSAMXSAXMMXMAXAMAAMAMAAAXSASMSSMXSAAXMASASAMXSAASM",
+
~c"AAAAMMSSXMASAAMSXSAMXSXSXSMXMASASAMXMAASASXMXAAXAXAASAXASXMMASXSASMMMXAXXMAAMXXXMMMXMAMAMXMXAMXSAXAXSXMXAMMXSAMMSMMMMSMAMXMMMSSMXAAXAAAMXMXM",
+
~c"MMMSAAXMMMSMMSSMAMMMMMMMMXAXSXSAMXMAXXXSXAAMSSSXMXSXMXSMMSAMAMAMXSAAAMXMAMMMMMSMSXSMMMXMMAXSAMAMASMXMASXSMMASXSAMXSAMXMAMAXASXXMMMMMMMXMMSSM",
+
~c"SAMAMMSMSMXAMMXMAMMSASASASAMMAMMMMMXMSAMXMXMAAMASMMXSMAXAXMMMMSMMMXSMSSSSSMAAAMMSAMMAMASXSMSAMXSASAXMAMAMAMMSAMXSASASXSMSMSXSXAMAAAAXSASAAXX",
+
~c"SMSMXXAAAAMMMMASASASASXMASAMXMAXAXSXMAAXMSXMAMXAMAMAMXSMMSXSXAAMXSMXXAAMAAMSMMSAMXMMASMSAMXSAMXMASXMMMSASAMAMXMAMASAMMSMAAXMMMSSSSSSSMAMMMMX",
+
~c"XAAXASMSMSMAAXXXAXMMMMAMAMAMXXSSMXXMAMXMAMASXSMMMAMAMMXXAAAXMSXSAMAAMMSMSSMMMAMXSAMSASAMXMASXMAMMMMAXMAXXMSAMXMAMXMAMAMMMXMSXAAMAAAXAMXMSASA",
+
~c"MXMXAMXAXMMSXSMMSMSSSSMMSSXMXXXAMXXSSSSMXSAMAMAAXSMMMAAMSMXXMAMMASASMAXMAAAAMMSASAXMSMXMXMASMXXXAAXMAMMAXMSXSASXSXSAMSSMSMASMMMSAMMMSXMXXASA",
+
~c"SASXSSSXMSXMAAAAXAAAXMASXMAAXXMSAMMAAAXAAMASAMMMAMASMSXAXXAXMSSSXMAXMXSMSSMMSMAXMMMXAMXXMXAXMASMSMXSAASMXAXXSAMSAASXMAAAXMAXXAASMAMAXAXXMMMM",
+
~c"SASAXAMXASAXSSSMMMMMMXMSASXMXMAXAXMMMMMMMMXAXXAMXXAMAMXSAMAMSAAXMMMMSXSAAXMASMMMMMXMMAMMAMSSMAXAAAASAMAAMSMXMSMMMMMMASMMXMMSMXMSSSMASMMAAAAA",
+
~c"MSMXMAMSSMMMXAAAXXMASMXSAMSAMXSMSMMASAAXMXAAMMXXSMSSXMXXASAMXMSMSAMXMAMMMMMMMMAAAAAAXMMAXXMMMMMSMMMSAXMMMMAXAXXAAAXXAXAMXAAAXMMMMMMAMMSXSMSS",
+
~c"SAMXSMMXXAAAMMMSAMXSMAAMAMMMXMXXAAMASXSXMSXSXSXASAMXAMXSXMAMMXMASASXMMMSXXSMMSSSSSSSSMSSSMXSAXXMAXAXXMXSAXMMMXSSSXMMSXMMSMSSSXSAAAMMXMXMMMXM",
+
~c"XAMMASMSSMMSMAAXXAXMXMMSMMASASXASXMASAMXXSAMAAMMMAMSAMAXMASXMAMMMAMXAMSMSXAAMXAAAAMAAAAAAAAMXXMXMMSSMSASMMXAXAXMAXSAMAMXSAMAAMASXMXMAMMSAXAM",
+
~c"SSMMSAMXAASMXMMSMMMSAMXXXSASASAXAAMAMAMMMMAMMXSASAMMAMXXXAXAMMSMSSSMSMSAXSSMMMMMMXMMMMMSMMMXMMAASAMAAMASAASXMMXMXXMAMXMMSAMMMMXASXSSXSASASMS",
+
~c"XAXSMMSSSMMXAMAAAAXMMSSMAXXMXMXSSXMXMAMAAMXMXASASASMSMXSAMXMMSAMMAAAXAMXMMMSMXSAMXSAAXXAMXSAASMMSAMMMMMMMMAAMAMSASMSMASASAMSMXSAMXAAAAXMAMAA",
+
~c"MXMXAAXMMMMSSMSSSSSMASAMSSMXXSAXAMMSSXSSSMSMMXMAMAMMXSAMXSAMXSASMSMMMSMMXMXAMXSAMXSSMMAMXAMMMMSASXMASMXSSMSSMASMASAXSMMASXMXMMAASMMMMMMMAMAM",
+
~c"MXXMMMSMXSAAAAAXAXAMMXAMAAAAMXXSAAAAXXMAMAXXMXMMMSMMXMXSASASASAMXXXAAXAMASAXMASXMMMMSMAXMMSXXAMMMMSAXSAMXAMXMMSMMMMXAXMAMXMASASMMAXSXSAMAXAX",
+
~c"MSMXAXXAAMMSMMMMSMSMMSMMXSMSXSMSXMMSMSMAMSMSMXMXMMAAMMXMASMMASAMXXSMXSXMAXAASASASXAAXXXMASAMMSMXMXMXSMXMMAMMMMXXXXXSMMMMSSXXAMMASMXAAMAMSMMS",
+
~c"AAASXMMMMSMAXXXAAMAAXSXSMXAMAAASAXMAXAAXMXAMXAXAMMXMAXAMMMMMAXAXMMXMXSAMASXXMASAMSMMAXMAMXASAMMSMAXMMMSASAMAAAAMXMXAXXXSAMMMMASAMXSMSMSMMAMX",
+
~c"SAXMSAAAAAMMMSMSSSMSMMAMAMAMXMSSMMMXASAMXMAMSMSXSSMSXMAXAAXMSSMMXMMSASMMMXXAMAMAMXMAXMASMSAMASASXSXSAAMXSAMSAMXAAAMMSMXMASAXSMMAMXAAMAXAMAMX",
+
~c"AMMASXMMSSSMASAMAAXXAMAMMSMMXXXXAAMXMMXXXMMMMAAAXMAXMASMSXSXAAXMAXSMAXXAXMSMMMSXMSMXMAXAMMMMAMXMAMAMMMSASMMXAXMSMSAMAMMSAMMXSAMAMXMSMMMSSSMM",
+
~c"SSMAMAMAMAAMAMAMXMMSAMXMXAAMAMMSSMSMXSXXMAXAMMMSMMSMXXMAXMSMSSMSXXAMSMSMSAMASAMXAAMSSSMSMAXAAXAMSMSMSXMASASMSMMAAXAMAMAMAMXMSAMXMMAMXXAAAAXX",
+
~c"MAMXSXMAMSMMXSXMASAMSMASMSSSMXAAXSAMAXMSSXSAMAAAAMMMSAMXMAXAXAMAXMXMXAMASXSAMASXMXSAAXAXSASMMSXSXAMAMXMXMXMAMMSASXSMSASMSMSXSMMAMMSMMMSSSMAA",
+
~c"SMMXMASAXMXMASASMSXSASMSAAAAMMMMSMMMMSMMAXAMSSSSXMAASXXMMAASMMMAXSAMMXMAMMMMSAMXMMMMSMMMMMSAASMMMSMAMSASMAMSMASAMAMAMAMAXXAAMXMSMMXAXMAAAXXM",
+
~c"XAMXXXASAMAMXSAMASMAMMXMXMMMMASXMMXSAAAMMAMMAXMMMSMAXMAXASMXAMMAXSASMSMASXSASAMMAAXAMMXAXASMMMAAAXXAMXAXMAMAMXMSMXMXMAMSMMMSMMMXAASAMAMSMMMM",
+
~c"SSMMSMAXXSXSAMAMAMAAXMAMXSMMSASMSMAMSSSMXMXMMSXAAXXAASMMMMASMMMXMSAMAAMXSXSAMAMXAMSASASASAMSXSSMSSSMMMAMSSSXSAAXMMMMSXMASXAXXXASMMMAAMXXXAAM",
+
...]
+
```
+
+
## Part 1
+
+
```elixir
+
defmodule CeresSearch do
+
def rows(rows), do: rows |> Enum.map(&count(&1, 0)) |> Enum.sum()
+
+
def count([], acc), do: acc
+
def count(~c"XMAS" ++ rest, acc), do: count([?S | rest], acc + 1)
+
def count(~c"SAMX" ++ rest, acc), do: count([?X | rest], acc + 1)
+
def count([_ | rest], acc), do: count(rest, acc)
+
+
def cols(rows) do
+
rows
+
|> Enum.zip()
+
|> Enum.map(&Tuple.to_list/1)
+
|> rows()
+
|> dbg()
+
end
+
+
def diagonals(rows) do
+
map =
+
for {row, x} <- Enum.with_index(rows),
+
{val, y} <- Enum.with_index(row),
+
into: %{},
+
do: {{y, x}, val}
+
+
{w, h} = Enum.max(Map.keys(map))
+
+
0..max(w, h)
+
|> gen_diagonals()
+
|> then(fn diags ->
+
Enum.map(diags, &extract(map, &1))
+
end)
+
|> rows()
+
end
+
+
def gen_diagonals(_..max//_ = range) do
+
d1 =
+
for n <- range do
+
for(
+
y <- 0..n,
+
x = n - y,
+
do: {y, x}
+
)
+
end
+
+
d2 =
+
for n <- range do
+
for(
+
y <- 0..n,
+
x = max - n + y,
+
do: {y, x}
+
)
+
end
+
+
diag1 = d1 ++ d2
+
+
diag2 =
+
Enum.map(diag1, fn d ->
+
Enum.map(d, fn {y, x} -> {max - y, x} end)
+
end)
+
+
Enum.uniq_by(diag1 ++ diag2, &Enum.sort/1)
+
end
+
+
def extract(map, keys) do
+
for key <- keys, val = map[key], do: val
+
end
+
+
def search_all(box) do
+
cols(box) + rows(box) + diagonals(box)
+
end
+
end
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:module, CeresSearch, <<70, 79, 82, 49, 0, 0, 31, ...>>, {:search_all, 1}}
+
```
+
+
```elixir
+
CeresSearch.search_all(search_box)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
2401
+
```
+
+
## Part 2
+
+
```elixir
+
map =
+
for {row, x} <- Enum.with_index(search_box),
+
{val, y} <- Enum.with_index(row),
+
into: %{},
+
do: {{y, x}, val}
+
+
Enum.count(map, fn
+
{{y, x}, ?A} ->
+
[map[{y + 1, x + 1}], map[{y - 1, x - 1}]] in [~c"MS", ~c"SM"] and
+
[map[{y - 1, x + 1}], map[{y + 1, x - 1}]] in [~c"MS", ~c"SM"]
+
_ ->
+
false
+
end)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
1822
+
```
+
+
<!-- livebook:{"offset":14266,"stamp":{"token":"XCP.T-RaxkkrFX_OdT79HvWI46TqX7It60uksnJ1LTiQVcPcCTg_ZZN1SjjXIgHd4F397ANKRpGPP5xOXl4FWp7rCtZ86gir5tQaVrJ8BqeDCy_3leOOuggQbLw1uB3x5qEdZBg","version":2}} -->
+373
2024/day05.livemd
···
+
<!-- livebook:{"persist_outputs":true} -->
+
+
# Day 05
+
+
```elixir
+
Mix.install([:kino_aoc])
+
```
+
+
## Section
+
+
<!-- livebook:{"attrs":"eyJhc3NpZ25fdG8iOiJwdXp6bGVfaW5wdXQiLCJkYXkiOiI1Iiwic2Vzc2lvbl9zZWNyZXQiOiJBRFZFTlRfT0ZfQ09ERV9TRVNTSU9OIiwieWVhciI6IjIwMjQifQ","chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2024", "5", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:ok,
+
"75|21\n28|29\n28|73\n95|48\n95|19\n95|16\n81|51\n81|95\n81|16\n81|56\n48|59\n48|83\n48|64\n48|57\n48|86\n15|43\n15|82\n15|49\n15|31\n15|35\n15|48\n83|68\n83|26\n83|56\n83|63\n83|64\n83|69\n83|84\n47|83\n47|29\n47|23\n47|18\n47|87\n47|53\n47|79\n47|59\n35|43\n35|34\n35|85\n35|28\n35|64\n35|94\n35|48\n35|79\n35|78\n34|65\n34|88\n34|87\n34|82\n34|45\n34|76\n34|47\n34|39\n34|49\n34|85\n92|15\n92|35\n92|59\n92|69\n92|34\n92|67\n92|26\n92|18\n92|73\n92|84\n92|19\n94|47\n94|83\n94|82\n94|85\n94|57\n94|48\n94|64\n94|28\n94|43\n94|76\n94|49\n94|88\n29|59\n29|51\n29|15\n29|73\n29|89\n29|66\n29|76\n29|75\n29|63\n29|53\n29|18\n29|62\n29|95\n69|94\n69|56\n69|66\n69|43\n69|85\n69|63\n69|82\n69|57\n69|78\n69|15\n69|34\n69|31\n69|35\n69|16\n63|78\n63|65\n63|43\n63|27\n63|66\n63|23\n63|62\n63|35\n63|34\n63|48\n63|56\n63|19\n63|94\n63|85\n63|57\n31|92\n31|28\n31|53\n31|49\n31|64\n31|59\n31|26\n31|47\n31|23\n31|76\n31|89\n31|79\n31|81\n31|83\n31|86\n31|45\n56|86\n56|43\n56|65\n56|57\n56|82\n56|47\n56|85\n56|48\n56|62\n56|31\n56|78\n56|35\n56|16\n56|87\n56|23\n56|95\n56|34\n23|76\n23|29\n23|39\n23|53\n23|45\n23|26\n23|27\n23|28\n23|79\n23|21\n23|84\n23|83\n23|73\n23|86\n23|81\n23|59\n23|68\n23|89\n65|53\n65|48\n65|87\n65|88\n65|27\n65|28\n65|49\n65|45\n65|82\n65|43\n65|29\n65|39\n65|76\n65|85\n65|64\n65|23\n65|31\n65|79\n65|92\n45|68\n45|59\n45|69\n45|73\n45|53\n45|21\n45|81\n45|62\n45|56\n45|15\n45|95\n45|35\n45|63\n45|51\n45|26\n45|19\n45|92\n45|66\n45|89\n45|78\n76|73\n76|51\n76|18\n76|75\n76|95\n76|66\n76|56\n76|69\n76|81\n76|21\n76|67\n76|26\n76|53\n76|92\n76|89\n76|35\n76|63\n76|19\n76|62\n76|59\n76|45\n53|92\n53|21\n53|18\n53|94\n53|67\n53|68\n53|69\n53|63\n53|66\n53|84\n53|34\n53|59\n53|89\n53|73\n53|78\n53|81\n53|19\n53|35\n53|26\n53|56\n53|15\n53|51\n51|47\n51|15\n51|69\n51|65\n51|94\n51|66\n51|31\n51|95\n51|43\n51|35\n51|78\n51|82\n51|85\n51|48\n51|23\n51|63\n51|34\n51|16\n51|88\n51|67\n51|62\n51|19\n51|56\n79|84\n79|28\n79|69\n79|45\n79|92\n79|83\n79|29\n79|53\n79|64\n79|76\n79|89\n79|51\n79|68\n79|39\n79|26\n79|81\n79|21\n79|63\n79|62\n79|59\n79|75\n79|56\n79|73\n79|18\n19|35\n19|48\n19|82\n19|94\n19|57\n19|78\n19|43\n19|79\n19|83\n19|31\n19|64\n19|23\n19|47\n19|67\n19|28\n19|85\n19|27\n19|86\n19|34\n19|65\n19|87\n19|88\n19|16\n19|49\n82|27\n82|68\n82|83\n82|39\n82|28\n82|73\n82|92\n82|49\n82|75\n82|89\n82|31\n82|45\n82|47\n82|18\n82|87\n82|53\n82|79\n82|23\n82|86\n82|81\n82|29\n82|59\n82|64\n82|76\n21|34\n21|19\n21|78\n21|57\n21|82\n21|51\n21|66\n21|35\n21|95\n21|62\n21|48\n21|84\n21|65\n21|69\n21|31\n21|56\n21|15\n21|67\n21|85\n21|16\n21|88\n21|94\n21|63\n21|43\n88|27\n88|29\n88|64\n88|75\n88|31\n88|59\n88|76\n88|39\n88|47\n88|28\n88|87\n88|23\n88|83\n88|81\n88|53\n88|86\n88|45\n88|18\n88|92\n88|79\n88|49\n88|57\n88|82\n88|89\n86|18\n86|28\n86|73\n86|75\n86|59\n86|26\n86|21\n86|69\n86|76\n86|79\n86|51\n86|92\n86|45\n86|83\n86|64\n86|49\n86|81\n86|68\n86|39\n86|53\n86|29\n86|84\n86|63\n86|89\n43|59\n43|64\n43|87\n43|47\n43|49\n43|57\n43|31\n43|86\n43|39\n43|27\n43|53\n43|88\n43|83\n43|89\n43|81\n43|79\n43|75\n43|82\n43|23\n43|76\n43|29\n43|28\n43|92\n43|45\n26|15\n26|82\n26|78\n26|67\n26|57\n26|88\n26|35\n26|43\n26|85\n26|21\n26|48\n26|84\n26|69\n26|62\n26|34\n26|19\n26|66\n26|65\n26|51\n26|16\n26|95\n26|94\n26|63\n26|56\n68|85\n68|65\n68|95\n68|35\n68|78\n68|67\n68|57\n68|51\n68|62\n68|56\n68|34\n68|21\n68|63\n68|88\n68|15\n68|48\n68|43\n68|26\n68|66\n68|84\n68|94\n68|19\n68|69\n68|16\n85|64\n85|27\n85|82\n85|43\n85|53\n85|48\n85|57\n85|86\n85|88\n85|29\n85|47\n85|87\n85|83\n85|75\n85|76\n85|28\n85|81\n85|49\n85|45\n85|39\n85|92\n85|31\n85|23\n85|79\n39|84\n39|76\n39|59\n39|67\n39|62\n39|92\n39|81\n39|69\n39|66\n39|26\n39|15\n39|75\n39|95\n39|63\n39|21\n39|73\n39|45\n39|51\n39|89\n39|53\n39|56\n39|68\n39|19\n39|18\n78|48\n78|87\n78|34\n78|29\n78|28\n78|79\n78|76\n78|43\n78|39\n78|85\n78|88\n78|49\n78|27\n78|86\n78|94\n78|64\n78|31\n78|83\n78|82\n78|16\n78|23\n78|47\n78|65\n78|57\n87|83\n87|26\n87|51\n87|29\n87|79\n87|45\n87|68\n87|75\n87|73\n87|21\n87|53\n87|81\n87|84\n87|39\n87|89\n87|92\n87|76\n87|59\n87|18\n87|86\n87|69\n87|49\n87|64\n87|28\n18|69\n18|95\n18|73\n18|16\n18|48\n18|21\n18|68\n18|85\n18|62\n18|34\n18|19\n18|65\n18|15\n18|94\n18|63\n18|51\n18|66\n18|84\n18|67\n18|43\n18|35\n18|26\n18|56\n18|78\n84|95\n84|62\n84|48\n84|35\n84|57\n84|31\n84|16\n84|78\n84|65\n84|88\n84|67\n84|34\n84|19\n84|43\n84|69\n84|15\n84|94\n84|63\n84|51\n84|66\n84|47\n84|56\n84|85\n84|82\n59|34\n59|69\n59|89\n59|19\n59|62\n59|84\n59|68\n59|73\n59|26\n59|66\n59|94\n59|67\n59|21\n59|85\n59|18\n59|95\n59|16\n59|15\n59|63\n59|56\n59|35\n59|51\n59|78\n59|65\n67|88\n67|27\n67|16\n67|28\n67|79\n67|64\n67|65\n67|29\n67|47\n67|83\n67|34\n67|48\n67|49\n67|43\n67|94\n67|23\n67|85\n67|35\n67|31\n67|82\n67|57\n67|87\n67|8" <> ...}
+
```
+
+
```elixir
+
[orderings, jobs] = String.split(puzzle_input, "\n\n", parts: 2)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
["75|21\n28|29\n28|73\n95|48\n95|19\n95|16\n81|51\n81|95\n81|16\n81|56\n48|59\n48|83\n48|64\n48|57\n48|86\n15|43\n15|82\n15|49\n15|31\n15|35\n15|48\n83|68\n83|26\n83|56\n83|63\n83|64\n83|69\n83|84\n47|83\n47|29\n47|23\n47|18\n47|87\n47|53\n47|79\n47|59\n35|43\n35|34\n35|85\n35|28\n35|64\n35|94\n35|48\n35|79\n35|78\n34|65\n34|88\n34|87\n34|82\n34|45\n34|76\n34|47\n34|39\n34|49\n34|85\n92|15\n92|35\n92|59\n92|69\n92|34\n92|67\n92|26\n92|18\n92|73\n92|84\n92|19\n94|47\n94|83\n94|82\n94|85\n94|57\n94|48\n94|64\n94|28\n94|43\n94|76\n94|49\n94|88\n29|59\n29|51\n29|15\n29|73\n29|89\n29|66\n29|76\n29|75\n29|63\n29|53\n29|18\n29|62\n29|95\n69|94\n69|56\n69|66\n69|43\n69|85\n69|63\n69|82\n69|57\n69|78\n69|15\n69|34\n69|31\n69|35\n69|16\n63|78\n63|65\n63|43\n63|27\n63|66\n63|23\n63|62\n63|35\n63|34\n63|48\n63|56\n63|19\n63|94\n63|85\n63|57\n31|92\n31|28\n31|53\n31|49\n31|64\n31|59\n31|26\n31|47\n31|23\n31|76\n31|89\n31|79\n31|81\n31|83\n31|86\n31|45\n56|86\n56|43\n56|65\n56|57\n56|82\n56|47\n56|85\n56|48\n56|62\n56|31\n56|78\n56|35\n56|16\n56|87\n56|23\n56|95\n56|34\n23|76\n23|29\n23|39\n23|53\n23|45\n23|26\n23|27\n23|28\n23|79\n23|21\n23|84\n23|83\n23|73\n23|86\n23|81\n23|59\n23|68\n23|89\n65|53\n65|48\n65|87\n65|88\n65|27\n65|28\n65|49\n65|45\n65|82\n65|43\n65|29\n65|39\n65|76\n65|85\n65|64\n65|23\n65|31\n65|79\n65|92\n45|68\n45|59\n45|69\n45|73\n45|53\n45|21\n45|81\n45|62\n45|56\n45|15\n45|95\n45|35\n45|63\n45|51\n45|26\n45|19\n45|92\n45|66\n45|89\n45|78\n76|73\n76|51\n76|18\n76|75\n76|95\n76|66\n76|56\n76|69\n76|81\n76|21\n76|67\n76|26\n76|53\n76|92\n76|89\n76|35\n76|63\n76|19\n76|62\n76|59\n76|45\n53|92\n53|21\n53|18\n53|94\n53|67\n53|68\n53|69\n53|63\n53|66\n53|84\n53|34\n53|59\n53|89\n53|73\n53|78\n53|81\n53|19\n53|35\n53|26\n53|56\n53|15\n53|51\n51|47\n51|15\n51|69\n51|65\n51|94\n51|66\n51|31\n51|95\n51|43\n51|35\n51|78\n51|82\n51|85\n51|48\n51|23\n51|63\n51|34\n51|16\n51|88\n51|67\n51|62\n51|19\n51|56\n79|84\n79|28\n79|69\n79|45\n79|92\n79|83\n79|29\n79|53\n79|64\n79|76\n79|89\n79|51\n79|68\n79|39\n79|26\n79|81\n79|21\n79|63\n79|62\n79|59\n79|75\n79|56\n79|73\n79|18\n19|35\n19|48\n19|82\n19|94\n19|57\n19|78\n19|43\n19|79\n19|83\n19|31\n19|64\n19|23\n19|47\n19|67\n19|28\n19|85\n19|27\n19|86\n19|34\n19|65\n19|87\n19|88\n19|16\n19|49\n82|27\n82|68\n82|83\n82|39\n82|28\n82|73\n82|92\n82|49\n82|75\n82|89\n82|31\n82|45\n82|47\n82|18\n82|87\n82|53\n82|79\n82|23\n82|86\n82|81\n82|29\n82|59\n82|64\n82|76\n21|34\n21|19\n21|78\n21|57\n21|82\n21|51\n21|66\n21|35\n21|95\n21|62\n21|48\n21|84\n21|65\n21|69\n21|31\n21|56\n21|15\n21|67\n21|85\n21|16\n21|88\n21|94\n21|63\n21|43\n88|27\n88|29\n88|64\n88|75\n88|31\n88|59\n88|76\n88|39\n88|47\n88|28\n88|87\n88|23\n88|83\n88|81\n88|53\n88|86\n88|45\n88|18\n88|92\n88|79\n88|49\n88|57\n88|82\n88|89\n86|18\n86|28\n86|73\n86|75\n86|59\n86|26\n86|21\n86|69\n86|76\n86|79\n86|51\n86|92\n86|45\n86|83\n86|64\n86|49\n86|81\n86|68\n86|39\n86|53\n86|29\n86|84\n86|63\n86|89\n43|59\n43|64\n43|87\n43|47\n43|49\n43|57\n43|31\n43|86\n43|39\n43|27\n43|53\n43|88\n43|83\n43|89\n43|81\n43|79\n43|75\n43|82\n43|23\n43|76\n43|29\n43|28\n43|92\n43|45\n26|15\n26|82\n26|78\n26|67\n26|57\n26|88\n26|35\n26|43\n26|85\n26|21\n26|48\n26|84\n26|69\n26|62\n26|34\n26|19\n26|66\n26|65\n26|51\n26|16\n26|95\n26|94\n26|63\n26|56\n68|85\n68|65\n68|95\n68|35\n68|78\n68|67\n68|57\n68|51\n68|62\n68|56\n68|34\n68|21\n68|63\n68|88\n68|15\n68|48\n68|43\n68|26\n68|66\n68|84\n68|94\n68|19\n68|69\n68|16\n85|64\n85|27\n85|82\n85|43\n85|53\n85|48\n85|57\n85|86\n85|88\n85|29\n85|47\n85|87\n85|83\n85|75\n85|76\n85|28\n85|81\n85|49\n85|45\n85|39\n85|92\n85|31\n85|23\n85|79\n39|84\n39|76\n39|59\n39|67\n39|62\n39|92\n39|81\n39|69\n39|66\n39|26\n39|15\n39|75\n39|95\n39|63\n39|21\n39|73\n39|45\n39|51\n39|89\n39|53\n39|56\n39|68\n39|19\n39|18\n78|48\n78|87\n78|34\n78|29\n78|28\n78|79\n78|76\n78|43\n78|39\n78|85\n78|88\n78|49\n78|27\n78|86\n78|94\n78|64\n78|31\n78|83\n78|82\n78|16\n78|23\n78|47\n78|65\n78|57\n87|83\n87|26\n87|51\n87|29\n87|79\n87|45\n87|68\n87|75\n87|73\n87|21\n87|53\n87|81\n87|84\n87|39\n87|89\n87|92\n87|76\n87|59\n87|18\n87|86\n87|69\n87|49\n87|64\n87|28\n18|69\n18|95\n18|73\n18|16\n18|48\n18|21\n18|68\n18|85\n18|62\n18|34\n18|19\n18|65\n18|15\n18|94\n18|63\n18|51\n18|66\n18|84\n18|67\n18|43\n18|35\n18|26\n18|56\n18|78\n84|95\n84|62\n84|48\n84|35\n84|57\n84|31\n84|16\n84|78\n84|65\n84|88\n84|67\n84|34\n84|19\n84|43\n84|69\n84|15\n84|94\n84|63\n84|51\n84|66\n84|47\n84|56\n84|85\n84|82\n59|34\n59|69\n59|89\n59|19\n59|62\n59|84\n59|68\n59|73\n59|26\n59|66\n59|94\n59|67\n59|21\n59|85\n59|18\n59|95\n59|16\n59|15\n59|63\n59|56\n59|35\n59|51\n59|78\n59|65\n67|88\n67|27\n67|16\n67|28\n67|79\n67|64\n67|65\n67|29\n67|47\n67|83\n67|34\n67|48\n67|49\n67|43\n67|94\n67|23\n67|85\n67|35\n67|31\n67|82\n67|57\n67|87\n67|8" <> ...,
+
"94,68,73,78,15,65,43,66,62\n34,65,85,48,82,47,23,87,49,79,83,28,29\n57,82,27,87,83,28,29,39,76,45,75,53,92,81,18\n29,86,68,39,81,45,75,76,31,53,64,23,92\n31,28,83,49,87,79,82,64,16,48,86\n45,89,73,53,59,68,28,83,86,79,69,76,39\n31,19,88,35,23,43,86,79,48,16,57,82,27,87,67,65,78,34,49,47,66\n31,47,23,27,87,49,79,83,28,64,29,76,45,75,53,81,59,89,18,73,68\n26,95,73,56,81,89,59,34,92,94,21\n16,63,34,19,66,65,47,56,31,82,51,85,57,67,88,62,48,78,95,35,15\n62,15,66,95,19,67,35,78,94,16,65,48,43,88,82,31,47,23,27,87,86\n62,15,66,95,67,35,34,16,65,43,88,82,31,47,86\n28,68,83,31,59,89,29,73,39,75,92,86,76,45,49,64,18,81,87,27,79,23,47\n81,78,26,16,59,62,51,19,21,56,68,94,18,73,69,35,89,84,66\n83,76,75,53,92,81,73,26,63,56,62\n53,27,29,79,28,88,85,31,47\n29,75,43,31,83,57,49,27,48,64,23,87,86,76,79,53,45\n63,27,43,95,78,56,34\n83,59,89,81,18,84,68,76,69,26,62,63,56,75,73,92,64,53,28,51,29\n75,53,92,18,73,68,26,51,69,63,15,19,67,35,78\n48,31,23,27,87,86,28,64,29,76,75\n16,51,62,43,15,68,78,65,88,19,34,85,26,48,95,94,67,56,84,69,66\n65,82,23,87,86,75,48,49,31,16,57,45,43,47,29\n29,76,45,75,81,18,73,21,56,62,95\n18,67,21,15,63,59,84,66,69,26,34,68,35,95,81,92,19\n49,79,39,76,53,92,59,89,18,68,51,69,63\n85,15,43,62,84,88,57,16,31,95,69\n21,51,43,16,94,78,19\n87,86,49,79,83,28,39,76,45,53,92,89,18,68,26,21,51\n51,69,62,35,88,15,16,21,48,57,26,78,65,43,34,95,19\n49,78,16,94,31,23,65\n87,83,29,45,59,73,51\n34,94,16,85,48,43,88,57,82,23,87,86,79,83,28,29,76\n84,51,69,63,56,62,15,66,95,19,67,35,78,34,94,85,43,88,57,82,31\n53,69,49,84,51,89,28,63,29\n83,21,64,68,75,59,87,45,76,23,29,73,18,27,28,81,26,53,86,89,39,92,79\n62,15,67,35,16,43,86\n88,31,23,83,39\n27,87,86,49,83,64,39,76,75,53,89,73,26,21,84\n53,81,21,51,63,15,95,35,34\n95,51,31,84,15,94,43\n92,76,59,63,73,64,84,81,28,75,15,29,68,62,69\n89,18,62,15,94,65,85\n92,68,63,95,67,78,94\n94,68,95,84,16,63,15,35,26,34,62,73,19,51,56,67,18,21,69,65,66,59,78\n35,34,16,65,48,27,86,83,29\n15,66,95,67,34,94,85,48,43,82,23\n69,63,56,66,95,19,67,35,78,34,94,16,65,85,48,43,23\n85,27,66,19,43,62,86\n65,85,48,43,82,31,47,49,79,28,39,76,45,75,53\n86,49,79,64,39,76,45,75,59,89,84,51,69\n92,81,59,89,18,73,26,21,84,51,69,63,56,62,15,66,95,19,67,35,78,34,94\n26,84,69,63,56,62,66,19,67,78,34,94,16,85,43,88,57\n21,89,19,84,94,35,68,65,18,51,16,63,59,67,34,56,73,78,15,69,95,66,26\n83,23,39,27,76,47,49,29,48,86,82,53,88,64,92,75,81,45,31,43,57\n34,94,16,65,48,57,82,31,23,27,83,28,76\n95,51,62,63,16,34,65,66,69,19,57,82,47\n82,57,84,65,78,31,16,67,66\n64,39,92,81,89,69,66\n59,95,18,68,15,34,35,51,19,92,66,56,94,81,73,62,78\n83,28,64,29,39,76,45,75,53,92,81,89,73,68,26,21,51,69,63,56,62\n66,73,39,64,56,76,59\n68,26,69,56,85,43,88\n67,35,78,94,16,65,48,88,57,82,47,23,49,79,83,28,64\n92,81,26,51,69,63,62,15,95,19,78,34,94\n81,59,73,68,26,51,63,56,15,95,35,34,16\n79,83,64,45,53,81,68,26,84,51,69,63,56\n89,53,84,39,62,63,51,75,64,81,26,18,69,83,45,29,56\n82,87,39,88,23,57,48,85,76,83,92,47,43\n48,43,57,27,87,79,83,76,45,75,53,92,81\n82,81,75,39,88\n43,88,57,82,31,47,23,27,87,86,49,79,83,28,64,29,39,76,45,75,53,81,59\n88,87,86,49,79,83,28,39,76,45,92,81,89\n59,76,29,23,89,79,31,73,45,82,87,92,86\n66,95,19,67,35,78,34,94,16,85,48,43,88,57,82,31,47,23,27,87,86,49,79\n23,27,86,79,83,28,64,29,39,76,45,92,59,89,73,68,21\n23,31,39,53,89,64,79,73,59,45,92\n63,85,66,35,65,15,31,62,95\n35,88,31,78,23,87,15,49,95,27,57\n79,83,28,64,29,76,45,75,53,92,81,59,89,68,26,21,51,69,63\n43,16,73,34,19,66,62\n84,51,56,62,95,67,78,34,85,48,57,82,31\n76,45,75,53,92,81,59,18,73,26,21,51,69,63,56,15,66,95,19\n49,79,83,28,64,29,39,45,75,53,92,81,59,89,18,73,68,26,21,84,51,69,63\n63,51,34,19,15,65,31,57,48,95,88,66,56,67,62,16,35,94,78,84,43\n45,48,83,43,65,29,94,82,76,23,39\n83,49,47,45,88,64,85,28,27\n31,19,35,16,49,88,65,43,48,83,94,67,28\n84,65,88,51,85,43,78,19,21,69,48,66,15,35,68\n21,15,66,19,35,78,94,16,65,88,57\n19,67,78,34,94,65,85,48,43,88,57,47,23,27,87,86,49,83,28\n67,82,87,48,23,65,43,19,95,56,66,35,16\n88,82,31,47,23,27,87,86,49,79,83,28,64,29,39,76,45,53,81,59,89\n92,81,59,73,68,26,21,84,51,69,63,56,15,66,95,19,67,35,78,34,94\n79,76,29,21,68,86,83,53,59,26,49,89,27,87,45,28,81\n49,79,83,28,64,29,39,76,45,75,53,92,81,59,8" <> ...]
+
```
+
+
```elixir
+
orderings =
+
orderings
+
|> String.split("\n", trim: true)
+
|> Enum.map(fn row ->
+
row
+
|> String.split("|")
+
|> Enum.map(&String.to_integer/1)
+
|> List.to_tuple()
+
end)
+
+
prev =
+
orderings
+
|> Enum.group_by(&elem(&1, 1), &elem(&1, 0))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
%{
+
73 => [28, 92, 29, 23, 45, 76, 53, 79, 82, 86, 39, 87, 18, 59, 57, 64, 89, 49, 27, 75, 81, 83, 47,
+
31],
+
23 => [47, 63, 31, 56, 65, 51, 19, 82, 88, 43, 85, 78, 67, 57, 16, 62, 66, 95, 48, 15, 35, 34, 94,
+
69],
+
29 => [28, 47, 23, 65, 79, 82, 88, 86, 43, 85, 78, 87, 67, 57, 64, 16, 49, 27, 48, 83, 35, 34, 94,
+
31],
+
47 => [34, 94, 31, 56, 51, 19, 82, 88, 43, 85, 78, 84, 67, 57, 16, 62, 66, 95, 48, 15, 35, 69, 63,
+
65],
+
89 => [29, 31, 23, 45, 76, 53, 79, 82, 88, 86, 43, 39, 87, 59, 57, 64, 49, 27, 75, 28, 81, 83, 47,
+
92],
+
43 => [15, 35, 94, 69, 63, 56, 65, 51, 19, 21, 26, 68, 85, 78, 18, 84, 67, 73, 16, 62, 66, 95, 48,
+
34],
+
39 => [34, 23, 65, 79, 82, 88, 86, 43, 85, 78, 87, 57, 64, 16, 49, 27, 28, 48, 83, 47, 35, 94, 29,
+
31],
+
45 => [34, 31, 23, 65, 76, 79, 82, 88, 86, 43, 85, 39, 87, 57, 64, 16, 49, 27, 28, 48, 83, 47, 94,
+
29],
+
48 => [95, 15, 35, 94, 63, 56, 65, 51, 19, 21, 26, 68, 85, 78, 18, 84, 67, 73, 16, 89, 62, 66, 34,
+
69],
+
57 => [48, 94, 69, 63, 56, 19, 21, 88, 43, 26, 68, 85, 78, 84, 67, 16, 62, 66, 95, 15, 35, 34, 65,
+
51],
+
26 => [83, 92, 31, 23, 45, 76, 53, 79, 86, 68, 39, 87, 18, 59, 73, 64, 89, 49, 27, 75, 28, 81, 47,
+
29],
+
69 => [83, 92, 45, 76, 53, 51, 79, 21, 86, 26, 68, 39, 87, 18, 84, 59, 73, 64, 89, 49, 75, 28, 81,
+
29],
+
88 => [34, 94, 65, 51, 19, 21, 43, 26, 68, 85, 78, 84, 67, 73, 16, 62, 66, 95, 48, 15, 35, 69, 63,
+
56],
+
63 => [83, 29, 69, 45, 76, 53, 51, 79, 21, 86, 26, 68, 39, 18, 84, 59, 73, 64, 89, 49, 75, 28, 81,
+
92],
+
31 => [15, 69, 56, 65, 51, 19, 82, 21, 88, 43, 85, 78, 84, 67, 57, 16, 62, 66, 95, 48, 35, 34, 94,
+
63],
+
81 => [31, 23, 45, 76, 53, 79, 82, 88, 86, 43, 85, 39, 87, 57, 64, 49, 27, 75, 28, 48, 83, 47, 92,
+
29],
+
76 => [34, 94, 29, 31, 23, 65, 79, 82, 88, 86, 43, 85, 39, 78, 87, 57, 64, 16, 49, 27, 28, 48, 83,
+
47],
+
34 => [35, 92, 69, 63, 56, 53, 51, 19, 21, 26, 68, 78, 18, 84, 59, 67, 73, 89, 62, 66, 75, 95, 81,
+
15],
+
28 => [35, 94, 31, 23, 65, 79, 19, 82, 88, 86, 43, 85, 78, 87, 67, 57, 16, 49, 27, 95, 48, 83, 47,
+
34],
+
85 => [35, 34, 94, 69, 63, 56, 65, 51, 19, 21, 26, 68, 78, 18, 84, 59, 67, 73, 16, 89, 62, 66, 95,
+
15],
+
64 => [48, 83, 35, 94, 31, 65, 79, 19, 82, 88, 86, 43, 85, 78, 87, 67, 57, 16, 49, 27, 28, 47, 34,
+
23],
+
68 => [83, 23, 45, 53, 79, 82, 86, 39, 87, 18, 59, 73, 64, 89, 49, 27, 75, 28, 81, 47, 92, 29, 31,
+
76],
+
86 => [48, 31, 56, 23, 19, 82, 88, 43, 85, 78, 87, 67, 57, 16, 27, 62, 66, 95, 15, 47, 35, 34, 94,
+
65],
+
51 => [81, 29, 45, 76, 53, 79, 21, 86, 26, 68, 39, 87, 18, 84, 59, 73, 64, 89, 49, 27, 75, 28, 83,
+
92],
+
59 => [48, 47, 92, 29, 31, 23, 45, 76, 53, 79, 82, 88, 86, 43, 39, 87, 57, 64, 49, 27, 75, 28, 81,
+
83],
+
95 => [81, 29, 56, 45, 76, 51, 21, 26, 68, 39, 18, 84, 59, 73, 64, 89, 62, 66, 75, 15, 92, 69, 63,
+
53],
+
78 => [35, 69, 63, 56, 45, 53, 51, 19, 21, 26, 68, 18, 84, 59, 67, 73, 89, 62, 66, 75, 95, 81, 15,
+
...],
+
15 => [92, 29, 69, 45, 53, 51, 21, 26, 68, 39, 18, 84, 59, 73, 64, 89, 62, 75, 28, 81, 83, 63,
+
...],
+
83 => [48, 47, 94, 31, 23, 79, 19, 82, 88, 86, 43, 85, 78, 87, 67, 57, 16, 49, 27, 66, 95, ...],
+
75 => [29, 76, 79, 82, 88, 86, 43, 85, 39, 87, 57, 64, 16, 49, 27, 28, 48, 83, 47, 94, ...],
+
87 => [47, 34, 56, 65, 19, 82, 88, 43, 85, 78, 67, 57, 16, 27, 62, 66, 95, 48, 15, ...],
+
21 => [75, 23, 45, 76, 53, 79, 86, 26, 68, 39, 87, 18, 59, 73, 64, 89, 49, 27, ...],
+
82 => [15, 34, 94, 69, 56, 65, 51, 19, 21, 88, 43, 26, 85, 78, 84, 67, 57, ...],
+
53 => [47, 29, 31, 23, 65, 45, 76, 79, 82, 88, 86, 43, 85, 39, 87, 57, ...],
+
66 => [29, 69, 63, 45, 76, 53, 51, 21, 26, 68, 39, 18, 84, 59, 73, ...],
+
35 => [15, 92, 69, 63, 56, 45, 76, 53, 51, 19, 21, 26, 68, 18, ...],
+
56 => [81, 83, 69, 63, 45, 76, 53, 51, 79, 21, 26, 68, 39, ...],
+
62 => [29, 63, 56, 45, 76, 51, 79, 21, 26, 68, 39, 18, ...],
+
49 => [15, 34, 94, 31, 65, 19, 82, 88, 86, 43, 85, ...],
+
27 => [63, 23, 65, 19, 82, 88, 43, 85, 78, 67, ...],
+
84 => [83, 92, 23, 53, 79, 21, 86, 26, 68, ...],
+
94 => [35, 69, 63, 53, 51, 19, 21, 26, ...],
+
92 => [31, 65, 45, 76, 53, 79, 82, ...],
+
19 => [95, 92, 63, 45, 76, 53, ...],
+
67 => [92, 76, 53, 51, 19, ...],
+
65 => [34, 63, 56, 51, ...],
+
18 => [47, 92, 29, ...],
+
79 => [47, 35, ...],
+
16 => [95, ...]
+
}
+
```
+
+
```elixir
+
jobs =
+
jobs
+
|> String.split("\n", trim: true)
+
|> Enum.map(fn row ->
+
row
+
|> String.split(",")
+
|> Enum.map(&String.to_integer/1)
+
end)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
[
+
[94, 68, 73, 78, 15, 65, 43, 66, 62],
+
[34, 65, 85, 48, 82, 47, 23, 87, 49, 79, 83, 28, 29],
+
[57, 82, 27, 87, 83, 28, 29, 39, 76, 45, 75, 53, 92, 81, 18],
+
[29, 86, 68, 39, 81, 45, 75, 76, 31, 53, 64, 23, 92],
+
[31, 28, 83, 49, 87, 79, 82, 64, 16, 48, 86],
+
[45, 89, 73, 53, 59, 68, 28, 83, 86, 79, 69, 76, 39],
+
[31, 19, 88, 35, 23, 43, 86, 79, 48, 16, 57, 82, 27, 87, 67, 65, 78, 34, 49, 47, 66],
+
[31, 47, 23, 27, 87, 49, 79, 83, 28, 64, 29, 76, 45, 75, 53, 81, 59, 89, 18, 73, 68],
+
[26, 95, 73, 56, 81, 89, 59, 34, 92, 94, 21],
+
[16, 63, 34, 19, 66, 65, 47, 56, 31, 82, 51, 85, 57, 67, 88, 62, 48, 78, 95, 35, 15],
+
[62, 15, 66, 95, 19, 67, 35, 78, 94, 16, 65, 48, 43, 88, 82, 31, 47, 23, 27, 87, 86],
+
[62, 15, 66, 95, 67, 35, 34, 16, 65, 43, 88, 82, 31, 47, 86],
+
[28, 68, 83, 31, 59, 89, 29, 73, 39, 75, 92, 86, 76, 45, 49, 64, 18, 81, 87, 27, 79, 23, 47],
+
[81, 78, 26, 16, 59, 62, 51, 19, 21, 56, 68, 94, 18, 73, 69, 35, 89, 84, 66],
+
[83, 76, 75, 53, 92, 81, 73, 26, 63, 56, 62],
+
[53, 27, 29, 79, 28, 88, 85, 31, 47],
+
[29, 75, 43, 31, 83, 57, 49, 27, 48, 64, 23, 87, 86, 76, 79, 53, 45],
+
~c"?\e+_N8\"",
+
[83, 59, 89, 81, 18, 84, 68, 76, 69, 26, 62, 63, 56, 75, 73, 92, 64, 53, 28, 51, 29],
+
[75, 53, 92, 18, 73, 68, 26, 51, 69, 63, 15, 19, 67, 35, 78],
+
[48, 31, 23, 27, 87, 86, 28, 64, 29, 76, 75],
+
[16, 51, 62, 43, 15, 68, 78, 65, 88, 19, 34, 85, 26, 48, 95, 94, 67, 56, 84, 69, 66],
+
[65, 82, 23, 87, 86, 75, 48, 49, 31, 16, 57, 45, 43, 47, 29],
+
[29, 76, 45, 75, 81, 18, 73, 21, 56, 62, 95],
+
[18, 67, 21, 15, 63, 59, 84, 66, 69, 26, 34, 68, 35, 95, 81, 92, 19],
+
[49, 79, 39, 76, 53, 92, 59, 89, 18, 68, 51, 69, 63],
+
[85, 15, 43, 62, 84, 88, 57, 16, 31, 95, 69],
+
[21, 51, 43, 16, 94, 78, 19],
+
[87, 86, 49, 79, 83, 28, 39, 76, 45, 53, 92, 89, 18, 68, 26, 21, 51],
+
[51, 69, 62, 35, 88, 15, 16, 21, 48, 57, 26, 78, 65, 43, 34, 95, 19],
+
[49, 78, 16, 94, 31, 23, 65],
+
[87, 83, 29, 45, 59, 73, 51],
+
[34, 94, 16, 85, 48, 43, 88, 57, 82, 23, 87, 86, 79, 83, 28, 29, 76],
+
[84, 51, 69, 63, 56, 62, 15, 66, 95, 19, 67, 35, 78, 34, 94, 85, ...],
+
[53, 69, 49, 84, 51, 89, 28, 63, 29],
+
[83, 21, 64, 68, 75, 59, 87, 45, 76, 23, 29, 73, 18, 27, ...],
+
[62, 15, 67, 35, 16, 43, 86],
+
[88, 31, 23, 83, 39],
+
[27, 87, 86, 49, 83, 64, 39, 76, 75, 53, 89, ...],
+
[53, 81, 21, 51, 63, 15, 95, 35, 34],
+
[95, 51, 31, 84, 15, 94, 43],
+
[92, 76, 59, 63, 73, 64, 84, 81, ...],
+
[89, 18, 62, 15, 94, 65, 85],
+
~c"\\D?_CN^",
+
[94, 68, 95, 84, 16, ...],
+
[35, 34, 16, 65, ...],
+
[15, 66, 95, ...],
+
[69, 63, ...],
+
[85, ...],
+
[...],
+
...
+
]
+
```
+
+
```elixir
+
defmodule PrintQueue do
+
def valid?(input, prev), do: do_valid?([], input, prev)
+
+
defp do_valid?(_, [], _prev), do: true
+
defp do_valid?(visited, [a | rest], prev) do
+
if Enum.any?(prev[a], & &1 in rest) do
+
false
+
else
+
do_valid?([a | visited], rest, prev)
+
end
+
end
+
+
def middle(list) do
+
Enum.at(list, div(length(list), 2))
+
end
+
end
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:module, PrintQueue, <<70, 79, 82, 49, 0, 0, 10, ...>>, {:middle, 1}}
+
```
+
+
```elixir
+
{valid, invalid} = Enum.split_with(jobs, &PrintQueue.valid?(&1, prev))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{[
+
[34, 65, 85, 48, 82, 47, 23, 87, 49, 79, 83, 28, 29],
+
[57, 82, 27, 87, 83, 28, 29, 39, 76, 45, 75, 53, 92, 81, 18],
+
[31, 47, 23, 27, 87, 49, 79, 83, 28, 64, 29, 76, 45, 75, 53, 81, 59, 89, 18, 73, 68],
+
[62, 15, 66, 95, 19, 67, 35, 78, 94, 16, 65, 48, 43, 88, 82, 31, 47, 23, 27, 87, 86],
+
[62, 15, 66, 95, 67, 35, 34, 16, 65, 43, 88, 82, 31, 47, 86],
+
[83, 76, 75, 53, 92, 81, 73, 26, 63, 56, 62],
+
[75, 53, 92, 18, 73, 68, 26, 51, 69, 63, 15, 19, 67, 35, 78],
+
[48, 31, 23, 27, 87, 86, 28, 64, 29, 76, 75],
+
[29, 76, 45, 75, 81, 18, 73, 21, 56, 62, 95],
+
[49, 79, 39, 76, 53, 92, 59, 89, 18, 68, 51, 69, 63],
+
[87, 86, 49, 79, 83, 28, 39, 76, 45, 53, 92, 89, 18, 68, 26, 21, 51],
+
[87, 83, 29, 45, 59, 73, 51],
+
[34, 94, 16, 85, 48, 43, 88, 57, 82, 23, 87, 86, 79, 83, 28, 29, 76],
+
[84, 51, 69, 63, 56, 62, 15, 66, 95, 19, 67, 35, 78, 34, 94, 85, 43, 88, 57, 82, 31],
+
[62, 15, 67, 35, 16, 43, 86],
+
[88, 31, 23, 83, 39],
+
[27, 87, 86, 49, 83, 64, 39, 76, 75, 53, 89, 73, 26, 21, 84],
+
[53, 81, 21, 51, 63, 15, 95, 35, 34],
+
[89, 18, 62, 15, 94, 65, 85],
+
~c"\\D?_CN^",
+
[35, 34, 16, 65, 48, 27, 86, 83, 29],
+
[15, 66, 95, 67, 34, 94, 85, 48, 43, 82, 23],
+
[69, 63, 56, 66, 95, 19, 67, 35, 78, 34, 94, 16, 65, 85, 48, 43, 23],
+
[65, 85, 48, 43, 82, 31, 47, 49, 79, 28, 39, 76, 45, 75, 53],
+
~c"V1O@'L-K;YT3E",
+
[92, 81, 59, 89, 18, 73, 26, 21, 84, 51, 69, 63, 56, 62, 15, 66, 95, 19, 67, 35, 78, 34, 94],
+
[26, 84, 69, 63, 56, 62, 66, 19, 67, 78, 34, 94, 16, 85, 43, 88, 57],
+
[34, 94, 16, 65, 48, 57, 82, 31, 23, 27, 83, 28, 76],
+
~c"@'\\QYEB",
+
[83, 28, 64, 29, 39, 76, 45, 75, 53, 92, 81, 89, 73, 68, 26, 21, 51, 69, 63, ...],
+
[68, 26, 69, 56, 85, 43, 88],
+
[67, 35, 78, 94, 16, 65, 48, 88, 57, 82, 47, 23, 49, 79, 83, 28, 64],
+
[92, 81, 26, 51, 69, 63, 62, 15, 95, 19, 78, 34, 94],
+
[81, 59, 73, 68, 26, 51, 63, 56, 15, 95, 35, 34, 16],
+
[79, 83, 64, 45, 53, 81, 68, 26, 84, 51, 69, 63, 56],
+
~c"0+9\eWOSL-K5\\Q",
+
[43, 88, 57, 82, 31, 47, 23, 27, 87, 86, 49, 79, ...],
+
[88, 87, 86, 49, 79, 83, 28, 39, 76, 45, 92, ...],
+
[66, 95, 19, 67, 35, 78, 34, 94, 16, 85, ...],
+
[23, 27, 86, 79, 83, 28, 64, 29, 39, ...],
+
[79, 83, 28, 64, 29, 76, 45, 75, ...],
+
[84, 51, 56, 62, 95, 67, 78, ...],
+
[76, 45, 75, 53, 92, 81, ...],
+
[49, 79, 83, 28, 64, ...],
+
[21, 15, 66, 19, ...],
+
[19, 67, 78, ...],
+
[88, 82, ...],
+
[92, ...],
+
[...],
+
...
+
],
+
[
+
[94, 68, 73, 78, 15, 65, 43, 66, 62],
+
[29, 86, 68, 39, 81, 45, 75, 76, 31, 53, 64, 23, 92],
+
[31, 28, 83, 49, 87, 79, 82, 64, 16, 48, 86],
+
[45, 89, 73, 53, 59, 68, 28, 83, 86, 79, 69, 76, 39],
+
[31, 19, 88, 35, 23, 43, 86, 79, 48, 16, 57, 82, 27, 87, 67, 65, 78, 34, 49, 47, 66],
+
[26, 95, 73, 56, 81, 89, 59, 34, 92, 94, 21],
+
[16, 63, 34, 19, 66, 65, 47, 56, 31, 82, 51, 85, 57, 67, 88, 62, 48, 78, 95, 35, 15],
+
[28, 68, 83, 31, 59, 89, 29, 73, 39, 75, 92, 86, 76, 45, 49, 64, 18, 81, 87, 27, 79, 23, 47],
+
[81, 78, 26, 16, 59, 62, 51, 19, 21, 56, 68, 94, 18, 73, 69, 35, 89, 84, 66],
+
[53, 27, 29, 79, 28, 88, 85, 31, 47],
+
[29, 75, 43, 31, 83, 57, 49, 27, 48, 64, 23, 87, 86, 76, 79, 53, 45],
+
~c"?\e+_N8\"",
+
[83, 59, 89, 81, 18, 84, 68, 76, 69, 26, 62, 63, 56, 75, 73, 92, 64, 53, 28, 51, 29],
+
[16, 51, 62, 43, 15, 68, 78, 65, 88, 19, 34, 85, 26, 48, 95, 94, 67, 56, 84, 69, 66],
+
[65, 82, 23, 87, 86, 75, 48, 49, 31, 16, 57, 45, 43, 47, 29],
+
[18, 67, 21, 15, 63, 59, 84, 66, 69, 26, 34, 68, 35, 95, 81, 92, 19],
+
[85, 15, 43, 62, 84, 88, 57, 16, 31, 95, 69],
+
[21, 51, 43, 16, 94, 78, 19],
+
[51, 69, 62, 35, 88, 15, 16, 21, 48, 57, 26, 78, 65, 43, 34, 95, 19],
+
[49, 78, 16, 94, 31, 23, 65],
+
[53, 69, 49, 84, 51, 89, 28, 63, 29],
+
[83, 21, 64, 68, 75, 59, 87, 45, 76, 23, 29, 73, 18, 27, 28, 81, 26, 53, 86, 89, 39, 92, 79],
+
[95, 51, 31, 84, 15, 94, 43],
+
[92, 76, 59, 63, 73, 64, 84, 81, 28, 75, 15, 29, 68, 62, 69],
+
[94, 68, 95, 84, 16, 63, 15, 35, 26, 34, 62, 73, 19, 51, 56, 67, 18, 21, 69, 65, 66, 59, 78],
+
[85, 27, 66, 19, 43, 62, 86],
+
[21, 89, 19, 84, 94, 35, 68, 65, 18, 51, 16, 63, 59, 67, 34, 56, 73, 78, 15, 69, 95, ...],
+
[83, 23, 39, 27, 76, 47, 49, 29, 48, 86, 82, 53, 88, 64, 92, 75, 81, 45, 31, 43, ...],
+
[95, 51, 62, 63, 16, 34, 65, 66, 69, 19, 57, 82, 47],
+
[82, 57, 84, 65, 78, 31, 16, 67, 66],
+
[59, 95, 18, 68, 15, 34, 35, 51, 19, 92, 66, 56, 94, 81, 73, 62, 78],
+
~c"BI'@8L;",
+
[89, 53, 84, 39, 62, 63, 51, 75, 64, 81, 26, 18, 69, 83, 45, ...],
+
[82, 87, 39, 88, 23, 57, 48, 85, 76, 83, 92, 47, 43],
+
~c"RQK'X",
+
[59, 76, 29, 23, 89, 79, 31, 73, 45, 82, 87, 92, ...],
+
[23, 31, 39, 53, 89, 64, 79, 73, 59, 45, 92],
+
[63, 85, 66, 35, 65, 15, 31, 62, 95],
+
[35, 88, 31, 78, 23, 87, 15, 49, 95, ...],
+
[43, 16, 73, 34, 19, 66, 62],
+
[63, 51, 34, 19, 15, 65, 31, ...],
+
[45, 48, 83, 43, 65, 29, ...],
+
[83, 49, 47, 45, 88, ...],
+
[31, 19, 35, 16, ...],
+
[84, 65, 88, ...],
+
[67, 82, ...],
+
[79, ...],
+
[...],
+
...
+
]}
+
```
+
+
## Part 1
+
+
```elixir
+
valid
+
|> Enum.map(&PrintQueue.middle/1)
+
|> Enum.sum()
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
6051
+
```
+
+
## Part 2
+
+
```elixir
+
invalid
+
|> Enum.map(fn job ->
+
Enum.sort(job, fn a, b -> b in prev[a] end)
+
end)
+
|> Enum.map(&PrintQueue.middle/1)
+
|> Enum.sum()
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
5093
+
```
+
+
<!-- livebook:{"offset":27803,"stamp":{"token":"XCP.89VYFJDxWhhYqFwu165HzJaFBGbiSzyXWCSnD4rBE7dhN7HuS1Im6xp-8VPztVgcmSlMso948ZvV8MkBmy35qbTi8rDfbB5Zr2PQ-9P6LUjHMKF8Wu3IKPm7UjkY_cOiA6k","version":2}} -->
+187
2024/day06.livemd
···
+
<!-- livebook:{"persist_outputs":true} -->
+
+
# Day 06
+
+
```elixir
+
Mix.install([:kino_aoc, :arrays])
+
```
+
+
## Section
+
+
<!-- livebook:{"attrs":"eyJhc3NpZ25fdG8iOiJwdXp6bGVfaW5wdXQiLCJkYXkiOiI2Iiwic2Vzc2lvbl9zZWNyZXQiOiJBRFZFTlRfT0ZfQ09ERV9TRVNTSU9OIiwieWVhciI6IjIwMjQifQ","chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2024", "6", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:ok,
+
"...#..................#...................#......................#..............................#.............................#...\n....#.......................#........#.#..............##...........#.....#..........#..........................#..................\n.............#........................................................................#.........#.#..#..#..........#..............\n..........#.......#..........#..................#........##...................#..............#....................................\n....................#..........................................................#..#.....................................#.........\n....#............................#..............................................#.....................#..........##....#..........\n.......#.............#......................................................................#.............#.........#.............\n....###......................#....#...........#.....#................................#..........................#.................\n..........#..#...........#..#........................................................#.....#...........#................#.........\n..#....#......#....#....#...................................................................#.....................................\n....................#............#............................................#......#....#...............................#.......\n..........#.......#.........#.......#.............................................................................................\n.......#...#.......................................#...................#..........................................................\n.......#........#............................#.....#.......#..............................................#..................#...#\n.....................#.................................#................#...#...............#.....#.#..........................#..\n.....#..........................................#......................#.............##..............................#........#...\n.....#......#.........................#..........................#..........................................................#..#..\n.#......#.............#......#.................................................#.....#...................##......#................\n.............................................................................##...................................................\n........................................#.......................................#........#.............................#.#.......#\n...........#.....................................#.............................#......#......#..#....................#..#.........\n.............................................#.......................#..................##....#.....#.............................\n........................#..............................................................#..........................................\n#..............#.........................#........#...#...............#..............#..................#....................##...\n...#...#.............................#.......#................................................#........................#....#.....\n.....#.........................#..#.......................#..........#.....................#..................#.#.....#...........\n..................#........#..#.......#...................................................................................#....#..\n..#...#...............................................#.#..#........................................................#....#......#.\n...............#...............#..........................#............................#..........#.............#.................\n............#.....#........#.........................................................#........#........#.....#........#......#....\n............................#.........#....#........#.....#...#.............#.................................#...................\n........#..................#....#.." <> ...}
+
```
+
+
```elixir
+
map =
+
puzzle_input
+
|> String.split("\n", trim: true)
+
|> Enum.with_index()
+
|> Enum.flat_map(fn {row, y} ->
+
row
+
|> String.to_charlist()
+
|> Enum.with_index()
+
|> Enum.map(fn {v, x} -> {{y, x}, v} end)
+
end)
+
|> Map.new()
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
%{
+
{18, 103} => 46,
+
{76, 13} => 46,
+
{61, 121} => 46,
+
{37, 47} => 46,
+
{65, 63} => 46,
+
{77, 129} => 46,
+
{120, 47} => 46,
+
{38, 2} => 46,
+
{1, 26} => 46,
+
{116, 69} => 46,
+
{124, 56} => 46,
+
{83, 76} => 46,
+
{117, 125} => 46,
+
{32, 15} => 46,
+
{103, 106} => 46,
+
{30, 113} => 46,
+
{123, 104} => 46,
+
{124, 60} => 46,
+
{89, 14} => 46,
+
{35, 30} => 46,
+
{37, 53} => 46,
+
{4, 5} => 46,
+
{8, 50} => 46,
+
{78, 98} => 46,
+
{101, 62} => 46,
+
{95, 56} => 46,
+
{74, 12} => 46,
+
{102, 74} => 46,
+
{11, 39} => 46,
+
{65, 43} => 46,
+
{22, 38} => 46,
+
{14, 86} => 46,
+
{49, 117} => 46,
+
{20, 41} => 46,
+
{29, 25} => 46,
+
{86, 10} => 46,
+
{83, 36} => 46,
+
{29, 26} => 46,
+
{47, 27} => 46,
+
{4, 81} => 46,
+
{31, 42} => 46,
+
{9, 34} => 46,
+
{13, 124} => 46,
+
{90, 0} => 46,
+
{14, 122} => 46,
+
{120, 42} => 46,
+
{121, 77} => 46,
+
{103, 39} => 46,
+
{102, ...} => 46,
+
{...} => 46,
+
...
+
}
+
```
+
+
```elixir
+
{start_pos, _} = start = Enum.find(map, fn {_pos, v} -> v in ~c'^>v<' end)
+
+
map = Map.replace(map, start_pos, ?.)
+
+
start
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{{93, 71}, 94}
+
```
+
+
```elixir
+
defmodule Guard do
+
def walk(map, start),
+
do: walk(map, start, MapSet.new())
+
+
defp walk(map, {pos, dir} = curr, visited) do
+
if curr in visited do
+
:loop
+
else
+
visited = MapSet.put(visited, curr)
+
+
case Map.fetch(map, next(pos, dir)) do
+
{:ok, ?#} ->
+
walk(map, {pos, turn(dir)}, visited)
+
+
{:ok, ?.} ->
+
walk(map, {next(pos, dir), dir}, visited)
+
+
:error ->
+
MapSet.new(visited, fn {pos, _} -> pos end)
+
end
+
end
+
end
+
+
defp next({y, x}, ?^), do: {y - 1, x}
+
defp next({y, x}, ?>), do: {y, x + 1}
+
defp next({y, x}, ?v), do: {y + 1, x}
+
defp next({y, x}, ?<), do: {y, x - 1}
+
+
defp turn(?^), do: ?>
+
defp turn(?>), do: ?v
+
defp turn(?v), do: ?<
+
defp turn(?<), do: ?^
+
end
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:module, Guard, <<70, 79, 82, 49, 0, 0, 12, ...>>, {:turn, 1}}
+
```
+
+
## Part 1
+
+
```elixir
+
orig_path = Guard.walk(map, start)
+
+
MapSet.size(orig_path)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
4433
+
```
+
+
## Part 2
+
+
```elixir
+
orig_path
+
|> MapSet.delete(start_pos)
+
|> Task.async_stream(fn point ->
+
map
+
|> Map.put(point, ?#)
+
|> Guard.walk(start)
+
|> Kernel.==(:loop)
+
end, ordered: false)
+
|> Enum.count(& &1)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
4432
+
```
+
+
<!-- livebook:{"offset":7376,"stamp":{"token":"XCP.Bv-aM7sns5Kb69SQdY4giDFl6fWiJ5L3lnISxUUjGi_DgTgM_r5rl-y8sy2RLl-KbEtOmW99QQsGItLYJhKJmkOZ5pPZ_7Aw3BhkL_ap8RnW8UkOt_OsNdpqoZT7FEDtmFQ","version":2}} -->
+205
2024/day07.livemd
···
+
<!-- livebook:{"persist_outputs":true} -->
+
+
# Day 07
+
+
```elixir
+
Mix.install([:kino_aoc])
+
```
+
+
## Section
+
+
<!-- livebook:{"attrs":"eyJhc3NpZ25fdG8iOiJwdXp6bGVfaW5wdXQiLCJkYXkiOiI3Iiwic2Vzc2lvbl9zZWNyZXQiOiJBRFZFTlRfT0ZfQ09ERV9TRVNTSU9OIiwieWVhciI6IjIwMjQifQ","chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2024", "7", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:ok,
+
"644197722674: 5 9 46 99 1 5 9 2 22 6 74\n3424919: 67 51 7 561 358\n7160145: 9 9 7 4 8 3 91 2 3 3 5 731\n1133404163: 231 3 49 2 32 128 36\n198444: 9 77 90 347 308 46 3\n258135: 7 61 68 6 249 6\n10677865: 864 7 4 1 9 4 7 7 1 5 367\n1134: 54 7 3\n28760910: 1 6 627 9 752 831\n6740: 82 236 356 10\n983873830: 977 6 267 606 830\n101904: 5 71 29 2 264\n8536122: 5 3 7 388 120\n818217: 8 27 21 484 92 5 214\n9221: 219 23 270 18 5\n216699547: 2 24 46 9 1 55 6 61 9 88\n19040: 434 4 5 2 41 713 28 54\n113740483608: 52 951 38 417 23 17\n1837300: 627 46 5 1 91 6 6 4\n21564: 6 143 330 9 5 9\n100992468: 4 4 2 9 7 69 3 24 92 8 6 8\n522672: 5 226 7 5\n72660535: 181 857 70 5 2 4 1 11\n1553455: 57 842 4 650 374 79\n177565304: 177 5 6 530 7\n123464883: 65 67 315 7 2 45\n162378: 47 799 75 702 74 3\n75882558: 4 4 9 3 8 7 5 29 5 4 57 5\n15486: 5 771 6 1 2 2 8 8 8 8 2 4\n195018949: 237 9 76 61 19 95 4 9 9\n120067914: 12 7 1 282 9 17 7 2 7 79\n10625355: 6 16 906 3 533\n714034: 2 3 60 7 7 90 325 9\n147283595568: 3 311 33 3 57 822 8 93\n2316922: 8 26 41 831 2 94\n182954295: 438 22 56 5 993 4\n17143497694679: 73 169 33 1 4 71 6 79\n758512003463: 3 2 790 700 4 2 2 34 63\n4146569285: 280 8 9 5 6 7 68 4 9 1 2 5\n31770235539495: 589 8 9 1 1 95 3 63 492\n2140548: 7 6 1 4 3 4 8 929 1 3 8 12\n12113461: 291 3 50 772 17 5 2 2\n9197820380208: 1 58 583 110 58 207\n1539915: 88 340 19 5 689\n198635345304: 19 711 980 6 44 341\n43172: 426 8 4 318 1 1 439 3 5\n53202: 5 3 7 1 4 79 62 6 6\n999074: 1 4 221 5 9 71\n107010: 2 1 29 410 3\n1207: 8 600 5 9 567 17 1\n963: 56 902 7\n3661: 87 42 4 3\n55680: 8 7 2 58 8 4\n1443280: 1 33 16 68 39 592\n11791444132: 954 3 412 412 9\n40408: 8 8 513 70 19\n895: 45 9 784 52 8\n3630590257: 5 787 5 98 113 94 57\n1219939: 9 5 183 9 3\n7243377: 1 231 8 2 1 36 6 5 795 3\n10281688290: 728 359 69 874 8 45\n52129140: 78 1 7 407 547 5 2 4 5\n844925: 778 18 78 6 8\n1517768001: 56 213 629 27 17\n1586: 26 1 18 35 9\n897822305: 10 89 7 8 222 55 52\n307677984: 38 946 58 79 2\n11629377: 7 10 83 82 37 548 6 79\n5706366: 203 30 937 6 1 26\n545930: 1 8 696 5 770\n21436: 57 94 4 4 1\n601219587: 2 5 1 2 1 1 4 1 1 912 327\n1210568: 5 3 9 86 1 1 98 2 8 97 6 8\n163672: 311 939 4 1 130 522\n816: 3 9 7 9 5 25 84 186 56\n413330: 71 9 181 504 50\n275151204: 5 8 9 8 4 3 433 1 5 6 7 3\n5565: 47 19 8 7 1 276\n5528836: 1 552 789 9 936\n30771: 42 81 5 12 9\n113510: 99 58 723\n2552925934889: 802 8 795 54 8 372 4 6\n13201: 45 124 77 31 159\n720468: 17 6 92 4 7\n22380384159: 7 8 166 29 159 1 3 2 8 2\n45770: 4 41 765 2 3\n32957: 4 28 886 71\n5110126: 6 173 214 66 8\n1762745: 982 227 3 3 27 3 6 5\n130796643: 131 32 1 5 5 624\n78364255: 8 9 694 57 7 253\n844276: 8 42 224 792 1\n362023: 9 25 594 5 5 40 87 103\n1291399844: 5 6 1 9 39 1 73 9 6 44\n228417920: 25 37 71 9 26 794 8 4\n40050828: 3 27 763 6 9 9 5 1 9 12\n116627652: 7 4 7 1 446 8 4 5 2 4 75 6\n2516095717: 7 385 8 43 59 8 5 46\n655270872: 9 2 8 159 89 2 9 3 89 95\n35298709: 6 41 170 3 2 422 97\n558606: 4 6 5 74 6 53 7 7 100 1 5\n96911: 5 9 75 6 9 665 2 7 9 2 7 8\n429735: 7 72 58 6 9\n9402: 3 453 9 86 920 1 7 88 6\n2948456: 69 251 9 68 456\n254061: 603 70 2 6 789\n27948: 485 575 322 262 17\n90873: 58 49 8 27 31 31 725\n6444009: 5 6 195 7 6 33 13\n17255343: 78 867 42 3 85\n144630242: 490 2 39 11 7 4 39 86 1\n444869: 4 7 8 878 5 479\n253242155: 42 203 6 7 234 57\n1823338: 2 414 9 487 4 6\n25234118: 91 683 58 7 1\n642484013: 917 822 4 6 1 7 9 1 2\n10018629: 99 944 235 99 628\n52518012: 663 80 8 5 99\n52968775714: 217 3 8 2 3 2 9 6 9 9 94 6\n7014: 1 666 9 933 8 70\n1210591: 39 8 40 97 31\n61925382: 366 648 1 1 9 837 29\n1392623100: 92 3 6 6 8 18 8 815 990\n146952: 66 53 92 6 677 43\n16148106: 41 31 9 5 4 39\n972134: 4 36 905 3 28 9 75 54 3\n1699: 9 7 94 2\n38915712: 66 83 4 3 296 2 1\n24871732: 71 178 3 656 148\n1016303031: 229 634 7 499 532\n553520: 7 3 7 22 69\n588423590: 2 1 9 143 8 3 6 923 1 3 4\n8360806312: 1 3 9 850 24 7 857 5 7 5\n462718: 4 6 26 93 26\n21935424: 280 60 96 2 4 2 84\n885836: 8 850 4 5 2 27 704 58 9\n797703006: 1 3 1 8 9 4 9 495 3 7 60 6\n7714822: 2 4 757 959 3 25\n233319196: 881 27 45 10 4 979\n451620568437: 170 6 57 4 9 5 56 8 439\n2836062720: 7 88 111 9 6 6 2 4 3 8 3 2\n81217110: 827 98 9 501 2\n21081: 6 3 41 6 3 1 6 324 8 5 8\n861: 7 7 2 " <> ...}
+
```
+
+
```elixir
+
#puzzle_input =
+
"""
+
190: 10 19
+
3267: 81 40 27
+
83: 17 5
+
156: 15 6
+
7290: 6 8 6 15
+
161011: 16 10 13
+
192: 17 8 14
+
21037: 9 7 18 13
+
292: 11 6 16 20
+
"""
+
+
equations =
+
puzzle_input
+
|> String.split("\n", trim: true)
+
|> Enum.map(fn row ->
+
{target, ": " <> rest} = Integer.parse(row)
+
+
values =
+
rest
+
|> String.split()
+
|> Enum.map(&String.to_integer/1)
+
+
{target, values}
+
end)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
warning: code block contains unused literal "190: 10 19\n3267: 81 40 27\n83: 17 5\n156: 15 6\n7290: 6 8 6 15\n161011: 16 10 13\n192: 17 8 14\n21037: 9 7 18 13\n292: 11 6 16 20\n" (remove the literal or assign it to _ to avoid warnings)
+
โ””โ”€ Workspace/hauleth/advent-of-code/2024/day07.livemd#cell:7pxlqq2wa3oqdwfr:1
+
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
[
+
{644197722674, [5, 9, 46, 99, 1, 5, 9, 2, 22, 6, 74]},
+
{3424919, [67, 51, 7, 561, 358]},
+
{7160145, [9, 9, 7, 4, 8, 3, 91, 2, 3, 3, 5, 731]},
+
{1133404163, [231, 3, 49, 2, 32, 128, 36]},
+
{198444, [9, 77, 90, 347, 308, 46, 3]},
+
{258135, [7, 61, 68, 6, 249, 6]},
+
{10677865, [864, 7, 4, 1, 9, 4, 7, 7, 1, 5, 367]},
+
{1134, [54, 7, 3]},
+
{28760910, [1, 6, 627, 9, 752, 831]},
+
{6740, [82, 236, 356, 10]},
+
{983873830, [977, 6, 267, 606, 830]},
+
{101904, [5, 71, 29, 2, 264]},
+
{8536122, [5, 3, 7, 388, 120]},
+
{818217, [8, 27, 21, 484, 92, 5, 214]},
+
{9221, [219, 23, 270, 18, 5]},
+
{216699547, [2, 24, 46, 9, 1, 55, 6, 61, 9, 88]},
+
{19040, [434, 4, 5, 2, 41, 713, 28, 54]},
+
{113740483608, [52, 951, 38, 417, 23, 17]},
+
{1837300, [627, 46, 5, 1, 91, 6, 6, 4]},
+
{21564, [6, 143, 330, 9, 5, 9]},
+
{100992468, [4, 4, 2, 9, 7, 69, 3, 24, 92, 8, 6, 8]},
+
{522672, [5, 226, 7, 5]},
+
{72660535, [181, 857, 70, 5, 2, 4, 1, 11]},
+
{1553455, [57, 842, 4, 650, 374, 79]},
+
{177565304, [177, 5, 6, 530, 7]},
+
{123464883, [65, 67, 315, 7, 2, 45]},
+
{162378, [47, 799, 75, 702, 74, 3]},
+
{75882558, [4, 4, 9, 3, 8, 7, 5, 29, 5, 4, 57, 5]},
+
{15486, [5, 771, 6, 1, 2, 2, 8, 8, 8, 8, 2, 4]},
+
{195018949, [237, 9, 76, 61, 19, 95, 4, 9, 9]},
+
{120067914, [12, 7, 1, 282, 9, 17, 7, 2, 7, 79]},
+
{10625355, [6, 16, 906, 3, 533]},
+
{714034, [2, 3, 60, 7, 7, 90, 325, 9]},
+
{147283595568, [3, 311, 33, 3, 57, 822, 8, 93]},
+
{2316922, [8, 26, 41, 831, 2, 94]},
+
{182954295, [438, 22, 56, 5, 993, 4]},
+
{17143497694679, [73, 169, 33, 1, 4, 71, 6, 79]},
+
{758512003463, [3, 2, 790, 700, 4, 2, 2, 34, 63]},
+
{4146569285, [280, 8, 9, 5, 6, 7, 68, 4, 9, ...]},
+
{31770235539495, [589, 8, 9, 1, 1, 95, 3, 63, ...]},
+
{2140548, [7, 6, 1, 4, 3, 4, 8, ...]},
+
{12113461, [291, 3, 50, 772, 17, 5, ...]},
+
{9197820380208, [1, 58, 583, 110, 58, ...]},
+
{1539915, [88, 340, 19, 5, ...]},
+
{198635345304, [19, 711, 980, ...]},
+
{43172, [426, 8, ...]},
+
{53202, [5, ...]},
+
{999074, [...]},
+
{107010, ...},
+
{...},
+
...
+
]
+
```
+
+
## Part 1
+
+
```elixir
+
defmodule Eq.P1 do
+
def possible?(0, []), do: true
+
def possible?(a, [a]), do: true
+
def possible?(0, [_ | _]), do: false
+
def possible?(_, []), do: false
+
def possible?(a, _) when a < 0, do: false
+
+
def possible?(a, [b | rest]) when rem(a, b) == 0 do
+
possible?(div(a, b), rest) or possible?(a - b, rest)
+
end
+
+
def possible?(a, [b | rest]), do: possible?(a - b, rest)
+
end
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:module, Eq.P1, <<70, 79, 82, 49, 0, 0, 8, ...>>, {:possible?, 2}}
+
```
+
+
```elixir
+
equations
+
|> Enum.filter(fn {target, vals} ->
+
Eq.P1.possible?(target, Enum.reverse(vals))
+
end)
+
|> Enum.reduce(0, &(elem(&1, 0) + &2))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
3119088655389
+
```
+
+
## Part 2
+
+
```elixir
+
defmodule Eq.P2 do
+
def possible?(a, [hd | rest]), do: possible?(a, hd, rest)
+
+
defp possible?(a, a, []), do: true
+
defp possible?(_, _, []), do: false
+
defp possible?(a, b, _) when b > a, do: false
+
+
defp possible?(target, curr, [a | rest]) do
+
possible?(target, concat(curr, a), rest) or
+
possible?(target, curr * a, rest) or
+
possible?(target, curr + a, rest)
+
end
+
+
defp concat(a, b), do: a * l10(b) + b
+
+
defp l10(n) when n >= 100, do: 1000
+
defp l10(n) when n >= 10, do: 100
+
defp l10(_), do: 10
+
end
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:module, Eq.P2, <<70, 79, 82, 49, 0, 0, 9, ...>>, {:l10, 1}}
+
```
+
+
```elixir
+
equations
+
|> Task.async_stream(
+
fn {target, vals} ->
+
if Eq.P2.possible?(target, vals), do: target, else: 0
+
end,
+
ordered: false
+
)
+
|> Enum.reduce(0, fn {:ok, val}, acc -> val + acc end)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
264184041398847
+
```
+
+
<!-- livebook:{"offset":9317,"stamp":{"token":"XCP.DCDL30p1jz3L9vRDdQ5EJLc3r7y1DTsVhQ3GXFK_huvoEXqgYu2TTOfTq8AFYpt5W6fEIo4MvfrnHttbqS-z4SjRkT7WM09v09mZ_FeyqstWzLMCK_oNqhrrdwPPv5BG_8c","version":2}} -->
+327
2024/day08.livemd
···
+
<!-- livebook:{"persist_outputs":true} -->
+
+
# Day 08
+
+
```elixir
+
Mix.install([:kino_aoc])
+
```
+
+
## Section
+
+
<!-- livebook:{"attrs":"eyJhc3NpZ25fdG8iOiJwdXp6bGVfaW5wdXQiLCJkYXkiOiI4Iiwic2Vzc2lvbl9zZWNyZXQiOiJBRFZFTlRfT0ZfQ09ERV9TRVNTSU9OIiwieWVhciI6IjIwMjQifQ","chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2024", "8", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:ok,
+
"..........M..........j.............y.....O........\n...B...............q......m........lGO............\n....................q......2.l.GQ...O.............\n.....X.......................................4....\n.....................q............................\n....M......P...............xl.K.............2.....\n....F.........L.......C.K..............m..........\n..........FM......P....jy......m..........o...r...\n..X.......P.....RL..............G..x..........4...\n............L..........NC.....q...................\n.....C.X...............K....y..........4..........\n........S...R.............j.x.....V...4...........\n.....................R..x.....V..i......m.........\n...........................R.V......N.......X.....\n.....F.........M......N......E....................\n................v................T.......F......O.\n.............................N...V.......Q........\n...v.....................C.....i..................\n......c.....W..n.w........................E.......\n3...................c.....................Q..6....\n...........h......................j...............\n.......n.0......h.................E..............2\n.v.............7.......120.....c..................\n......n.0............w...........D.t.........E...r\n....8..3......0.w.hP....z...D..T...............r..\n.................f........T........G......eQ......\n......f.n.....7..p................................\n.....Y..7.......f......I......D......K............\n............Uf....T..W.....D..r...i...............\n......I...............................Z...........\n....5....B.......b..............s..............Z..\n..........d...W..Uwh.............c..........i.....\n..I.3..Y......................e...................\n.....p.b..........k......7........................\np...........k....I..b..........s..................\n.....k.......o...........W........................\n.A..Y..........U.................a........6.......\n..A...Y.p...................................6.....\nB......k..........................Z............u..\n...3.....................s..............a.........\n......A.........................g.....a...........\n.......A....8...b.U......H....sS..................\n.........................S1.............t.........\n.....................9z..e.....5..1.g.u...........\n.......................z....d....g....H.J....o.6..\n........B................d.....u....9.J.H.........\n.8........S.................u9.............J.....H\n.....................Z5.............t1...........a\n.....................e..v...................o..t..\n.....8...............L.....z.............J........"}
+
```
+
+
```elixir
+
# puzzle_input =
+
"""
+
............
+
........0...
+
.....0......
+
.......0....
+
....0.......
+
......A.....
+
............
+
............
+
........A...
+
.........A..
+
............
+
............
+
"""
+
+
freqs =
+
puzzle_input
+
|> String.split("\n", trim: true)
+
|> Enum.with_index()
+
|> Enum.flat_map(fn {row, y} ->
+
row
+
|> String.to_charlist()
+
|> Enum.with_index()
+
|> Enum.filter(fn {freq, _} -> freq != ?. end)
+
|> Enum.map(fn {freq, x} -> {{x, y}, freq} end)
+
end)
+
|> Map.new()
+
|> Enum.group_by(&elem(&1, 1), &elem(&1, 0))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
warning: code block contains unused literal "............\n........0...\n.....0......\n.......0....\n....0.......\n......A.....\n............\n............\n........A...\n.........A..\n............\n............\n" (remove the literal or assign it to _ to avoid warnings)
+
โ””โ”€ Workspace/hauleth/advent-of-code/2024/day08.livemd#cell:y5uv5vxll4fey6gh:1
+
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
%{
+
117 => [{28, 46}, {31, 45}, {38, 43}, {47, 38}],
+
73 => [{2, 32}, {17, 34}, {23, 27}, {6, 29}],
+
89 => [{4, 36}, {7, 32}, {6, 37}, {5, 27}],
+
48 => [{25, 22}, {9, 21}, {8, 23}, {14, 24}],
+
57 => [{29, 46}, {21, 43}, {36, 45}],
+
113 => [{30, 9}, {20, 2}, {21, 4}, {19, 1}],
+
69 => [{42, 18}, {34, 21}, {45, 23}, {29, 14}],
+
88 => [{7, 10}, {5, 3}, {44, 13}, {2, 8}],
+
100 => [{25, 45}, {28, 44}, {10, 31}],
+
71 => [{36, 1}, {35, 25}, {31, 2}, {32, 8}],
+
98 => [{16, 41}, {7, 33}, {20, 34}, {17, 30}],
+
81 => [{42, 19}, {41, 16}, {43, 25}, {32, 2}],
+
76 => [{12, 9}, {14, 6}, {17, 8}, {21, 49}],
+
85 => [{15, 36}, {12, 28}, {17, 31}, {18, 41}],
+
120 => [{27, 5}, {35, 8}, {28, 11}, {24, 12}],
+
109 => [{26, 1}, {39, 6}, {40, 12}, {31, 7}],
+
72 => [{38, 44}, {40, 45}, {49, 46}, {25, 41}],
+
110 => [{8, 26}, {7, 21}, {15, 18}, {6, 23}],
+
68 => [{30, 27}, {28, 24}, {27, 28}, {33, 23}],
+
86 => [{29, 13}, {33, 16}, {30, 12}, {34, 11}],
+
116 => [{35, 23}, {36, 47}, {47, 48}, {40, 42}],
+
51 => [{7, 24}, {0, 19}, {3, 39}, {4, 32}],
+
80 => [{18, 7}, {19, 24}, {10, 8}, {11, 5}],
+
77 => [{11, 7}, {15, 14}, {10, 0}, {4, 5}],
+
78 => [{22, 14}, {29, 16}, {36, 13}, {23, 9}],
+
108 => [{29, 2}, {28, 5}, {35, 1}],
+
103 => [{32, 40}, {36, 43}, {33, 44}],
+
122 => [{27, 49}, {23, 44}, {24, 24}, {22, 43}],
+
83 => [{10, 46}, {25, 42}, {31, 41}, {8, 11}],
+
74 => [{38, 45}, {41, 49}, {43, 46}, {40, 44}],
+
99 => [{31, 22}, {33, 31}, {20, 19}, {6, 18}],
+
112 => [{5, 33}, {17, 26}, {8, 37}, {0, 34}],
+
97 => [{38, 40}, {33, 36}, {49, 47}, {40, 39}],
+
104 => [{16, 21}, {19, 31}, {11, 20}, {18, 24}],
+
75 => [{30, 5}, {24, 6}, {23, 10}, {37, 27}],
+
90 => [{21, 47}, {47, 30}, {34, 38}, {38, 29}],
+
55 => [{15, 22}, {14, 26}, {8, 27}, {25, 33}],
+
52 => [{45, 3}, {38, 11}, {39, 10}, {46, 8}],
+
111 => [{13, 35}, {42, 7}, {45, 44}, {44, 48}],
+
87 => [{25, 35}, {12, 18}, {14, 31}, {21, 28}],
+
119 => [{21, 23}, {18, 31}, {17, 18}, {16, 24}],
+
82 => [{12, 11}, {27, 13}, {21, 12}, {16, 8}],
+
53 => [{22, 47}, {31, 43}, {4, 30}],
+
50 => [{27, 2}, {24, 22}, {44, 5}, {49, 21}],
+
66 => [{8, 45}, {9, 30}, {3, 1}, {0, ...}],
+
70 => [{5, 14}, {41, 15}, {10, ...}, {...}],
+
56 => [{12, 41}, {4, ...}, {...}, ...],
+
102 => [{17, ...}, {...}, ...],
+
105 => [{...}, ...],
+
121 => [...],
+
...
+
}
+
```
+
+
```elixir
+
{w, h} =
+
puzzle_input
+
|> String.split("\n", trim: true)
+
|> then(fn [a | _] = lst ->
+
{byte_size(a), length(lst)}
+
end)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{50, 50}
+
```
+
+
```elixir
+
defmodule Antennas do
+
def each_pair([]), do: []
+
def each_pair([a | rest]) do
+
for(b <- rest, do: {a, b}) ++ each_pair(rest)
+
end
+
+
def antinodes({xa, ya}, {xb, yb}) do
+
dx = xa - xb
+
dy = ya - yb
+
+
Stream.from_index()
+
|> Stream.flat_map(fn n ->
+
dx = dx * n
+
dy = dy * n
+
[{xa + dx, ya + dy}, {xb - dx, yb - dy}]
+
end)
+
end
+
end
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:module, Antennas, <<70, 79, 82, 49, 0, 0, 10, ...>>, {:antinodes, 2}}
+
```
+
+
## Part 1
+
+
```elixir
+
antinodes =
+
for {_, antennas} <- freqs,
+
{a, b} <- Antennas.each_pair(antennas),
+
{x, y} = node <- Antennas.antinodes(a, b) |> Stream.drop(2) |> Enum.take(2),
+
x in 0..(w - 1) and y in 0..(h - 1),
+
into: MapSet.new() do
+
node
+
end
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
MapSet.new([
+
{20, 41},
+
{20, 3},
+
{16, 10},
+
{26, 21},
+
{6, 18},
+
{10, 32},
+
{20, 30},
+
{33, 17},
+
{17, 30},
+
{29, 28},
+
{40, 35},
+
{28, 37},
+
{25, 49},
+
{10, 19},
+
{14, 17},
+
{35, 7},
+
{29, 48},
+
{1, 34},
+
{23, 8},
+
{35, 6},
+
{49, 17},
+
{46, 38},
+
{5, 39},
+
{37, 29},
+
{16, 15},
+
{48, 41},
+
{4, 18},
+
{24, 15},
+
{33, 44},
+
{39, 18},
+
{40, 25},
+
{35, 21},
+
{41, 17},
+
{20, 37},
+
{45, 24},
+
{0, 35},
+
{18, 3},
+
{1, 36},
+
{35, 41},
+
{37, 28},
+
{28, 15},
+
{29, 38},
+
{46, 43},
+
{31, 19},
+
{19, 39},
+
{43, 10},
+
{38, 10},
+
{21, 26},
+
{28, ...},
+
{...},
+
...
+
])
+
```
+
+
```elixir
+
MapSet.size(antinodes)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
398
+
```
+
+
## Part 2
+
+
```elixir
+
antinodes_res =
+
for {_, antennas} <- freqs,
+
{a, b} <- Antennas.each_pair(antennas),
+
{x, y} = node <- Enum.take(Antennas.antinodes(a, b), 100),
+
x in 0..(w - 1) and y in 0..(h - 1),
+
into: MapSet.new() do
+
node
+
end
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
MapSet.new([
+
{37, 47},
+
{35, 30},
+
{4, 5},
+
{20, 41},
+
{31, 42},
+
{9, 34},
+
{47, 38},
+
{20, 3},
+
{47, 44},
+
{22, 36},
+
{45, 7},
+
{19, 38},
+
{27, 21},
+
{9, 33},
+
{16, 10},
+
{21, 45},
+
{26, 21},
+
{21, 48},
+
{16, 38},
+
{35, 26},
+
{28, 20},
+
{45, 19},
+
{27, 22},
+
{16, 24},
+
{6, 18},
+
{10, 32},
+
{33, 15},
+
{36, 14},
+
{20, 30},
+
{33, 17},
+
{41, 1},
+
{36, 25},
+
{28, 48},
+
{5, 9},
+
{14, 16},
+
{17, 30},
+
{30, 49},
+
{32, 18},
+
{29, 28},
+
{40, 35},
+
{6, 23},
+
{17, 39},
+
{28, 37},
+
{6, 29},
+
{39, 23},
+
{49, 16},
+
{34, 0},
+
{11, 37},
+
{25, ...},
+
{...},
+
...
+
])
+
```
+
+
```elixir
+
MapSet.size(antinodes_res)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
1333
+
```
+
+
<!-- livebook:{"offset":9159,"stamp":{"token":"XCP.vUy-wiQ1Ola4DEyyjRWCHAhmtmjmoDVd4jyZ0g5rhe0RM8-OKii82hOqtdVQ6B_yetZ17Z8avgol_Frq-whc91b45zMSMIRVIC-azF_IQmYLdHX0p3LEQ0xKLcBUuir19OQ","version":2}} -->
+243
2024/day09.livemd
···
+
<!-- livebook:{"persist_outputs":true} -->
+
+
# Day 09
+
+
```elixir
+
Mix.install([:kino_aoc])
+
```
+
+
## Section
+
+
<!-- livebook:{"attrs":"eyJhc3NpZ25fdG8iOiJwdXp6bGVfaW5wdXQiLCJkYXkiOiI5Iiwic2Vzc2lvbl9zZWNyZXQiOiJBRFZFTlRfT0ZfQ09ERV9TRVNTSU9OIiwieWVhciI6IjIwMjQifQ","chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2024", "9", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:ok,
+
"6920945132536042828994482345396169724991532616269072173941615129441070989533549353544192338215647480107561245832285861135469128938656230362333818111433746344751894125805448321674418337459440436476402523264257512621383849394968854739721644705231266361534476141022646838663844981685665728936624151235476791584929822482292987334479824016888196957024425673938289753698621244157130975989396226731549454298144391686468562820376390235135108330238590316674261440783039581594584646247629719986582560203598244312596985279832984526808559405915881067383593502384107494586724976925694948216635952475703445963854271259175649271576378184603074946598276445248640841860479933368524996925945274749282264063148922416399632485376097486952663787643633316356949469798134153950341455917737349115548390535536536397237654519556679716185652595572754749672866345553911576628161614338861880658781637382837898686889463249126116447176285128303560134154431099612772162289797131303641655015516771696046959228585241299646581370538088916416989047515564526116366867367181678616439431284930379889626059473847818663132232979123503952455854489755245141781899866948543116887346827534697893607177987563154596774691267167851154138330695352108499217988406372425774968626985943665687196181233111972699532427257992757984672882888037943925818450345177398760216079692074854569485530377584183586279552981343712063437565138087959796501957177177884278405560475435141829787014884681355059571489723985901554488154898784759668954752934048679146776060562786272011429026535298115262548593878183498916571398351436431313482968486771572527901996664899792152552410493090499727835643526428881322227999149881884793853729989624533029587010105028429614225841889414576176753414877452414680577843459538128911939238704598815126186492327558383740971333501769852667796188543180462490517062819496532859194781303437743159526136553370517461484469733677187178992265612439155938358015666261906673153823768535183244601645561579916316476813124539675061263411515873626197742860301068615568696174716481151333516718804424987323957615961444822618946925923196806747458558553262735686467327309580525855605085698452928593956820699112556481136173708346321771719645737818963669665547522134505223646796667286359173528172301211931188731691358636677670346032949579894428251583802532214067603254278658698940647270167640764638397570409829821264846762426836572463386475815673329747876757249732659277388030843590439617143487927833367461978526979212861844382550791390358527895937281110537852835869713059958217969899704145215985377666628719451233132412294358444746793946343553683032671225858498134340537229859741987180829468238642605723478228646886791227546199853372232566387139711011753555879744151132642224546223435667375781861424845134566438891443785750344893853718679532879854483395621276216275644617996376282773738211864275304297979547422875934634992111232368475557713129934172577624852042405732858060209959806520925730394293739081861693532946112557827992852621975727432957291082907728921029905725787812513023871891551681262814572424452648875694586632916946898788794936727799526748807158546930659285568029733948646265541485187570661411984840326374573377475525442055851882711851241546246736884066686885724058588220382743451817154627144869212944944985727560911326298754699513901913775411631051155448259136813383243697125190592983671813131786588158152523929049549018258627964330945831994544156999373027523966329015316477207024639470312244244043635392684240435826402148884612989874566739774998162494686244143442812672951249922585423333957811202767768597518787769627151336335561386093158376767595684951873065594471827052965041948820794865486179401375326111497235854418829486872664452298163169179763609277741983868518845423468770227926607088302941698125295594475259881783566721809397453893791727816025381929613950311537338366491240658016437269618697401059446097141870959520762921795565136242743648578086232855147488427619213536145259919693337741268680894834764319547389247696113145205712656834305853252319218569748862345539664553175240528621328137233671331496239591159242157540311894387168" <> ...}
+
```
+
+
```elixir
+
#puzzle_input = "2333133121414131402"
+
+
tags =
+
Stream.from_index()
+
|> Stream.intersperse(:gap)
+
+
files =
+
puzzle_input
+
|> String.split("", trim: true)
+
|> Enum.map(&String.to_integer/1)
+
|> Enum.zip(tags)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
[
+
{6, 0},
+
{9, :gap},
+
{2, 1},
+
{0, :gap},
+
{9, 2},
+
{4, :gap},
+
{5, 3},
+
{1, :gap},
+
{3, 4},
+
{2, :gap},
+
{5, 5},
+
{3, :gap},
+
{6, 6},
+
{0, :gap},
+
{4, 7},
+
{2, :gap},
+
{8, 8},
+
{2, :gap},
+
{8, 9},
+
{9, :gap},
+
{9, 10},
+
{4, :gap},
+
{4, 11},
+
{8, :gap},
+
{2, 12},
+
{3, :gap},
+
{4, 13},
+
{5, :gap},
+
{3, 14},
+
{9, :gap},
+
{6, 15},
+
{1, :gap},
+
{6, 16},
+
{9, :gap},
+
{7, 17},
+
{2, :gap},
+
{4, 18},
+
{9, :gap},
+
{9, 19},
+
{1, :gap},
+
{5, 20},
+
{3, :gap},
+
{2, 21},
+
{6, :gap},
+
{1, 22},
+
{6, :gap},
+
{2, 23},
+
{6, :gap},
+
{9, ...},
+
{...},
+
...
+
]
+
```
+
+
```elixir
+
defmodule Disk do
+
def checksum(files) do
+
files
+
|> Enum.reduce({0, 0}, fn
+
{gap, :gap}, {pos, sum} ->
+
{pos + gap, sum}
+
+
{len, idx}, {pos, sum} ->
+
new_pos = pos + len
+
score = Enum.sum(pos..(new_pos - 1)) * idx
+
+
{new_pos, score + sum}
+
end)
+
|> elem(1)
+
end
+
+
def display(lst) do
+
Enum.map(lst, fn
+
{len, val} ->
+
sym = if val == :gap, do: ".", else: to_string(val)
+
+
List.duplicate(sym, len)
+
end)
+
|> IO.iodata_to_binary()
+
end
+
end
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:module, Disk, <<70, 79, 82, 49, 0, 0, 11, ...>>, {:display, 1}}
+
```
+
+
## Part 1
+
+
```elixir
+
defmodule Compactor do
+
def run(files) do
+
occupied =
+
Enum.reduce(files, 0, fn
+
{_, :gap}, acc -> acc
+
{len, _idx}, acc -> acc + len
+
end)
+
+
compact([], occupied, files, Enum.reverse(files))
+
end
+
+
defp compact(acc, 0, _, _), do: Enum.reverse(acc)
+
+
defp compact(acc, left, [{0, :gap} | rest], rfiles),
+
do: compact(acc, left, rest, rfiles)
+
+
defp compact(acc, left, rest, [{_, :gap} | rfiles]),
+
do: compact(acc, left, rest, rfiles)
+
+
defp compact(acc, left, rest, [{0, _idx} | rfiles]) do
+
compact(acc, left, rest, rfiles)
+
end
+
+
defp compact(acc, left, [{gap, :gap} | rest], [{len, idx} | rfiles]) do
+
fill = min(gap, len)
+
+
compact([{fill, idx} | acc], left - fill, [{gap - fill, :gap} | rest], [
+
{len - fill, idx} | rfiles
+
])
+
end
+
+
defp compact(acc, left, [{len, idx} = file | rest], rfiles) when is_integer(idx) do
+
compact([file | acc], left - len, rest, rfiles)
+
end
+
end
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:module, Compactor, <<70, 79, 82, 49, 0, 0, 11, ...>>, {:compact, 4}}
+
```
+
+
```elixir
+
files
+
|> Compactor.run()
+
|> Disk.checksum()
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
6332189866718
+
```
+
+
## Part 2
+
+
```elixir
+
defmodule Defrag do
+
def run(files) do
+
files
+
|> Enum.reverse()
+
|> Enum.reduce(files, fn
+
{_, :gap}, acc -> acc
+
file, acc -> do_run(acc, file, [])
+
end)
+
end
+
+
defp do_run([], _, acc), do: Enum.reverse(acc)
+
+
defp do_run([file | _] = list, file, acc), do: Enum.reverse(acc, list)
+
+
defp do_run([{len, :gap} | rest], {len, idx}, acc),
+
do: Enum.reverse(acc, [{len, idx} | rep(rest, {len, idx})])
+
+
defp do_run([{gap, :gap} | rest], {len, idx}, acc) when len < gap,
+
do: Enum.reverse(acc, [{len, idx}, {gap - len, :gap} | rep(rest, {len, idx})])
+
+
defp do_run([hd | rest], file, acc), do: do_run(rest, file, [hd | acc])
+
+
defp rep([{a, :gap}, file, {b, :gap} | rest], {len, _} = file),
+
do: [{a + len + b, :gap} | rest]
+
+
defp rep([{a, :gap}, file | rest], {len, _} = file), do: [{a + len, :gap} | rest]
+
defp rep([file, {b, :gap} | rest], {len, _} = file), do: [{len + b, :gap} | rest]
+
defp rep([file | rest], {len, _} = file), do: [{len, :gap} | rest]
+
defp rep([hd | rest], file), do: [hd | rep(rest, file)]
+
end
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:module, Defrag, <<70, 79, 82, 49, 0, 0, 12, ...>>, {:rep, 2}}
+
```
+
+
```elixir
+
files
+
|> Defrag.run()
+
|> Disk.checksum()
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
6353648390778
+
```
+
+
<!-- livebook:{"offset":8665,"stamp":{"token":"XCP.-mRlAHFcVs4Mg2hQj8TCLWgOv8zjlatUnbxbgI43tZXllMXB8VfJTbRJrHTJ1k_FrGDhUdviUPyCSPNKqXk-ZOQ9PHWUPFkLaK5S4SMKa18Ny7WrQvSmaHuoE2R6vJhqrck","version":2}} -->
+218
2024/day10.livemd
···
+
<!-- livebook:{"persist_outputs":true} -->
+
+
# Day 10
+
+
```elixir
+
Mix.install([:kino_aoc])
+
```
+
+
## Section
+
+
<!-- livebook:{"attrs":"eyJhc3NpZ25fdG8iOiJwdXp6bGVfaW5wdXQiLCJkYXkiOiIxMCIsInNlc3Npb25fc2VjcmV0IjoiQURWRU5UX09GX0NPREVfU0VTU0lPTiIsInllYXIiOiIyMDI0In0","chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2024", "10", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:ok,
+
"543067650323210321032110356789890110710189878760134567\n612148941212306782345091235410765227893258759651021298\n701238932301456798106787549323454336794567549842330807\n898547215450589867287654678892961245987654456732498910\n987656306769678956398013234781870301256003301201567821\n234543215878760145478920105690210982340112210341056932\n109650124981232230569834124567345673451234985452347845\n018744323890341021656765033438454589298545676701037796\n199803210787650110765017842129823672107655677812378987\n785012345654789541874326956010510563201234389983405676\n174321498723498632903455467173421454102348210234514430\n065430239014323721212762398982567876218959650149623521\n145540128765017890101871081071018967327968743898734678\n236692134984178768718981012567894458456876212798604329\n987783005673269659654108923458763349663212108789015012\n896654012562154546743267830309854218767103419276126787\n765780123473043432890154321212903109878756578125435698\n434099874984012301740125654567812893469017647030165556\n323101065765101787434436763058906732154178736543256765\n013298187890678696325569892143215440043289128954343894\n010367296541549045016678765014300351234567037760012983\n329458305032132134787867410967891267653438546891898012\n458789414145010120196986323898763298344129655432743210\n567076523236678743285898456777654101201098766653658901\n456167654107549658374567689985403100312434985567877014\n343228943298938569843210576876312238920125676656986323\n651014543498127478755765435410278947437876985543235434\n743223672567078369876890324320127656506987234350145632\n894102981089569232125981210451256543215432122341076541\n765091234676352101034674323401237894101341001456789830\n014780365445443032126501012532345743103210112565898321\n123689876034321145098432107645236743254101101876543210\n094545763125210056788943258896107858969010332987674301\n785430432106782169877652349787567967678321245696784561\n876021569045893458965601654343478914565414326781093870\n987109878010432167014298710234323901258905015492012901\n789219894324569052123109620123217892109876012323458692\n654308765543678743013234538994106543010870965410069783\n789877787632189852101110145885287676521961871012178654\n034565896601087601211001406776896789437652676523468743\n121053795542194512389132312345445676548943989430549012\n262342187634765433498545434531230107401232104321678298\n876533014123892324567696526540043298340981010780890187\n983414523016101019876587017832134781256672125690743296\n032101654327892100345678789901295690764543434321652345\n123089789236743981234589654800387789835678987787601336\n854176590187656876104310343211456876544549016098543223\n965765410194545675465231230898565963233432145123210112\n876894321243232980370110141767653210112321039654101101\n146765232100101061289879852632154100203410128789210322\n036787103761267876518768763543069911012543454376325412\n123498654854356987405650654985678892327632567215436701\n210567569983543292314321569876301765438761078904589898\n325456478754330101223433478765432654349652987615678765"}
+
```
+
+
```elixir
+
map =
+
for {row, y} <- puzzle_input |> String.split("\n", trim: true) |> Enum.with_index(),
+
{h, x} <- row |> String.to_charlist() |> Enum.with_index(),
+
into: %{},
+
do: {{x, y}, h - ?0}
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
%{
+
{37, 47} => 3,
+
{38, 2} => 4,
+
{1, 26} => 5,
+
{32, 15} => 4,
+
{35, 30} => 3,
+
{37, 53} => 4,
+
{4, 5} => 4,
+
{8, 50} => 3,
+
{11, 39} => 1,
+
{22, 38} => 1,
+
{20, 41} => 8,
+
{29, 25} => 6,
+
{29, 26} => 0,
+
{47, 27} => 0,
+
{31, 42} => 4,
+
{9, 34} => 0,
+
{47, 38} => 2,
+
{20, 3} => 7,
+
{47, 44} => 1,
+
{22, 37} => 3,
+
{22, 36} => 0,
+
{45, 7} => 7,
+
{19, 38} => 0,
+
{27, 21} => 9,
+
{9, 33} => 1,
+
{26, 41} => 4,
+
{52, 42} => 8,
+
{21, 35} => 2,
+
{42, 8} => 6,
+
{19, 22} => 9,
+
{16, 10} => 3,
+
{21, 45} => 5,
+
{11, 8} => 7,
+
{26, 21} => 0,
+
{21, 48} => 1,
+
{50, 40} => 9,
+
{10, 25} => 9,
+
{11, 19} => 0,
+
{16, 38} => 5,
+
{35, 15} => 8,
+
{37, 15} => 6,
+
{35, 26} => 7,
+
{28, 20} => 1,
+
{45, 19} => 9,
+
{27, 22} => 8,
+
{16, 24} => 5,
+
{6, 18} => 0,
+
{10, 32} => 2,
+
{32, ...} => 8,
+
{...} => 7,
+
...
+
}
+
```
+
+
```elixir
+
starts = Enum.filter(map, fn {_, elev} -> elev == 0 end)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
[
+
{{38, 5}, 0},
+
{{24, 7}, 0},
+
{{11, 35}, 0},
+
{{3, 9}, 0},
+
{{15, 36}, 0},
+
{{41, 32}, 0},
+
{{51, 14}, 0},
+
{{51, 24}, 0},
+
{{5, 12}, 0},
+
{{4, 35}, 0},
+
{{40, 4}, 0},
+
{{46, 4}, 0},
+
{{22, 30}, 0},
+
{{27, 12}, 0},
+
{{7, 4}, 0},
+
{{24, 43}, 0},
+
{{31, 20}, 0},
+
{{29, 42}, 0},
+
{{29, 9}, 0},
+
{{10, 2}, 0},
+
{{0, 20}, 0},
+
{{15, 20}, 0},
+
{{14, 0}, 0},
+
{{42, 48}, 0},
+
{{40, 15}, 0},
+
{{43, 14}, 0},
+
{{19, 2}, 0},
+
{{14, 22}, 0},
+
{{34, 35}, 0},
+
{{38, 42}, 0},
+
{{23, 5}, 0},
+
{{0, 11}, 0},
+
{{44, 11}, 0},
+
{{15, 30}, 0},
+
{{17, 44}, 0},
+
{{31, 32}, 0},
+
{{48, 28}, 0},
+
{{21, 39}, 0},
+
{{49, 13}, 0},
+
{{29, 45}, 0},
+
{{4, 37}, 0},
+
{{53, 31}, 0},
+
{{45, 46}, 0},
+
{{43, 29}, 0},
+
{{8, 0}, 0},
+
{{47, 42}, 0},
+
{{7, 14}, 0},
+
{{52, ...}, 0},
+
{{...}, ...},
+
{...},
+
...
+
]
+
```
+
+
```elixir
+
defmodule Trail do
+
def traverse(start, map), do: MapSet.new(traverse(start, map, []))
+
+
defp traverse({curr, 9}, _map, acc), do: [[{curr, 9} | acc]]
+
defp traverse({curr, elev}, map, acc) do
+
curr
+
|> surroundings()
+
|> then(&Map.take(map, &1))
+
|> Enum.filter(fn {_, h} -> elev + 1 == h end)
+
|> Enum.flat_map(&traverse(&1, map, [{curr, elev} | acc]))
+
end
+
+
defp surroundings({x, y}) do
+
[
+
{x, y - 1},
+
{x - 1, y},
+
{x, y + 1},
+
{x + 1, y}
+
]
+
end
+
end
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:module, Trail, <<70, 79, 82, 49, 0, 0, 11, ...>>, {:surroundings, 1}}
+
```
+
+
## Part 1
+
+
```elixir
+
starts
+
|> Enum.map(fn start ->
+
Trail.traverse(start, map)
+
|> MapSet.new(&hd/1)
+
|> MapSet.size()
+
end)
+
|> Enum.sum()
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
733
+
```
+
+
## Section
+
+
```elixir
+
starts
+
|> Enum.map(fn start ->
+
Trail.traverse(start, map)
+
|> MapSet.size()
+
end)
+
|> Enum.sum()
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
1514
+
```
+
+
<!-- livebook:{"offset":6605,"stamp":{"token":"XCP.68U6SzidJCV7il26kiMv6z5qLEx_50_v2V7x6LqV9t8LQG1-aShVMNE1DEgCj9SwpKOn02np0aeSu5T1parIYMF9MeWGGfqP-oc4UGnDiDGDtJ5RGqdwcxcPjuPUQmCtZj0","version":2}} -->
+110
2024/day11.livemd
···
+
<!-- livebook:{"persist_outputs":true} -->
+
+
# Day 11
+
+
```elixir
+
Mix.install([:kino_aoc])
+
```
+
+
## Section
+
+
<!-- livebook:{"attrs":"eyJhc3NpZ25fdG8iOiJwdXp6bGVfaW5wdXQiLCJkYXkiOiIxMSIsInNlc3Npb25fc2VjcmV0IjoiQURWRU5UX09GX0NPREVfU0VTU0lPTiIsInllYXIiOiIyMDI0In0","chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2024", "11", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:ok, "554735 45401 8434 0 188 7487525 77 7"}
+
```
+
+
```elixir
+
# puzzle_input = "125 17"
+
+
stones =
+
puzzle_input
+
|> String.split()
+
|> Enum.map(&String.to_integer/1)
+
|> Enum.frequencies()
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
%{0 => 1, 7 => 1, 77 => 1, 188 => 1, 8434 => 1, 45401 => 1, 554735 => 1, 7487525 => 1}
+
```
+
+
```elixir
+
defmodule Stones do
+
def blink(list), do: Enum.reduce(list, %{}, &alter/2)
+
+
defp alter({0, count}, map), do: update(map, 1, count)
+
+
defp alter({n, count}, map) do
+
len = len(n)
+
+
if rem(len, 2) == 0 do
+
half = 10 ** div(len, 2)
+
+
map
+
|> update(div(n, half), count)
+
|> update(rem(n, half), count)
+
else
+
update(map, n * 2024, count)
+
end
+
end
+
+
defp len(n) when n < 10, do: 1
+
defp len(n) when n < 100, do: 2
+
defp len(n) when n < 1000, do: 3
+
defp len(n) when n < 10000, do: 4
+
defp len(n), do: ceil(:math.log10(n))
+
+
defp update(map, key, val), do: Map.update(map, key, val, &(&1 + val))
+
end
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:module, Stones, <<70, 79, 82, 49, 0, 0, 11, ...>>, {:update, 3}}
+
```
+
+
## Part 1
+
+
```elixir
+
1..25
+
|> Enum.reduce(stones, fn _, acc ->
+
Stones.blink(acc)
+
end)
+
|> Map.values()
+
|> Enum.sum()
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
209412
+
```
+
+
## Part 2
+
+
```elixir
+
1..75
+
|> Enum.reduce(stones, fn _, acc ->
+
Stones.blink(acc)
+
end)
+
|> Map.values()
+
|> Enum.sum()
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
248967696501656
+
```
+
+
<!-- livebook:{"offset":1963,"stamp":{"token":"XCP.YCGtDQl3XNWJm5oY1OPI2QDRB7EIjZxBmwK3eswS1ryD28kg8fS_fKGIFJGFbtL1NL7wYrv2ADW60yeAZnCv5KbDelUm_bxkPN4_K56iTJ1toOGfIRYlo2lj5beAjrmbhRw","version":2}} -->
+811
2024/day12.livemd
···
+
<!-- livebook:{"persist_outputs":true} -->
+
+
# Day 12
+
+
```elixir
+
Mix.install([:kino_aoc, :range_set])
+
```
+
+
## Section
+
+
<!-- livebook:{"attrs":"eyJhc3NpZ25fdG8iOiJwdXp6bGVfaW5wdXQiLCJkYXkiOiIxMiIsInNlc3Npb25fc2VjcmV0IjoiQURWRU5UX09GX0NPREVfU0VTU0lPTiIsInllYXIiOiIyMDI0In0","chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2024", "12", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:ok,
+
"KKKKKKZZZZZZZZDDQQQQXXXXXXXXXXXXTTTTTTTTTTTTDHHHHHHHHHHHHHHHHHGGGGGGPPPGUUGGXXGGGGGGJJJJJJJJJIIIIIIIIIIIIIIIIIIIIDIIIIIIIIIIIKIIIIIIIIIIIIIM\nKKKKKKZZZZZZZDDDQQQQXXCXXXXXXXXXTTTTTTTTTTTTTHHHHHHHHHHHHHHHHHGGGGGGGGPGUUGGGGGGGGGJJJJJJJJIIIIIIIIIIIIIIIIIIVVVIDDIIIIIIIKKKKIIIIIIIIIIIIMM\nKKKKKZZZZZZZZZZQQQQQQXCCCXXXXXXTTTTTTTTTTTTTTTHHHHHHHHHHHHHHHGGGGGGGGGGGGGGGGGGGGJJJJJJJJJJIIIIIIIIIIIIIIIIIIVIIIIDIHIIIIIIIKKIIIIIIIIIIIIMM\nKKKKKZZZZZZZZEEHQQQYQQZCCCCXXXTTTTTTTTTTTTTTHHHIIIIHHHHHHHHHHGGGGGGGGGGGGGGGGGGGGGJJJJJJJJIIIIIIIIKKKKKKIIIIIVIIIIDHHIIIIIIIIKIIIIIIIIIIIIIM\nKKKKKKOOEZEEEEHHQQQYYCCCCCCTTTTTTTTTTTTTTTTTVVVIIIIHHHHHHBBBBGGGGGGGGGGGGGGGGGGGGJJJJJJJJJIIIIIIIBCKKKKKIIIIIIIIHHHHHIIIIIIIIIIIIIIIIIIIMMMM\nKKKKKOOEEEEEEEHHHQQYYCCCCCCCCCTTTTTTTTTTTOOTTIIIIIHHHHHHHHHBBBGGGGGGGGGGGGGGGGGGGJJJJJJJJJIIIIIBBBCKKKKKKKIIIIIHHHHHIIIIIIIIIIIIIIIIIIIIIIMM\nKKKKKKOGGEEEGHHHHQDDYYCCCCCCCOOTTTTTTTTTTTIDIIIIIIIHHHHHHBBBBBGGGGGGGGGGGGGGGGGGGGJJJJJJJJIIIIBBBBKKKKKKKKIKIIIBHHHHHIIIIIIIIIIIIIIIIIIIIIIM\nKKKKTKOOGEGGGHGHDDDDDYYYCCCCCOOTTTTTTTTTTIIIIIIIIIIHHHHHBBBBBBGGGGGJGGGQGGLGGGGGGJJJJJJRRJJJBBBBKKKKKKKKKKKKKKFHHHHHHHIHHIIIIIRIIIIIIIIIIMMM\nKRRRVOOGGGGGGGGGDDDDPDDYDSSCCCOOOTTOTTTTTIIIIIIIIIIHHHBHBBBBBBGGGGGJGJJGGGGGGGGGGJJJJJRRRRRWBBBBBBVKKKKKKKKKKTHHHHHHHHHHIIIIIIIIIIIIIIGIIMMM\nYVRVVOOGGGGGGGDDDDDDDDDDDSSCCOOOOOOOTOOOIIIIIIIIIIIHHBBBBBBBBBGGGGGJJJJJGGGCGGFFGFFJRRRRRRRWWBBBBBBKKKKKKKKKKKHHHHHHHHHFFIIIIIIIIIIIIIGIVVMM\nYVRVVVVGGGGGGGDDDDDDDDDDDDDCCOOOOOOOOOOOIIIIIIIIIIIHHHBBBBBBBBBBGGJJJJJJJJJGGGFFFFRRRRRRRRRRRBBBBBKKKKKKKKKKKKKHHHHHHHHFIIIIIIIIIIIIIIIIVVVM\nYVVVVVVVVGGGGGGDDDDDDDDDDDDOOOOOOOOOOOOOOIIIIIIEEIIHHHOBBBBBBBBBBGJJJJJJJJJFFFFFFFFFRRRRRRRRRRBBBBKBKKKKKKKKKKKHHHHHHFFFFIIFIIIIZIIAIIIIVVMM\nVVVVVVVVVGGGGGGDDDDDDDDDDDOOOOOOOOOOOOOOOOOOOIOOEJJHHHOBBBBBBBBBBEEJEEEEEFFFFFFFFFFFRRRRRRRNBBBBBBBBKKKKKKKKKKRHHHHHHFFFFFFFIIIIIIIIBBIIVMMM\nVVVVVVVVVGGGGGDDDDDDDDDDDDEOOOOOOOOOOOOOOOOOOOOOEEJHHOOOBBBBGGGGBEEEHEEXFFFFFFFFFFFFRRRRRRBNBBBBBBBBKKKKKKKKKKHHHHHHHFFFFFFFIIIIIIIIBBVVVMMM\nVVVVVVVVGGGGGDPDDDDDDDDDDDEEOOOOOOOOOOOOOOOOOOOOEEJEOOOOBGGGGGGGHEEEEEEFFFLFFFFFFFFRRRRRRRBBBBBBBBBBBKKKKKKKKFHHHHHFFFFFFFFIIIIIIIIIIVVVVVMM\nVVVVVVVVGGGGGDDDDDDDDDDDDDDEOOOOOOOOGOOOOOEOIIOOEEEEOOOOOGGGGGGGEEEEEEEFFFFFFFFFFFFFRDRRXXBBBBBBBBBBBKKKKKKKKKBBHHHHFFFFFFFIIIIIIIIIVVVVVVLM\nVVVVVVVVWGGGGDDDDDDDDDDDDEEEOOOOOOGGGOOOOOOIIIIIEEOOOOBOOGGGGGGGUEEEEEGUFFFFFFFFFFFFDDDDMMSBBBBBBBBBBBBBKKKKKKBBBHHFFFFFFFFIIIIINNWIVVVVVVLL\nVVVVVVZZZFGGGRDDDDDDDDDDDEOOOOOOOFFFGOGOOIIIBIBBBEOBBBBBBGGGGGGGEEEEEGGUUFFFFFFFFFFFDDDDDMMMBBBBBBBBBBBKKKKKKBBBBHHFFFFFFFFFIINNNNNPPVVVVLLL\nVVVZZZZZZZIGRRADADDDDDDDDEOEEOYYGFFGGOGGGIIIBBBBBEBBBBBBBGGGGGGGFEEEGGGGUUFFFFFFFFFHDVVVVVVMBBBBBBBBBBBKKKKBBBBBBBBBFFFFFFFRRRRNNNNPPVVLLLLL\nVVZZZZZZZZZRRRADAADEEEDDDEEEEOYYGGGGGGGGGGIBBBBBBBBBBBBBBGGGGGGGEEEEBGGGUUFFFFFFFFFHHVVVVVVMBBBBBBBBBPBKKBBBBBBBBBBFFFFFFFFFRBRNNNNNNNVLLLLL\nVZZZZZBZZZNAAAAAAAAEEEEEEEEEGGYYGGGGGGGGGIIBBBBBBBBBBBBBBGGGGGFFFEEBBGGGGCFFFFFFFFFHHVVVVVVMBBBBBBBMMMMMBBBBBBBGBBBFFFFFFFGGBBBNNNNNLLLLLLLL\nBBBBBBBZZNNNAAAAAAEEEEEEGEEEEGYYGGGGGGGIIIIBBBBBBBBBBBBBBGGGGGFFCCCBGGGCCCFCCWWWWWWWHVVVVVVMMBBBMMMMMMMMBBBBBBBGBGGTTFFFFFFFFBBNNNNNLLLLLLLL\nJBBBBBBBZZNAAAAAAAAAAGGGGGGEGGGGGGGGGGGGGIHDBBBBBBBBBBBBBBFFFFFCCCCCGGGCCKCCCWHHHHHHHVVVVVVMMVVVVVVMMMMMBBBBBBGGBGGTFFFFTFFFFBBBBBBBBBLLLLLL\nJJJBBBBBBAAAAAAAAAAAGGGGGGGEGGGGGGGGGGGGIIHDBBBBBBBBBBBBBBBBFFFCZCCCCCCCCCCCCHHHHHHHHVVVVVVMMVVVVVVMMMMMBBBBBBGGGGGTTFFTTFFFBBBBBBBBBBLLLLLL\nJJJBBBBAAAAAAAAAAAAAGGGGGGGGGGGGGGGGGGGGIHHDHHHHBBBBBBSSSSFFFFFCCCCCCCCCCCCCCHHHHHHHHVVVVVVHHVVVVVVMMMMMBBBBBBGGGGGTTTTTTFHFBBBBBBBBBBBLBBLV\nJJJJJJAAAAAAAAAAAAAAGGGGGGGGGGGGGGGGGGGHHHHHHHHHHIJJJJJSSSSFFFCCFFCCCCCCCCCCCHHHHHHHHVVVVVVVVVVVVVVMMMMMMBBBBGGGGGGGGGTTTLLBBBBBBBBBBBBBBBBV\nJJJJJJAAAAAAAAAAAAAAGAAGGGGGGGGGGGGGGGGHHHHHHHHHHJJJHJSSSSSFFFFFFCCCCCCCCCCCCHRHHHHHHVVVVVVVVVVVVVVGMMMMMBBBBGGGGGGGGGTTLLLLLLBBBBBBBBBBBBBB\nJJJJJJAAAAAAAAAAAAAAAAGGGGGGGGHGGGGGGGGHHHHHHHHHHJJJJJJJSJSFFFFFCCCCCCCCCCCCCCHHHHHHHVVVVVVVVVVVVVVGGMMCMBBBGGGGGGGGPGGGLLZLLLBBBBBBBBBBBBBB\nJJJJJJAAAAAAAAAAAAAAGAGGGGGGGGGGGGZZGHGHHHHHHHHHJJJJJJJJJJSFFFFFCCCCCCCCCCCCCCHHHHHHHHHOHHOOMVVVVVVGGJGGIBBBTGGGGGGTGGGLLLLLLLLBBBBBBBBBBBBB\nJJJJJAA" <> ...}
+
```
+
+
```elixir
+
map =
+
puzzle_input
+
|> String.split("\n", trim: true)
+
|> Enum.with_index()
+
|> Enum.flat_map(fn {row, y} ->
+
row
+
|> String.split("", trim: true)
+
|> Enum.with_index()
+
|> Enum.map(fn {plant, x} -> {{x, y}, plant} end)
+
end)
+
|> Map.new()
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
%{
+
{18, 103} => "H",
+
{76, 13} => "F",
+
{61, 121} => "X",
+
{112, 138} => "T",
+
{37, 47} => "U",
+
{65, 63} => "G",
+
{77, 129} => "E",
+
{120, 47} => "L",
+
{38, 2} => "T",
+
{1, 26} => "J",
+
{116, 69} => "W",
+
{124, 56} => "O",
+
{83, 76} => "N",
+
{117, 125} => "Q",
+
{100, 134} => "W",
+
{78, 139} => "D",
+
{32, 15} => "O",
+
{103, 106} => "N",
+
{30, 113} => "J",
+
{123, 104} => "W",
+
{68, 134} => "Q",
+
{124, 60} => "O",
+
{89, 14} => "R",
+
{35, 30} => "E",
+
{37, 53} => "H",
+
{77, 130} => "E",
+
{2, 132} => "Q",
+
{4, 5} => "K",
+
{8, 50} => "X",
+
{78, 98} => "Y",
+
{101, 62} => "X",
+
{98, 136} => "W",
+
{95, 56} => "D",
+
{74, 12} => "F",
+
{17, 138} => "F",
+
{102, 74} => "S",
+
{11, 39} => "P",
+
{131, 5} => "I",
+
{65, 43} => "S",
+
{22, 38} => "R",
+
{14, 86} => "N",
+
{139, 46} => "U",
+
{12, 135} => "Q",
+
{65, 131} => "A",
+
{49, 117} => "O",
+
{20, 41} => "D",
+
{29, 25} => "G",
+
{86, 10} => "R",
+
{83, ...} => "I",
+
{...} => "G",
+
...
+
}
+
```
+
+
```elixir
+
defmodule Garden do
+
def plots(map) do
+
map
+
|> Enum.group_by(&elem(&1, 1), &elem(&1, 0))
+
|> Enum.flat_map(fn {kind, pts} ->
+
for parcel <- parcels(MapSet.new(pts), []) do
+
{kind, parcel}
+
end
+
end)
+
end
+
+
def parcels(set, acc) do
+
case Enum.take(set, 1) do
+
[] ->
+
acc
+
+
[p] ->
+
{parcel, rest} = flood(p, MapSet.new(), set)
+
+
parcels(rest, [parcel | acc])
+
end
+
end
+
+
def flood({x, y} = curr, visited, potential) do
+
visited = MapSet.put(visited, curr)
+
potential = MapSet.delete(potential, curr)
+
+
for next <- [
+
{x - 1, y},
+
{x + 1, y},
+
{x, y - 1},
+
{x, y + 1}
+
],
+
next in potential,
+
reduce: {visited, potential} do
+
{v, p} -> flood(next, v, p)
+
end
+
end
+
+
def as_int(false), do: 0
+
def as_int(true), do: 1
+
end
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:module, Garden, <<70, 79, 82, 49, 0, 0, 15, ...>>, {:as_int, 1}}
+
```
+
+
```elixir
+
plots = Garden.plots(map)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
[
+
{"A", MapSet.new([{131, 11}])},
+
{"A",
+
MapSet.new([
+
{54, 38},
+
{54, 39},
+
{55, 38},
+
{56, 36},
+
{56, 37},
+
{56, 38},
+
{57, 37},
+
{57, 38},
+
{57, 39},
+
{57, 40},
+
{58, 36},
+
{58, 37},
+
{58, 38},
+
{58, 39},
+
{58, 40},
+
{59, 36},
+
{59, 37},
+
{59, 38},
+
{60, 36},
+
{60, 37},
+
{60, 38},
+
{61, 36},
+
{61, 37},
+
{61, 38},
+
{62, 38},
+
{63, 38}
+
])},
+
{"A", MapSet.new([{18, 56}])},
+
{"A",
+
MapSet.new([
+
{93, 86},
+
{94, 86},
+
{95, 86},
+
{95, 87},
+
{95, 88},
+
{96, 86},
+
{96, 87},
+
{97, 80},
+
{97, 81},
+
{97, 82},
+
{97, 83},
+
{97, 84},
+
{97, 85},
+
{97, 86},
+
{97, 87},
+
{98, 80},
+
{98, 81},
+
{98, 82},
+
{98, 83},
+
{98, 84},
+
{98, 85},
+
{99, 81},
+
{99, 82},
+
{99, 84}
+
])},
+
{"A",
+
MapSet.new([
+
{35, 102},
+
{42, 111},
+
{38, 112},
+
{38, 108},
+
{39, 111},
+
{35, 106},
+
{41, 105},
+
{36, 105},
+
{36, 108},
+
{42, 110},
+
{35, 104},
+
{36, 109},
+
{43, 111},
+
{42, 107},
+
{41, 107},
+
{37, 108},
+
{41, 111},
+
{42, 108},
+
{39, 107},
+
{35, 103},
+
{36, 111},
+
{37, 113},
+
{37, 105},
+
{40, 110},
+
{38, 107},
+
{43, 107},
+
{38, 105},
+
{41, 110},
+
{34, 108},
+
{37, 109},
+
{35, 108},
+
{36, 106},
+
{42, 109},
+
{38, 114},
+
{37, 112},
+
{39, 110},
+
{39, 109},
+
{36, 103},
+
{38, 110},
+
{37, 111},
+
{39, 108},
+
{38, ...},
+
{...},
+
...
+
])},
+
{"A", MapSet.new([{70, 115}, {70, 116}, {70, 117}, {71, 116}, {71, 117}, {72, 116}, {72, 117}])},
+
{"A",
+
MapSet.new([
+
{85, 84},
+
{88, 82},
+
{87, 83},
+
{83, 84},
+
{87, 79},
+
{86, 82},
+
{86, 84},
+
{83, 85},
+
{87, 78},
+
{87, 84},
+
{85, 79},
+
{87, 81},
+
{85, 80},
+
{88, 83},
+
{84, 84},
+
{86, 81},
+
{86, 80},
+
{82, 85},
+
{85, 82},
+
{82, 84},
+
{82, 86},
+
{88, 81},
+
{87, 82},
+
{86, 83},
+
{85, 81},
+
{83, 83},
+
{84, 80},
+
{88, 84},
+
{83, 86},
+
{87, 80},
+
{87, 77},
+
{81, 85},
+
{85, 83},
+
{84, 85},
+
{84, 82},
+
{84, 81},
+
{84, 83}
+
])},
+
{"A",
+
MapSet.new([
+
{19, 22},
+
{10, 25},
+
{16, 24},
+
{10, 32},
+
{17, 30},
+
{6, 29},
+
{18, 29},
+
{17, 22},
+
{13, 25},
+
{14, 24},
+
{10, 23},
+
{8, 29},
+
{13, 22},
+
{14, 28},
+
{6, 26},
+
{18, 26},
+
{16, 23},
+
{21, 26},
+
{19, 30},
+
{13, 27},
+
{16, 18},
+
{18, 23},
+
{9, 25},
+
{16, 29},
+
{7, 26},
+
{12, 27},
+
{16, 30},
+
{17, 24},
+
{18, 24},
+
{18, 22},
+
{6, 28},
+
{13, 20},
+
{9, 26},
+
{7, 27},
+
{11, 22},
+
{8, 25},
+
{17, 23},
+
{13, 23},
+
{20, ...},
+
{...},
+
...
+
])},
+
{"A",
+
MapSet.new([
+
{111, 103},
+
{107, 102},
+
{110, 102},
+
{110, 106},
+
{112, 103},
+
{114, 103},
+
{112, 100},
+
{108, 97},
+
{103, 96},
+
{109, 104},
+
{103, 99},
+
{108, 95},
+
{110, 104},
+
{113, 101},
+
{105, 105},
+
{108, 108},
+
{106, 105},
+
{111, 100},
+
{104, 98},
+
{109, 101},
+
{111, 104},
+
{107, 100},
+
{106, 102},
+
{112, 106},
+
{105, 95},
+
{104, 104},
+
{112, 97},
+
{108, 94},
+
{104, 97},
+
{111, 99},
+
{108, 102},
+
{108, 109},
+
{101, 97},
+
{104, 103},
+
{102, 96},
+
{112, 101},
+
{113, 97},
+
{100, ...},
+
{...},
+
...
+
])},
+
{"A",
+
MapSet.new([
+
{132, 99},
+
{136, 110},
+
{137, 104},
+
{139, 106},
+
{134, 98},
+
{139, 101},
+
{136, 102},
+
{139, 104},
+
{136, 96},
+
{134, 107},
+
{132, 100},
+
{138, 96},
+
{138, 102},
+
{135, 109},
+
{137, 107},
+
{133, 97},
+
{135, 107},
+
{137, 101},
+
{139, 97},
+
{137, 100},
+
{139, 109},
+
{135, 100},
+
{137, 97},
+
{132, 97},
+
{138, 105},
+
{137, 106},
+
{138, 99},
+
{136, 100},
+
{135, 98},
+
{139, 98},
+
{138, 103},
+
{138, 107},
+
{136, 108},
+
{139, 99},
+
{133, 96},
+
{139, 105},
+
{132, ...},
+
{...},
+
...
+
])},
+
{"A",
+
MapSet.new([
+
{84, 102},
+
{82, 100},
+
{86, 101},
+
{82, 91},
+
{86, 93},
+
{90, 93},
+
{88, 93},
+
{86, 96},
+
{82, 95},
+
{84, 93},
+
{85, 97},
+
{87, 95},
+
{81, 95},
+
{83, 100},
+
{87, 93},
+
{81, 100},
+
{84, 96},
+
{88, 95},
+
{81, 98},
+
{84, 100},
+
{85, 102},
+
{84, 91},
+
{82, 97},
+
{85, 99},
+
{83, 95},
+
{89, 96},
+
{88, 94},
+
{84, 104},
+
{86, 102},
+
{80, 92},
+
{89, 94},
+
{86, 103},
+
{83, 92},
+
{83, 96},
+
{82, 102},
+
{84, ...},
+
{...},
+
...
+
])},
+
{"A",
+
MapSet.new([
+
{65, 131},
+
{65, 129},
+
{74, 135},
+
{72, 134},
+
{71, 133},
+
{66, 130},
+
{73, 135},
+
{69, 130},
+
{74, 134},
+
{66, 132},
+
{68, 132},
+
{67, 128},
+
{69, 133},
+
{71, 132},
+
{70, 134},
+
{72, 132},
+
{72, 133},
+
{69, 132},
+
{71, 130},
+
{74, 136},
+
{73, 136},
+
{70, 128},
+
{68, 130},
+
{69, 129},
+
{73, 133},
+
{69, 131},
+
{70, 129},
+
{70, 130},
+
{67, 133},
+
{68, 131},
+
{68, 129},
+
{72, 135},
+
{68, 128},
+
{73, 134},
+
{66, ...},
+
{...},
+
...
+
])},
+
{"B", MapSet.new([{132, 12}, {132, 13}, {133, 12}, {133, 13}])},
+
{"B", MapSet.new([{111, 6}])},
+
{"B", MapSet.new([{104, 115}])},
+
{"B", MapSet.new([{83, 87}, {84, 87}, {84, 88}])},
+
{"B", MapSet.new([{83, 82}])},
+
{"B", MapSet.new([{71, 79}])},
+
{"B",
+
MapSet.new([
+
{69, 112},
+
{70, 109},
+
{70, 111},
+
{70, 112},
+
{71, 108},
+
{71, 109},
+
{71, 110},
+
{71, 111},
+
{72, 108}
+
])},
+
{"B", MapSet.new([{67, 20}, {67, 21}, {68, 19}, {68, 20}])},
+
{"B", MapSet.new([{63, 100}])},
+
{"B", MapSet.new([{44, 121}, {44, 122}])},
+
{"B", MapSet.new([{41, 45}])},
+
{"B", MapSet.new([{30, 54}])},
+
{"B", MapSet.new([{18, 90}])},
+
{"B", MapSet.new([{10, 127}])},
+
{"B", MapSet.new([{9, 126}])},
+
{"B",
+
MapSet.new([
+
{37, 75},
+
{39, 77},
+
{42, 73},
+
{35, 75},
+
{39, 81},
+
{40, 75},
+
{41, 75},
+
{40, 77},
+
{40, 81},
+
{40, 76},
+
{32, 78},
+
{33, 78},
+
{32, 77},
+
{37, 80},
+
{35, 79},
+
{34, 75},
+
{30, 78},
+
{39, 76},
+
{34, ...},
+
{...},
+
...
+
])},
+
{"B", MapSet.new([{42, 69}])},
+
{"B",
+
MapSet.new([
+
{0, 21},
+
{1, 21},
+
{1, 22},
+
{2, 21},
+
{2, 22},
+
{3, 21},
+
{3, 22},
+
{3, 23},
+
{3, 24},
+
{4, 21},
+
{4, 22},
+
{4, 23},
+
{4, 24},
+
{5, 21},
+
{5, 22},
+
{5, 23},
+
{5, ...},
+
{...},
+
...
+
])},
+
{"B", MapSet.new([{100, 130}])},
+
{"B",
+
MapSet.new([
+
{108, 25},
+
{108, 21},
+
{104, 24},
+
{104, 21},
+
{109, 18},
+
{107, 25},
+
{107, 18},
+
{109, 17},
+
{107, 27},
+
{106, 22},
+
{113, 20},
+
{112, 17},
+
{106, 26},
+
{108, 24},
+
{105, ...},
+
{...},
+
...
+
])},
+
{"B",
+
MapSet.new([
+
{15, 93},
+
{18, 93},
+
{17, 93},
+
{19, 97},
+
{13, 98},
+
{16, 93},
+
{17, 97},
+
{13, 95},
+
{14, 93},
+
{12, 95},
+
{15, 98},
+
{15, 96},
+
{14, 95},
+
{14, ...},
+
{...},
+
...
+
])},
+
{"B",
+
MapSet.new([
+
{45, 19},
+
{53, 23},
+
{54, 16},
+
{55, 17},
+
{53, 19},
+
{55, 20},
+
{56, 18},
+
{55, 21},
+
{49, 20},
+
{56, 22},
+
{47, 22},
+
{54, 23},
+
{47, ...},
+
{...},
+
...
+
])},
+
{"B",
+
MapSet.new([
+
{98, 9},
+
{97, 20},
+
{95, 16},
+
{100, 18},
+
{94, 21},
+
{97, 10},
+
{102, 16},
+
{93, 17},
+
{98, 19},
+
{95, 17},
+
{96, 13},
+
{92, ...},
+
{...},
+
...
+
])},
+
{"B",
+
MapSet.new([
+
{58, 10},
+
{61, 7},
+
{53, 9},
+
{58, 8},
+
{55, 11},
+
{60, 10},
+
{60, 11},
+
{60, 12},
+
{61, 11},
+
{59, 13},
+
{56, ...},
+
{...},
+
...
+
])},
+
{"B",
+
MapSet.new([
+
{131, 24},
+
{129, 25},
+
{130, 28},
+
{132, 31},
+
{127, 22},
+
{132, 33},
+
{130, 25},
+
{123, 25},
+
{130, 27},
+
{126, ...},
+
{...},
+
...
+
])},
+
{"B", MapSet.new([{30, 42}, {31, 42}, {32, 42}])},
+
{"C", MapSet.new([{114, 87}, {114, 88}])},
+
{"C", MapSet.new([{103, 27}])},
+
{"C", MapSet.new([{98, 4}, {98, 5}])},
+
{"C", MapSet.new([{92, 104}])},
+
{"C", MapSet.new([{83, 33}])},
+
{"C", MapSet.new([{82, 87}])},
+
{"C", MapSet.new([{76, 32}])},
+
{"C", MapSet.new([{75, ...}])},
+
{"C", MapSet.new([{...}])},
+
{"C", MapSet.new([...])},
+
{"C", ...},
+
{...},
+
...
+
]
+
```
+
+
## Part 1
+
+
```elixir
+
defmodule Garden.Circ do
+
def circumfence(set) do
+
{{sx, _}, {ex, _}} = Enum.min_max_by(set, &elem(&1, 0))
+
{{_, sy}, {_, ey}} = Enum.min_max_by(set, &elem(&1, 1))
+
+
rows = (sx - 1)..(ex + 1)//1
+
cols = (sy - 1)..(ey + 1)//1
+
+
vert =
+
rows
+
|> Enum.map(fn x -> count_flips(cols, &({x, &1} in set)) end)
+
|> Enum.sum()
+
+
hori =
+
cols
+
|> Enum.map(fn y -> count_flips(rows, &({&1, y} in set)) end)
+
|> Enum.sum()
+
+
vert + hori
+
end
+
+
defp count_flips(enum, init \\ false, func) do
+
Enum.reduce(enum, {0, init}, fn elem, {count, last} ->
+
curr = func.(elem)
+
{count + Garden.as_int(last != curr), curr}
+
end)
+
|> elem(0)
+
end
+
end
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:module, Garden.Circ, <<70, 79, 82, 49, 0, 0, 15, ...>>, {:count_flips, 3}}
+
```
+
+
```elixir
+
plots
+
|> Enum.map(fn {_, points} ->
+
Garden.Circ.circumfence(points) * MapSet.size(points)
+
end)
+
|> Enum.sum()
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
1464678
+
```
+
+
## Part 2
+
+
```elixir
+
defmodule Garden.Sides do
+
def sides(set) do
+
xy = do_count(set, 0, 1)
+
yx = do_count(set, 1, 0)
+
+
xy + yx
+
end
+
+
defp do_count(set, a, b) do
+
set
+
|> Enum.group_by(&elem(&1, a), &elem(&1, b))
+
|> Enum.sort()
+
|> Enum.map(fn {_, row} -> row |> Enum.map(&(&1..&1)) |> RangeSet.new() end)
+
|> Enum.chunk_every(2, 1, [RangeSet.new()])
+
|> Enum.flat_map(fn [top, bot] ->
+
top.ranges
+
|> Enum.map(fn a..b//_ ->
+
Garden.as_int(not Enum.any?(bot.ranges, &(a == &1.first))) +
+
Garden.as_int(not Enum.any?(bot.ranges, &(b == &1.last)))
+
end)
+
end)
+
|> Enum.sum()
+
end
+
end
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:module, Garden.Sides, <<70, 79, 82, 49, 0, 0, 16, ...>>, {:do_count, 3}}
+
```
+
+
```elixir
+
plots
+
|> Enum.map(fn {_, plot} ->
+
Garden.Sides.sides(plot) * MapSet.size(plot)
+
end)
+
|> Enum.sum()
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
877492
+
```
+
+
<!-- livebook:{"offset":17848,"stamp":{"token":"XCP.d5P0-cESwFZ7qUYI4K40J_3AxksZ7WIqnIE6sn4smJvJahembJKNW-3db5gLxIgp_FEyn1pBBioGJSDsU7MO2fi1HjFgxeFNU0dLXi9Z4tf68Ey8dtld73d7SrSGlcv2DDM","version":2}} -->
+272
2024/day13.livemd
···
+
<!-- livebook:{"persist_outputs":true} -->
+
+
# Day 13
+
+
```elixir
+
Mix.install([:kino_aoc])
+
```
+
+
## Section
+
+
<!-- livebook:{"attrs":"eyJhc3NpZ25fdG8iOiJwdXp6bGVfaW5wdXQiLCJkYXkiOiIxMyIsInNlc3Npb25fc2VjcmV0IjoiQURWRU5UX09GX0NPREVfU0VTU0lPTiIsInllYXIiOiIyMDI0In0","chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2024", "13", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:ok,
+
"Button A: X+22, Y+88\nButton B: X+90, Y+28\nPrize: X=6496, Y=3076\n\nButton A: X+54, Y+14\nButton B: X+14, Y+44\nPrize: X=8084, Y=1284\n\nButton A: X+96, Y+15\nButton B: X+55, Y+63\nPrize: X=5535, Y=3966\n\nButton A: X+17, Y+42\nButton B: X+40, Y+25\nPrize: X=12176, Y=3136\n\nButton A: X+87, Y+31\nButton B: X+15, Y+36\nPrize: X=6672, Y=2500\n\nButton A: X+59, Y+27\nButton B: X+21, Y+56\nPrize: X=1475, Y=15098\n\nButton A: X+39, Y+51\nButton B: X+98, Y+14\nPrize: X=7890, Y=3126\n\nButton A: X+23, Y+37\nButton B: X+35, Y+14\nPrize: X=16537, Y=6184\n\nButton A: X+21, Y+89\nButton B: X+74, Y+23\nPrize: X=2407, Y=8748\n\nButton A: X+47, Y+17\nButton B: X+35, Y+59\nPrize: X=17994, Y=16242\n\nButton A: X+14, Y+45\nButton B: X+52, Y+16\nPrize: X=18768, Y=3912\n\nButton A: X+29, Y+45\nButton B: X+85, Y+11\nPrize: X=3149, Y=4161\n\nButton A: X+81, Y+95\nButton B: X+67, Y+12\nPrize: X=5489, Y=2110\n\nButton A: X+48, Y+58\nButton B: X+86, Y+22\nPrize: X=4802, Y=2280\n\nButton A: X+27, Y+59\nButton B: X+47, Y+15\nPrize: X=2602, Y=2090\n\nButton A: X+39, Y+87\nButton B: X+94, Y+38\nPrize: X=8830, Y=6134\n\nButton A: X+23, Y+61\nButton B: X+82, Y+16\nPrize: X=8405, Y=3957\n\nButton A: X+54, Y+14\nButton B: X+24, Y+63\nPrize: X=894, Y=1708\n\nButton A: X+26, Y+14\nButton B: X+18, Y+35\nPrize: X=5510, Y=12541\n\nButton A: X+65, Y+55\nButton B: X+21, Y+69\nPrize: X=430, Y=620\n\nButton A: X+11, Y+62\nButton B: X+50, Y+11\nPrize: X=11414, Y=3683\n\nButton A: X+21, Y+54\nButton B: X+93, Y+22\nPrize: X=7683, Y=5642\n\nButton A: X+20, Y+95\nButton B: X+52, Y+29\nPrize: X=5580, Y=10155\n\nButton A: X+37, Y+13\nButton B: X+11, Y+66\nPrize: X=18250, Y=14983\n\nButton A: X+54, Y+28\nButton B: X+37, Y+58\nPrize: X=17939, Y=14902\n\nButton A: X+87, Y+65\nButton B: X+11, Y+79\nPrize: X=3765, Y=4087\n\nButton A: X+74, Y+30\nButton B: X+16, Y+59\nPrize: X=9858, Y=8342\n\nButton A: X+74, Y+31\nButton B: X+17, Y+59\nPrize: X=14764, Y=6598\n\nButton A: X+12, Y+95\nButton B: X+27, Y+33\nPrize: X=945, Y=3324\n\nButton A: X+21, Y+36\nButton B: X+34, Y+14\nPrize: X=7247, Y=5012\n\nButton A: X+48, Y+62\nButton B: X+90, Y+29\nPrize: X=9150, Y=5973\n\nButton A: X+93, Y+43\nButton B: X+49, Y+91\nPrize: X=7090, Y=6422\n\nButton A: X+28, Y+70\nButton B: X+68, Y+21\nPrize: X=17176, Y=3693\n\nButton A: X+33, Y+16\nButton B: X+27, Y+51\nPrize: X=1884, Y=2771\n\nButton A: X+11, Y+43\nButton B: X+51, Y+19\nPrize: X=4114, Y=10066\n\nButton A: X+26, Y+70\nButton B: X+87, Y+46\nPrize: X=3532, Y=6874\n\nButton A: X+22, Y+35\nButton B: X+38, Y+13\nPrize: X=7508, Y=16592\n\nButton A: X+33, Y+16\nButton B: X+48, Y+72\nPrize: X=12065, Y=15896\n\nButton A: X+67, Y+25\nButton B: X+14, Y+55\nPrize: X=4093, Y=10275\n\nButton A: X+36, Y+17\nButton B: X+43, Y+77\nPrize: X=3253, Y=1933\n\nButton A: X+84, Y+24\nButton B: X+42, Y+69\nPrize: X=8862, Y=4869\n\nButton A: X+70, Y+16\nButton B: X+17, Y+68\nPrize: X=5690, Y=3224\n\nButton A: X+58, Y+27\nButton B: X+44, Y+92\nPrize: X=1890, Y=1595\n\nButton A: X+64, Y+30\nButton B: X+29, Y+57\nPrize: X=15004, Y=15224\n\nButton A: X+13, Y+90\nButton B: X+64, Y+33\nPrize: X=6560, Y=6048\n\nButton A: X+37, Y+91\nButton B: X+64, Y+49\nPrize: X=5214, Y=8379\n\nButton A: X+12, Y+80\nButton B: X+75, Y+25\nPrize: X=6684, Y=8460\n\nButton A: X+27, Y+53\nButton B: X+53, Y+30\nPrize: X=4897, Y=14148\n\nButton A: X+41, Y+11\nButton B: X+39, Y+72\nPrize: X=2818, Y=493\n\nButton A: X+74, Y+45\nButton B: X+14, Y+35\nPrize: X=8996, Y=13510\n\nButton A: X+11, Y+36\nButton B: X+86, Y+58\nPrize: X=18273, Y=14722\n\nButton A: X+99, Y+72\nButton B: X+11, Y+39\nPrize: X=2530, Y=3390\n\nButton A: X+55, Y+17\nButton B: X+22, Y+80\nPrize: X=3652, Y=6326\n\nButton A: X+11, Y+17\nButton B: X+76, Y+16\nPrize: X=5480, Y=1976\n\nButton A: X+18, Y+73\nButton B: X+28, Y+22\nPrize: X=3222, Y=4827\n\nButton A: X+14, Y+46\nButton B: X+33, Y+29\nPrize: X=2212, Y=3932\n\nButton A: X+11, Y+14\nButton B: X+80, Y+28\nPrize: X=4187, Y=2450\n\nButton A: X+28, Y+70\nButton B: X+78, Y+25\nPrize: X=2220, Y=1810\n\nButton A: X+53, Y+19\nButton B: X+73, Y+91\nPrize: X=4514, Y=2850\n\nButton A: X+21, Y+54\nButton B: X+54, Y+25\nPrize: X=5609, Y=7594\n\nButton A: X+79, Y+15\nButton B: X+16, Y+80\nPrize: X=14993, Y=17105\n\nButton A: X+20, Y+59\nButton B: X+35, Y+17\nPrize: X=10820, Y=1709\n\nButton A: X+96, Y+22\nButton B: X+24, Y+43\n" <> ...}
+
```
+
+
```elixir
+
#puzzle_input =
+
"""
+
Button A: X+94, Y+34
+
Button B: X+22, Y+67
+
Prize: X=8400, Y=5400
+
+
Button A: X+26, Y+66
+
Button B: X+67, Y+21
+
Prize: X=12748, Y=12176
+
+
Button A: X+17, Y+86
+
Button B: X+84, Y+37
+
Prize: X=7870, Y=6450
+
+
Button A: X+69, Y+23
+
Button B: X+27, Y+71
+
Prize: X=18641, Y=10279
+
"""
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
warning: outdented heredoc line. The contents inside the heredoc should be indented at the same level as the closing """. The following is forbidden:
+
+
def text do
+
"""
+
contents
+
"""
+
end
+
+
Instead make sure the contents are indented as much as the heredoc closing:
+
+
def text do
+
"""
+
contents
+
"""
+
end
+
+
The current heredoc line is indented too little
+
โ””โ”€ Workspace/hauleth/advent-of-code/2024/day13.livemd#cell:b6uoz4dag7jywljr:3:3
+
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
"Button A: X+94, Y+34\nButton B: X+22, Y+67\nPrize: X=8400, Y=5400\n\nButton A: X+26, Y+66\nButton B: X+67, Y+21\nPrize: X=12748, Y=12176\n\nButton A: X+17, Y+86\nButton B: X+84, Y+37\nPrize: X=7870, Y=6450\n\nButton A: X+69, Y+23\nButton B: X+27, Y+71\nPrize: X=18641, Y=10279\n"
+
```
+
+
```elixir
+
games =
+
puzzle_input
+
|> String.split("\n\n", trim: true)
+
|> Enum.map(fn game ->
+
[
+
"Button A: X+" <> <<ax::2-binary>> <> ", Y+" <> <<ay::2-binary>>,
+
"Button B: X+" <> <<bx::2-binary>> <> ", Y+" <> <<by::2-binary>>,
+
"Prize: " <> prize_pos
+
] = String.split(game, "\n", trim: true)
+
+
["X=" <> px, "Y=" <> py] = String.split(prize_pos, ", ")
+
+
%{
+
btn_a: {String.to_integer(ax), String.to_integer(ay)},
+
btn_b: {String.to_integer(bx), String.to_integer(by)},
+
prize: {String.to_integer(px), String.to_integer(py)}
+
}
+
end)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
[
+
%{btn_a: {22, 88}, btn_b: {90, 28}, prize: {6496, 3076}},
+
%{btn_a: {54, 14}, btn_b: {14, 44}, prize: {8084, 1284}},
+
%{btn_a: {96, 15}, btn_b: {55, 63}, prize: {5535, 3966}},
+
%{btn_a: {17, 42}, btn_b: {40, 25}, prize: {12176, 3136}},
+
%{btn_a: {87, 31}, btn_b: {15, 36}, prize: {6672, 2500}},
+
%{btn_a: {59, 27}, btn_b: {21, 56}, prize: {1475, 15098}},
+
%{btn_a: {39, 51}, btn_b: {98, 14}, prize: {7890, 3126}},
+
%{btn_a: {23, 37}, btn_b: {35, 14}, prize: {16537, 6184}},
+
%{btn_a: {21, 89}, btn_b: {74, 23}, prize: {2407, 8748}},
+
%{btn_a: {47, 17}, btn_b: {35, 59}, prize: {17994, 16242}},
+
%{btn_a: {14, 45}, btn_b: {52, 16}, prize: {18768, 3912}},
+
%{btn_a: {29, 45}, btn_b: {85, 11}, prize: {3149, 4161}},
+
%{btn_a: {81, 95}, btn_b: {67, 12}, prize: {5489, 2110}},
+
%{btn_a: {48, 58}, btn_b: {86, 22}, prize: {4802, 2280}},
+
%{btn_a: {27, 59}, btn_b: {47, 15}, prize: {2602, 2090}},
+
%{btn_a: {39, 87}, btn_b: {94, 38}, prize: {8830, 6134}},
+
%{btn_a: {23, 61}, btn_b: {82, 16}, prize: {8405, 3957}},
+
%{btn_a: {54, 14}, btn_b: {24, 63}, prize: {894, 1708}},
+
%{btn_a: {26, 14}, btn_b: {18, 35}, prize: {5510, 12541}},
+
%{btn_a: {65, 55}, btn_b: {21, 69}, prize: {430, 620}},
+
%{btn_a: {11, 62}, btn_b: {50, 11}, prize: {11414, 3683}},
+
%{btn_a: {21, 54}, btn_b: {93, 22}, prize: {7683, 5642}},
+
%{btn_a: {20, 95}, btn_b: {52, 29}, prize: {5580, 10155}},
+
%{btn_a: {37, 13}, btn_b: {11, 66}, prize: {18250, 14983}},
+
%{btn_a: {54, 28}, btn_b: {37, 58}, prize: {17939, 14902}},
+
%{btn_a: {87, 65}, btn_b: {11, 79}, prize: {3765, 4087}},
+
%{btn_a: {74, 30}, btn_b: {16, 59}, prize: {9858, 8342}},
+
%{btn_a: {74, 31}, btn_b: {17, 59}, prize: {14764, 6598}},
+
%{btn_a: {12, 95}, btn_b: {27, 33}, prize: {945, 3324}},
+
%{btn_a: {21, 36}, btn_b: {34, 14}, prize: {7247, 5012}},
+
%{btn_a: {48, 62}, btn_b: {90, 29}, prize: {9150, 5973}},
+
%{btn_a: {93, 43}, btn_b: {49, 91}, prize: {7090, 6422}},
+
%{btn_a: {28, 70}, btn_b: {68, 21}, prize: {17176, 3693}},
+
%{btn_a: {33, 16}, btn_b: {27, 51}, prize: {1884, 2771}},
+
%{btn_a: {11, 43}, btn_b: {51, 19}, prize: {4114, 10066}},
+
%{btn_a: {26, 70}, btn_b: {87, 46}, prize: {3532, 6874}},
+
%{btn_a: {22, 35}, btn_b: {38, 13}, prize: {7508, 16592}},
+
%{btn_a: {33, 16}, btn_b: {48, 72}, prize: {12065, 15896}},
+
%{btn_a: {67, 25}, btn_b: {14, 55}, prize: {4093, 10275}},
+
%{btn_a: {36, 17}, btn_b: {43, 77}, prize: {3253, 1933}},
+
%{btn_a: {84, 24}, btn_b: {42, 69}, prize: {8862, 4869}},
+
%{btn_a: {70, 16}, btn_b: {17, 68}, prize: {5690, 3224}},
+
%{btn_a: {58, 27}, btn_b: {44, 92}, prize: {1890, 1595}},
+
%{btn_a: {64, 30}, btn_b: {29, 57}, prize: {15004, 15224}},
+
%{btn_a: {13, 90}, btn_b: {64, 33}, prize: {6560, 6048}},
+
%{btn_a: {37, 91}, btn_b: {64, 49}, prize: {5214, ...}},
+
%{btn_a: {12, 80}, btn_b: {75, ...}, prize: {...}},
+
%{btn_a: {27, ...}, btn_b: {...}, ...},
+
%{btn_a: {...}, ...},
+
%{...},
+
...
+
]
+
```
+
+
Yay, matrices again. We need to solve linear equations in form of:
+
+
$$
+
\begin{cases}
+
a_x x & + & b_x y & = & p_x \\
+
a_y x & + & b_x y & = & p_y
+
\end{cases}
+
$$
+
+
So we need to solve:
+
+
$$
+
\begin{bmatrix}
+
a_x & b_x \\
+
a_y & b_y
+
\end{bmatrix}
+
\begin{bmatrix}
+
x \\
+
y
+
\end{bmatrix}
+
= \begin{bmatrix}
+
p_x \\
+
p_y
+
\end{bmatrix}
+
$$
+
+
For each game. So we can use [Cramer's Rule](https://en.wikipedia.org/wiki/Cramer%27s_rule).
+
+
$$
+
\begin{gather*}
+
x = \frac{\text{det}(A_x)}{\text{det}(A)} \\
+
y = \frac{\text{det}(A_y)}{\text{det}(A)}
+
\end{gather*}
+
$$
+
+
Assuming that $\text{det}(A) \ne 0$ (otherwise there will be no solution). In case of $2\times2$ matrices determinant is simple to compute:
+
+
$$
+
\text{det}
+
\begin{vmatrix}
+
a & b \\
+
c & d
+
\end{vmatrix}
+
= ad - bc
+
$$
+
+
So in the end we need to compute:
+
+
$$
+
\begin{gather*}
+
x = \frac{p_x b_y - b_x p_y}{a_x b_y - b_x a_y} \\
+
y = \frac{a_x p_y - p_x a_y}{a_x b_y - b_x a_y}
+
\end{gather*}
+
$$
+
+
And reject cases where $x$ or $y$ is non-integer value.
+
+
```elixir
+
defmodule Game do
+
def solve(%{btn_a: {ax, ay}, btn_b: {bx, by}, prize: {px, py}}) do
+
det_a = ax * by - bx * ay
+
det_x = px * by - bx * py
+
det_y = ax * py - px * ay
+
+
if rem(det_x, det_a) == 0 do
+
{div(det_x, det_a), div(det_y, det_a)}
+
end
+
end
+
end
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:module, Game, <<70, 79, 82, 49, 0, 0, 8, ...>>, {:solve, 1}}
+
```
+
+
## Part 1
+
+
```elixir
+
games
+
|> Enum.map(&Game.solve/1)
+
|> Enum.map(fn
+
nil -> 0
+
{a, b} -> a * 3 + b * 1
+
end)
+
|> Enum.sum()
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
31897
+
```
+
+
## Part 2
+
+
```elixir
+
games
+
|> Enum.map(fn %{prize: {px, py}} = game ->
+
add = 10_000_000_000_000
+
%{game | prize: {px + add, py + add}}
+
end)
+
|> Enum.map(&Game.solve/1)
+
|> Enum.map(fn
+
nil -> 0
+
{a, b} -> a * 3 + b * 1
+
end)
+
|> Enum.sum()
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
87596249540359
+
```
+
+
<!-- livebook:{"offset":11449,"stamp":{"token":"XCP.AhVykQ8wyKxhTI29dXZZ0BnWEqWCuVGz8E2TRFpScgbUfqJJtY47yrvU9g9OzcejZVc8LbU3ak4YrgSGy5A5XeARPC3qt5fGPV4K9PYS3YabI7-q8rCKi8R6ZpGBpmZeDNQ","version":2}} -->
+219
2024/day14.livemd
···
+
<!-- livebook:{"persist_outputs":true} -->
+
+
# Day 14
+
+
```elixir
+
Mix.install([:kino_aoc, :image])
+
```
+
+
## Section
+
+
<!-- livebook:{"attrs":"eyJhc3NpZ25fdG8iOiJwdXp6bGVfaW5wdXQiLCJkYXkiOiIxNCIsInNlc3Npb25fc2VjcmV0IjoiQURWRU5UX09GX0NPREVfU0VTU0lPTiIsInllYXIiOiIyMDI0In0","chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2024", "14", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:ok,
+
"p=49,14 v=-82,-41\np=27,80 v=67,31\np=76,93 v=-15,-66\np=90,62 v=-84,86\np=62,86 v=46,20\np=7,72 v=25,26\np=30,32 v=-92,60\np=91,40 v=6,1\np=50,58 v=57,-21\np=71,79 v=-3,58\np=84,44 v=36,-59\np=87,12 v=-62,-95\np=69,46 v=76,39\np=50,51 v=-26,-64\np=41,58 v=30,5\np=80,97 v=-13,9\np=52,84 v=98,-50\np=52,32 v=64,39\np=52,91 v=61,20\np=31,22 v=49,45\np=85,73 v=-43,32\np=77,15 v=20,-52\np=17,10 v=74,-3\np=88,92 v=-54,26\np=20,46 v=31,-63\np=42,49 v=-26,44\np=3,101 v=40,-95\np=78,77 v=-17,48\np=10,88 v=-88,55\np=100,68 v=74,76\np=42,11 v=-97,-25\np=88,57 v=-37,93\np=11,36 v=-33,54\np=88,61 v=-58,43\np=66,47 v=-55,82\np=11,52 v=52,-60\np=9,48 v=41,-64\np=70,57 v=61,27\np=22,80 v=11,11\np=73,11 v=65,56\np=79,84 v=-28,41\np=50,79 v=-93,-12\np=55,35 v=23,-64\np=48,26 v=45,29\np=38,23 v=-86,-54\np=71,48 v=-21,6\np=60,98 v=28,-54\np=75,70 v=59,7\np=24,71 v=-20,-46\np=55,88 v=79,-23\np=13,48 v=44,49\np=37,73 v=-86,-99\np=82,12 v=-26,80\np=13,16 v=-8,30\np=86,34 v=84,99\np=45,90 v=-31,68\np=23,93 v=44,8\np=3,52 v=-65,-54\np=64,7 v=16,-30\np=97,88 v=-67,-39\np=58,87 v=72,42\np=8,70 v=-27,5\np=25,67 v=99,22\np=48,92 v=19,31\np=23,46 v=-16,-76\np=13,101 v=70,13\np=55,4 v=-25,-39\np=44,10 v=10,-59\np=56,2 v=83,67\np=90,83 v=28,42\np=28,84 v=7,-12\np=49,87 v=-7,-50\np=11,56 v=-76,87\np=27,72 v=46,-28\np=76,43 v=-59,32\np=19,50 v=80,62\np=12,1 v=44,-84\np=53,29 v=83,61\np=57,12 v=-63,-90\np=67,39 v=38,71\np=38,78 v=86,26\np=14,19 v=-72,-85\np=75,9 v=42,-43\np=89,33 v=65,-43\np=77,21 v=-64,54\np=32,72 v=-45,-71\np=9,21 v=55,-4\np=22,49 v=70,-71\np=86,73 v=-35,-7\np=32,5 v=-41,-62\np=14,51 v=89,-92\np=71,34 v=24,-69\np=87,18 v=69,-10\np=58,67 v=4,-28\np=22,75 v=15,26\np=73,14 v=-77,24\np=2,26 v=-12,91\np=53,3 v=38,-57\np=49,35 v=-37,-59\np=25,87 v=52,-83\np=47,74 v=46,-22\np=70,22 v=-81,24\np=46,57 v=23,-76\np=59,96 v=27,-40\np=72,77 v=99,28\np=66,89 v=61,-67\np=46,43 v=70,-23\np=30,55 v=-67,48\np=8,75 v=89,-17\np=15,29 v=-86,-3\np=53,2 v=38,-56\np=6,90 v=55,-83\np=44,83 v=8,-50\np=2,56 v=-54,-43\np=30,13 v=19,-62\np=21,97 v=-78,-46\np=13,53 v=70,22\np=2,5 v=59,56\np=2,48 v=18,50\np=81,94 v=92,57\np=1,1 v=6,-59\np=99,61 v=-65,-76\np=99,95 v=-24,35\np=17,53 v=-84,19\np=33,77 v=-4,53\np=100,32 v=-3,-43\np=60,74 v=-10,97\np=23,54 v=-57,-75\np=56,69 v=27,21\np=58,100 v=-51,44\np=43,77 v=-41,-93\np=75,3 v=80,13\np=66,32 v=72,34\np=67,67 v=-32,69\np=80,80 v=-23,-3\np=62,23 v=-4,48\np=77,0 v=87,30\np=2,96 v=-35,-73\np=15,4 v=4,-38\np=92,56 v=-54,-16\np=90,46 v=26,-16\np=75,2 v=1,67\np=59,71 v=-59,-33\np=79,21 v=-62,24\np=34,99 v=45,14\np=49,18 v=-37,-76\np=63,26 v=79,-41\np=97,54 v=-80,71\np=66,18 v=69,-30\np=14,25 v=74,-90\np=9,95 v=-87,96\np=24,39 v=-8,83\np=32,98 v=-75,79\np=36,50 v=-23,-92\np=97,36 v=-73,86\np=66,36 v=23,-53\np=84,3 v=2,95\np=89,73 v=48,26\np=3,94 v=-46,68\np=61,75 v=-52,-98\np=51,36 v=8,50\np=70,48 v=80,-2\np=32,39 v=-54,4\np=73,85 v=-92,-72\np=22,70 v=-12,38\np=92,48 v=-92,93\np=100,79 v=-76,-12\np=1,52 v=-43,65\np=22,98 v=78,52\np=35,76 v=-97,48\np=52,14 v=-48,-74\np=7,55 v=29,98\np=79,40 v=-2,-38\np=90,91 v=57,-72\np=60,3 v=-14,-94\np=34,69 v=-56,32\np=63,19 v=-44,24\np=48,71 v=-18,-98\np=90,42 v=-87,9\np=73,59 v=27,-28\np=30,66 v=18,-48\np=9,54 v=-79,-43\np=57,73 v=-73,-34\np=75,93 v=-39,60\np=31,75 v=-98,86\np=93,86 v=-95,-45\np=64,33 v=33,4\np=62,27 v=12,46\np=76,93 v=91,58\np=92,23 v=-13,29\np=54,93 v=69,51\np=19,53 v=59,-16\np=78,90 v=84,-7\np=17,93 v=33,25\np=100,73 v=5,59\np=74,39 v=80,28\np=88,4 v=84,19\np=63,98 v=-65,-2\np=81,98 v=32,4\np=64,89 v=-7,9\np=88,3 v=-35,9\np=77,14 v=-62,-79\np=15,15 v=18,-41\np=40,4 v=41,-24\np=14,68 v=89,-98\np=77,71 v=-14,97\np=69,28 v=1,-9\np=16,102 v=-87,52\np=26,20 v=-62,15\np=100,25 v=28,-37\np=22,63 v=93,-5\np=9,47 v=77,-47\np=78,36 v=76,-95\np=41,84 v=52,63\np=14,6 v=30,-88\np=99,72 v=59,42\np=72,45 v=7,-21\np=99,71 v=-20,-98\np=30,40 v=-6,82\np=75,50 v=-99,97\np=91,80 v=8,44\np=7,44 v=52,-91\np=96,12 v=-50,-74\np=72,48 v=-88,-33\np=21,7 v=-29,-3\np=96,38 v=2,-48\np=33,22 v=86,-36\np=79,84 v=-36,-77\np=87,65 v=2,48\np=46,42 v=98,-11\np=60,79 v=80,-27\np=95,3 v=-2,-94\np=94,75 v=88,-29\np=16,66 v=-24,48\np=83,51 v=-24,-64\np=54,94 v=-10,-7\np=0,96 v=-8,-96\np=4,50 v=-31,71\np=21,98 v=-66,-4\np=50,85 v=-48,69\np=71,14 v=5,67\np=19,56 v=71,6\np=18,43 v=-16,-49\np=11,25 v=18,45\np=38,90 v=-52,-34\np=50,9 v=-89,73\np=15,23 v=" <> ...}
+
```
+
+
```elixir
+
robots =
+
puzzle_input
+
|> String.split("\n", trim: true)
+
|> Enum.map(fn row ->
+
["p=" <> pos, "v=" <> v] = String.split(row, " ")
+
+
pos = pos |> String.split(",") |> Enum.map(&String.to_integer/1) |> List.to_tuple()
+
v = v |> String.split(",") |> Enum.map(&String.to_integer/1) |> List.to_tuple()
+
+
%{pos: pos, v: v}
+
end)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
[
+
%{pos: {49, 14}, v: {-82, -41}},
+
%{pos: {27, 80}, v: {67, 31}},
+
%{pos: {76, 93}, v: {-15, -66}},
+
%{pos: {90, 62}, v: {-84, 86}},
+
%{pos: {62, 86}, v: {46, 20}},
+
%{pos: {7, 72}, v: {25, 26}},
+
%{pos: {30, 32}, v: {-92, 60}},
+
%{pos: {91, 40}, v: {6, 1}},
+
%{pos: {50, 58}, v: {57, -21}},
+
%{pos: {71, 79}, v: {-3, 58}},
+
%{pos: {84, 44}, v: {36, -59}},
+
%{pos: {87, 12}, v: {-62, -95}},
+
%{pos: {69, 46}, v: {76, 39}},
+
%{pos: {50, 51}, v: {-26, -64}},
+
%{pos: {41, 58}, v: {30, 5}},
+
%{pos: {80, 97}, v: {-13, 9}},
+
%{pos: {52, 84}, v: {98, -50}},
+
%{pos: {52, 32}, v: {64, 39}},
+
%{pos: {52, 91}, v: {61, 20}},
+
%{pos: {31, 22}, v: {49, 45}},
+
%{pos: {85, 73}, v: {-43, 32}},
+
%{pos: {77, 15}, v: {20, -52}},
+
%{pos: {17, 10}, v: {74, -3}},
+
%{pos: {88, 92}, v: {-54, 26}},
+
%{pos: {20, 46}, v: {31, -63}},
+
%{pos: {42, 49}, v: {-26, 44}},
+
%{pos: {3, 101}, v: {40, -95}},
+
%{pos: {78, 77}, v: {-17, 48}},
+
%{pos: {10, 88}, v: {-88, 55}},
+
%{pos: {100, 68}, v: {74, 76}},
+
%{pos: {42, 11}, v: {-97, -25}},
+
%{pos: {88, 57}, v: {-37, 93}},
+
%{pos: {11, 36}, v: {-33, 54}},
+
%{pos: {88, 61}, v: {-58, 43}},
+
%{pos: {66, 47}, v: {-55, 82}},
+
%{pos: {11, 52}, v: {52, -60}},
+
%{pos: {9, 48}, v: {41, -64}},
+
%{pos: {70, 57}, v: {61, 27}},
+
%{pos: {22, 80}, v: {11, 11}},
+
%{pos: {73, 11}, v: {65, 56}},
+
%{pos: {79, 84}, v: {-28, 41}},
+
%{pos: {50, 79}, v: {-93, -12}},
+
%{pos: {55, 35}, v: {23, -64}},
+
%{pos: {48, 26}, v: {45, 29}},
+
%{pos: {38, 23}, v: {-86, -54}},
+
%{pos: {71, 48}, v: {-21, 6}},
+
%{pos: {60, 98}, v: {28, ...}},
+
%{pos: {75, ...}, v: {...}},
+
%{pos: {...}, ...},
+
%{...},
+
...
+
]
+
```
+
+
```elixir
+
room = {w, h} = {101, 103}
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{101, 103}
+
```
+
+
```elixir
+
defmodule Robot do
+
def walk(robots, room, n \\ 1), do: Enum.map(robots, &move(&1, room, n))
+
+
def move(%{pos: {x, y}, v: {vx, vy}}, {w, h}, by \\ 1) do
+
x = Integer.mod(x + vx * by, w)
+
y = Integer.mod(y + vy * by, h)
+
+
%{pos: {x, y}, v: {vx, vy}}
+
end
+
+
def quad(%{pos: {x, y}}, {w, h}) do
+
hw = div(w - 1, 2)
+
hh = div(h - 1, 2)
+
+
if x == hw or y == hh do
+
:middle
+
else
+
{sign(x - hw), sign(y - hh)}
+
end
+
end
+
+
defp sign(0), do: 0
+
defp sign(n) when n < 0, do: -1
+
defp sign(n) when n > 0, do: 1
+
+
def with_neighbours(robots) do
+
set = MapSet.new(robots, & &1.pos)
+
+
with_neighbours =
+
Enum.count(robots, fn %{pos: {x, y}} ->
+
[{x + 1, y}, {x - 1, y}, {x, y - 1}, {x, y + 1}] |> Enum.any?(&(&1 in set))
+
end)
+
+
div(with_neighbours * 100, length(robots))
+
end
+
end
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:module, Robot, <<70, 79, 82, 49, 0, 0, 18, ...>>, {:with_neighbours, 1}}
+
```
+
+
## Part 1
+
+
```elixir
+
robots
+
|> Robot.walk(room, 100)
+
|> Enum.group_by(fn robot -> Robot.quad(robot, room) end)
+
|> Map.new(fn {k, l} -> {k, length(l)} end)
+
|> Map.drop([:middle])
+
|> Map.values()
+
|> Enum.product()
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
219150360
+
```
+
+
## Part 2
+
+
Hack that I have found over the internet - if more than 60% of the robots have neighbours, you have found solution.
+
+
Othe hack that I have found - checking whether there are no robots that are occupying the same position - didn't work for me.
+
+
```elixir
+
{tree, steps} =
+
Stream.from_index()
+
|> Task.async_stream(
+
fn step ->
+
robots = Robot.walk(robots, room, step)
+
+
if Robot.with_neighbours(robots) >= 60, do: {robots, step}
+
end,
+
ordered: false
+
)
+
|> Enum.find_value(fn {:ok, val} -> val end)
+
+
steps
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
8053
+
```
+
+
```elixir
+
Image.new!(w, h)
+
|> Image.mutate(fn img ->
+
for %{pos: {x, y}} <- tree do
+
# Add some festivity
+
color =
+
if abs(:math.sin(x + y)) < 0.5 do
+
:red
+
else
+
:green
+
end
+
+
Image.Draw.point(img, x, y, color: color)
+
end
+
+
{:ok, img}
+
end)
+
|> elem(1)
+
|> Image.resize!(4, interpolate: :nearest)
+
```
+
+
<!-- livebook:{"offset":9213,"stamp":{"token":"XCP.bbViODF6Z4_TcNSzpaXWzuFflurdyZ5JsvKHJZr6NjgJ4MQaH2OorTxA-YR5uDBN5HxiB0uC5hX0vi-Kgdm26HMcOubYpE_c39bjuPfPH_BH4SVxLeEac5c8aaRtPdt7CJk","version":2}} -->
+395
2024/day15.livemd
···
+
<!-- livebook:{"persist_outputs":true} -->
+
+
# Day 15
+
+
```elixir
+
Mix.install([:kino_aoc])
+
```
+
+
## Section
+
+
<!-- livebook:{"attrs":"eyJhc3NpZ25fdG8iOiJwdXp6bGVfaW5wdXQiLCJkYXkiOiIxNSIsInNlc3Npb25fc2VjcmV0IjoiQURWRU5UX09GX0NPREVfU0VTU0lPTiIsInllYXIiOiIyMDI0In0","chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2024", "15", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:ok,
+
"##################################################\n##...O...#OO...O.#....#....#O#O..O..O......O..O..#\n#OOOO.#.O.O.....OO#...O.OO.O....O.#..OO....O#OOO.#\n#...#.#O..O...OO......O.......#....O..O#.O..OO...#\n#.O.....O..#.........O......OO..O..OO.OO....O.O..#\n#.....O.OO.O.#.O...O..#.OOOO..#...#.O.OO.O.#.#OO##\n#...OO.#..O.O.#.O..OO..O....O...OO.OOO.......O...#\n##.O.....O..#O...........O..O.....O.......OO.....#\n#...O..O....O...O...O...O..O..O...O......O..OO...#\n#.O##.O.OO.....O.O.#....O#.....OO.O.O.#..O....#O.#\n#.............#.O........OOO.OO..#.............O.#\n#OOO..O.O.........OO....O.#......#.OO.......O..O.#\n#.......#...O..#O.OO...O..#O.O...##O#O......O##..#\n#O#.O..#........O....O.....O...#O..#......O.O..O.#\n#O..O..O#...#.......OO.OO..O.....O..O..O.O.O...O.#\n#...O.O...OO.......#O#O...O.##.....#..O.O.....O..#\n#.#OOOO..OO..O....O.O....OO.#.OO..O.......O....#.#\n#..O...#.....#.....OO..#O....O#.O....O..OOO.O...O#\n#.O.......OO.O.#........OO...O..O#..O.#..##...#.O#\n#.O..#..........OO.O.O..O..O.......O...O.O.OO....#\n#.O..##..........OO..O..O.....#OO#...#..O....O...#\n#O.OOOO.O..O........O#.#OO.OO...OO.#OO..OO#O.....#\n#..OO..........O...O....O.O.....O.....O...#..O..O#\n#.#O..O..O.....#.O...#........O.O.O..O.......#.O.#\n#..##..O.....O......O..O@........O....O#.O..OO..O#\n#...O..##O.#....#.......O..OO#..O.O.....##O....O.#\n#....O.O...O.OOO.O.O#..O..OOOOOOOOOO#.....O...#.O#\n#O.....#O..O..#..O....O.O..OOOO.#.O.O#....#.O.O#.#\n#..O.O..#O..............O....###..O#.O.....O.#O#O#\n#O...O.O.#.#..O......OO.OO#..O...O.O....O#.O...OO#\n#..OO.O#.....O##.O##....O..#..#..#O..O.....#....O#\n#....#..O..O....O.OO...O.......OO.OO...O.O.....O.#\n#....O.O.#O.#OO.......O......O........OOO..O.....#\n#..#...##.O......##.....O..O.O#.O...O....O..#.O..#\n#...O.O..O....O..O.OOOOOO...#.O...OO.#.....OO.O..#\n#O.......O....#.OO.OO...OO...##O......O.O........#\n##.O.OO.OO...O..O#......O.O....#.............O.#.#\n#O#O...O..O..OO.O.O...OO..O.O..OOOO..O..O...O..O.#\n#..OO.O#O..O..#.O..O.#...#..O.....OO..OOO..O...O.#\n#.O.O..OO.....O...O.....O..#..O..#.O.#.OOO...O.O.#\n#.O..O.......O...OO#.#..O....O...O....O..........#\n#....O..O.OO...OO..#....#O.OO.OO##.....O.........#\n#..O..O....O...O....OO#.#O..O.#.#O.O..O...#....O.#\n#.O.....O.#.O#.O..O.OO.O#............O..........O#\n#..O#O.O.........O.#.O#O..#O.O.........O....O..O.#\n#..O.....#OO..O..#.#.#....O.O.OO.O.O......O#.#O..#\n#.O.O..O.O.O.O...O..O..OO..................#OO...#\n#..O....O....O.....OOO...OO..OO.......O....OO....#\n#.O....OO.O................OO....O.O#O.O.........#\n##################################################\n\n>v>>>^>>v>vv^v^^v^^^<v^vv^vv<<>^v^^^<<<vv<>vv^^>v>v^^><>^<v<v><>>^>^<^^v>v<>^^v<><<^><v>v^v<<^>^>^>^>>vvv>^<<^^^^^><vv>>^>^^>^vv>><v^^v^<<<>^^<<<^^^vv^<^<<<>v<^v<v>^<>v<^>>^v^<>><><<^<>v>^>^>v>>v>vv^><v<v^v>vv>><^^<<>>vv<<^vv>^^vv>>><^v^>>v<<<<v>^<><>^>v^vv>v>><><^vvv>^><<>^<<<vvv^>^vv<<>v^^^>v<>^^vv>vv^<>^<>vvv<vvvv^^^<^vv^<v^<<vv^v<><vvvv^>vv<>><><<v>><^>v<>v<v<v>^v>^<>^v>>><^>>v<<<v^>^v>v>^^>^v<v^v^^<vv^v^><<^^<v^v>>^v>>>>>v<v^>^>^v^>vv^v^><^<v>^^<>^v^>><>>><vv<<>^v<^vvv<v^vvv^>v<<v>>^>><<^v^^v>^^>^<<<>v^^>><<v>^<v^<^>v>>>^^^<<vvv^>vvv>^><v>^>vvv^^^v^^>v^><v>><>^<v<<vv^^>>^^v>><vv>vvv>^>>>vv^><^<v<<<^^v>v^<v^^>^^<<<>v^vv<vvv>^v>v<^^>vv>v<>>vv<><v>v<^^<<^>>v<v^<>^<<v>><<vv^<<<<v^^^v^^<^<^<>v><^<>>v>v>v>v>v><v>>v<<^>>><v^v<v>>v^><^v^>>>^>^<<>>^^v><^<v^vv^<><>>v^^>v<vvv>v<>><<<<<>><<><v<>vv><^^^><vv<v<<>v^>v>>^^v^v^>vvv<v^<>><<<^>vvv><^^v>v<>v><^<v>v<^<<^<>v>>>>^<>^^^>v<v<<vv><v>>>^<^>v^><vv>^<<v<>><<^<>>>^v>><<>v^^v<^>v^v^>vvvv>vv<<>^^^<v>^<<v>>><<>>>vv^<^><><^^^>^v^<><>^<vv<^vv^^v>^<\n<^>vv>v>^^>^vvvv<<^><^<>>^<v>v>>^^<v><^<>><<<>^vv<>v<v^>>>^<<^<><<>^^vv^^<<><<vvv>v^^>vv^<v<<>>v><^>v^>>^^v<<<<^v<v<<>>v><v^>vv^<vv^>^v>^^>>><>v<><^v><vvvv^v<<>>^^v><>>vv^>v>v^>^>v<><^v>v^^<<>^v^>^>v<><^v<^^vv<>^^^v^>>><<><<<<v^v^><v<v<^^^><><^<<^^^vv<^^<^<v>v<<v^>>v<>>^<vv<^<v><>^<^v^>^v>>>^v>>v^>^^v^>><<v>>^<v>^vvv<v<<<v>^<>vv<^<v<>^<>v^v^>vv^v>><^>><>^^^<<v<vv^<vv>>v<^^^>vv<^^>vv^^^^<<^<v^>v<v>vvv<v<<^^><v<<^>^^<>v>>v><^v^<v>vv^<v<<v>v>vvv^>v<vv>>>>>^^v<<>^><>v^^^>^^>^>^^vvvv^v<v>>^^^v>>^<v<^^v>>><<>^^><<<^>v^^^v><v<v<v^v^><>^>v<v<^^^>" <> ...}
+
```
+
+
```elixir
+
#puzzle_input =
+
"""
+
##########
+
#..O..O.O#
+
#......O.#
+
#.OO..O.O#
+
#..O@..O.#
+
#O#..O...#
+
#O..O..O.#
+
#.OO.O.OO#
+
#....O...#
+
##########
+
+
<vv>^<v^>v>^vv^v>v<>v^v<v<^vv<<<^><<><>>v<vvv<>^v^>^<<<><<v<<<v^vv^v>^
+
vvv<<^>^v^^><<>>><>^<<><^vv^^<>vvv<>><^^v>^>vv<>v<<<<v<^v>^<^^>>>^<v<v
+
><>vv>v^v^<>><>>>><^^>vv>v<^^^>>v^v^<^^>v^^>v^<^v>v<>>v^v^<v>v^^<^^vv<
+
<<v<^>>^^^^>>>v^<>vvv^><v<<<>^^^vv^<vvv>^>v<^^^^v<>^>vvvv><>>v^<<^^^^^
+
^><^><>>><>^^<<^^v>>><^<v>^<vv>>v>>>^v><>^v><<<<v>>v<v<v>vvv>^<><<>^><
+
^>><>^v<><^vvv<^^<><v<<<<<><^v<<<><<<^^<v<^^^><^>>^<v^><<<^>>^v<v^v<v^
+
>^>>^v>vv>^<<^v<>><<><<v<<v><>v<^vv<<<>^^v^>^^>>><<^v>>v^v><^^>>^<>vv^
+
<><^^>^^^<><vvvvv^v<v<<>^v<v>v<<^><<><<><<<^^<<<^<<>><<><^^^>^^<>^>v<>
+
^^>vv<^v^v<vv>^<><v<^v>^^^>>>^^vvv^>vvv<>>>^<^>>>>>^<<^v>^vvv<>^<><<v>
+
v^^>>><<^^<>>^v^<v^vv<>v^<<>^<^v^v><^<<<><<^<v><v<>vv>>v><v^<vv<>v^<<^
+
"""
+
+
#puzzle_input =
+
"""
+
########
+
#..O.O.#
+
##@.O..#
+
#...O..#
+
#.#.O..#
+
#...O..#
+
#......#
+
########
+
+
<^^>>>vv<v>>v<<
+
"""
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
warning: outdented heredoc line. The contents inside the heredoc should be indented at the same level as the closing """. The following is forbidden:
+
+
def text do
+
"""
+
contents
+
"""
+
end
+
+
Instead make sure the contents are indented as much as the heredoc closing:
+
+
def text do
+
"""
+
contents
+
"""
+
end
+
+
The current heredoc line is indented too little
+
โ””โ”€ Workspace/hauleth/advent-of-code/2024/day15.livemd#cell:7w6bq5lw7vctw7mk:3:3
+
+
warning: outdented heredoc line. The contents inside the heredoc should be indented at the same level as the closing """. The following is forbidden:
+
+
def text do
+
"""
+
contents
+
"""
+
end
+
+
Instead make sure the contents are indented as much as the heredoc closing:
+
+
def text do
+
"""
+
contents
+
"""
+
end
+
+
The current heredoc line is indented too little
+
โ””โ”€ Workspace/hauleth/advent-of-code/2024/day15.livemd#cell:7w6bq5lw7vctw7mk:28:3
+
+
warning: code block contains unused literal "##########\n#..O..O.O#\n#......O.#\n#.OO..O.O#\n#..O@..O.#\n#O#..O...#\n#O..O..O.#\n#.OO.O.OO#\n#....O...#\n##########\n\n<vv>^<v^>v>^vv^v>v<>v^v<v<^vv<<<^><<><>>v<vvv<>^v^>^<<<><<v<<<v^vv^v>^\nvvv<<^>^v^^><<>>><>^<<><^vv^^<>vvv<>><^^v>^>vv<>v<<<<v<^v>^<^^>>>^<v<v\n><>vv>v^v^<>><>>>><^^>vv>v<^^^>>v^v^<^^>v^^>v^<^v>v<>>v^v^<v>v^^<^^vv<\n<<v<^>>^^^^>>>v^<>vvv^><v<<<>^^^vv^<vvv>^>v<^^^^v<>^>vvvv><>>v^<<^^^^^\n^><^><>>><>^^<<^^v>>><^<v>^<vv>>v>>>^v><>^v><<<<v>>v<v<v>vvv>^<><<>^><\n^>><>^v<><^vvv<^^<><v<<<<<><^v<<<><<<^^<v<^^^><^>>^<v^><<<^>>^v<v^v<v^\n>^>>^v>vv>^<<^v<>><<><<v<<v><>v<^vv<<<>^^v^>^^>>><<^v>>v^v><^^>>^<>vv^\n<><^^>^^^<><vvvvv^v<v<<>^v<v>v<<^><<><<><<<^^<<<^<<>><<><^^^>^^<>^>v<>\n^^>vv<^v^v<vv>^<><v<^v>^^^>>>^^vvv^>vvv<>>>^<^>>>>>^<<^v>^vvv<>^<><<v>\nv^^>>><<^^<>>^v^<v^vv<>v^<<>^<^v^v><^<<<><<^<v><v<>vv>>v><v^<vv<>v^<<^\n" (remove the literal or assign it to _ to avoid warnings)
+
โ””โ”€ Workspace/hauleth/advent-of-code/2024/day15.livemd#cell:7w6bq5lw7vctw7mk:1
+
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
"########\n#..O.O.#\n##@.O..#\n#...O..#\n#.#.O..#\n#...O..#\n#......#\n########\n\n<^^>>>vv<v>>v<<\n"
+
```
+
+
```elixir
+
[map, moves] = String.split(puzzle_input, "\n\n")
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
["##################################################\n##...O...#OO...O.#....#....#O#O..O..O......O..O..#\n#OOOO.#.O.O.....OO#...O.OO.O....O.#..OO....O#OOO.#\n#...#.#O..O...OO......O.......#....O..O#.O..OO...#\n#.O.....O..#.........O......OO..O..OO.OO....O.O..#\n#.....O.OO.O.#.O...O..#.OOOO..#...#.O.OO.O.#.#OO##\n#...OO.#..O.O.#.O..OO..O....O...OO.OOO.......O...#\n##.O.....O..#O...........O..O.....O.......OO.....#\n#...O..O....O...O...O...O..O..O...O......O..OO...#\n#.O##.O.OO.....O.O.#....O#.....OO.O.O.#..O....#O.#\n#.............#.O........OOO.OO..#.............O.#\n#OOO..O.O.........OO....O.#......#.OO.......O..O.#\n#.......#...O..#O.OO...O..#O.O...##O#O......O##..#\n#O#.O..#........O....O.....O...#O..#......O.O..O.#\n#O..O..O#...#.......OO.OO..O.....O..O..O.O.O...O.#\n#...O.O...OO.......#O#O...O.##.....#..O.O.....O..#\n#.#OOOO..OO..O....O.O....OO.#.OO..O.......O....#.#\n#..O...#.....#.....OO..#O....O#.O....O..OOO.O...O#\n#.O.......OO.O.#........OO...O..O#..O.#..##...#.O#\n#.O..#..........OO.O.O..O..O.......O...O.O.OO....#\n#.O..##..........OO..O..O.....#OO#...#..O....O...#\n#O.OOOO.O..O........O#.#OO.OO...OO.#OO..OO#O.....#\n#..OO..........O...O....O.O.....O.....O...#..O..O#\n#.#O..O..O.....#.O...#........O.O.O..O.......#.O.#\n#..##..O.....O......O..O@........O....O#.O..OO..O#\n#...O..##O.#....#.......O..OO#..O.O.....##O....O.#\n#....O.O...O.OOO.O.O#..O..OOOOOOOOOO#.....O...#.O#\n#O.....#O..O..#..O....O.O..OOOO.#.O.O#....#.O.O#.#\n#..O.O..#O..............O....###..O#.O.....O.#O#O#\n#O...O.O.#.#..O......OO.OO#..O...O.O....O#.O...OO#\n#..OO.O#.....O##.O##....O..#..#..#O..O.....#....O#\n#....#..O..O....O.OO...O.......OO.OO...O.O.....O.#\n#....O.O.#O.#OO.......O......O........OOO..O.....#\n#..#...##.O......##.....O..O.O#.O...O....O..#.O..#\n#...O.O..O....O..O.OOOOOO...#.O...OO.#.....OO.O..#\n#O.......O....#.OO.OO...OO...##O......O.O........#\n##.O.OO.OO...O..O#......O.O....#.............O.#.#\n#O#O...O..O..OO.O.O...OO..O.O..OOOO..O..O...O..O.#\n#..OO.O#O..O..#.O..O.#...#..O.....OO..OOO..O...O.#\n#.O.O..OO.....O...O.....O..#..O..#.O.#.OOO...O.O.#\n#.O..O.......O...OO#.#..O....O...O....O..........#\n#....O..O.OO...OO..#....#O.OO.OO##.....O.........#\n#..O..O....O...O....OO#.#O..O.#.#O.O..O...#....O.#\n#.O.....O.#.O#.O..O.OO.O#............O..........O#\n#..O#O.O.........O.#.O#O..#O.O.........O....O..O.#\n#..O.....#OO..O..#.#.#....O.O.OO.O.O......O#.#O..#\n#.O.O..O.O.O.O...O..O..OO..................#OO...#\n#..O....O....O.....OOO...OO..OO.......O....OO....#\n#.O....OO.O................OO....O.O#O.O.........#\n##################################################",
+
">v>>>^>>v>vv^v^^v^^^<v^vv^vv<<>^v^^^<<<vv<>vv^^>v>v^^><>^<v<v><>>^>^<^^v>v<>^^v<><<^><v>v^v<<^>^>^>^>>vvv>^<<^^^^^><vv>>^>^^>^vv>><v^^v^<<<>^^<<<^^^vv^<^<<<>v<^v<v>^<>v<^>>^v^<>><><<^<>v>^>^>v>>v>vv^><v<v^v>vv>><^^<<>>vv<<^vv>^^vv>>><^v^>>v<<<<v>^<><>^>v^vv>v>><><^vvv>^><<>^<<<vvv^>^vv<<>v^^^>v<>^^vv>vv^<>^<>vvv<vvvv^^^<^vv^<v^<<vv^v<><vvvv^>vv<>><><<v>><^>v<>v<v<v>^v>^<>^v>>><^>>v<<<v^>^v>v>^^>^v<v^v^^<vv^v^><<^^<v^v>>^v>>>>>v<v^>^>^v^>vv^v^><^<v>^^<>^v^>><>>><vv<<>^v<^vvv<v^vvv^>v<<v>>^>><<^v^^v>^^>^<<<>v^^>><<v>^<v^<^>v>>>^^^<<vvv^>vvv>^><v>^>vvv^^^v^^>v^><v>><>^<v<<vv^^>>^^v>><vv>vvv>^>>>vv^><^<v<<<^^v>v^<v^^>^^<<<>v^vv<vvv>^v>v<^^>vv>v<>>vv<><v>v<^^<<^>>v<v^<>^<<v>><<vv^<<<<v^^^v^^<^<^<>v><^<>>v>v>v>v>v><v>>v<<^>>><v^v<v>>v^><^v^>>>^>^<<>>^^v><^<v^vv^<><>>v^^>v<vvv>v<>><<<<<>><<><v<>vv><^^^><vv<v<<>v^>v>>^^v^v^>vvv<v^<>><<<^>vvv><^^v>v<>v><^<v>v<^<<^<>v>>>>^<>^^^>v<v<<vv><v>>>^<^>v^><vv>^<<v<>><<^<>>>^v>><<>v^^v<^>v^v^>vvvv>vv<<>^^^<v>^<<v>>><<>>>vv^<^><><^^^>^v^<><>^<vv<^vv^^v>^<\n<^>vv>v>^^>^vvvv<<^><^<>>^<v>v>>^^<v><^<>><<<>^vv<>v<v^>>>^<<^<><<>^^vv^^<<><<vvv>v^^>vv^<v<<>>v><^>v^>>^^v<<<<^v<v<<>>v><v^>vv^<vv^>^v>^^>>><>v<><^v><vvvv^v<<>>^^v><>>vv^>v>v^>^>v<><^v>v^^<<>^v^>^>v<><^v<^^vv<>^^^v^>>><<><<<<v^v^><v<v<^^^><><^<<^^^vv<^^<^<v>v<<v^>>v<>>^<vv<^<v><>^<^v^>^v>>>^v>>v^>^^v^>><<v>>^<v>^vvv<v<<<v>^<>vv<^<v<>^<>v^v^>vv^v>><^>><>^^^<<v<vv^<vv>>v<^^^>vv<^^>vv^^^^<<^<v^>v<v>vvv<v<<^^><v<<^>^^<>v>>v><^v^<v>vv^<v<<v>v>vvv^>v<vv>>>>>^^v<<>^><>v^^^>^^>^>^^vvvv^v<v>>^^^v>>^<v<^^v>>><<>^^><<<^>v^^^v><v<v<v^v^><>^>v<v<^^^>>>vv><<^>><v>><<v<<vv><^^^<<^<>v>^v^v><<<<<<>>vv^<<<><<><><<^<^>^<v<^v>>>^>v^>^v>^v^<^>^v>><<<v>v^^vvv><<^>v^^<><v^>><<v><^^>>v<<<<<^>>><><vv>v<<>>^v<><<^>>v<<<^<^>>^>v^>^v<v>^v>>v<^>><<>><>vvv<<>vv^>v>><><<^><vvv>v><^>^<^v><>>v><v><^v^vv><>^^>>>v<^v^<^v>^v><vv<<v<<v><>>><v<vv<>>v^^>>>vv><v<<<<><v^^>>v>^<v^^>^v<<<><v>v>>^^<vv<v^v>><^<^^<>><v>^<^^<><^^^><>^<v^^^<v<^>>^v>vv^^<^v>><<vv><<v>><v>>>^>>><<<v<<><^vvv^<v>^>vvv^v>>v><<>v><<v<vvvvv^>^>><v^>vv^>>^\nvvv^v^><<v<>><><><<<^v>^v^><>^vvv<<^<<v^v<>>v<v^^>>^>v<v>^v<v^v>^<<vvv<^^v<<<<>v^v<<<v<^>><v^vv^vvvv^v><><v<<^>v>v^v^<v<v<^<><^>^vv<^^v<^^>vv<<>^^<>><<<<^^>>>^<^^>vv<>>>^^^^vv^>^v^v^^>^<<<>v^<v>^^^>v<^^<<^<v><^vvv>v>v>v<^>><^<^<>>>^^<<<vv^>>><>>v><>^<>^^<v^><<vv>vv^v<<>^>v><vvv>v^>>v^^^v<<>>^v><^<>^>^<^>^^<vv<>>><v^v^>>>^^>>^v^^^>>^v>v><^^^v<>>vv>>v^^<><^^v>v<^>>v<v^v^v^v^vv^vvv>v^vv>^v>vv<vv<^<<<v^v><<v>v<<^>vvv^^^^>>^>v>^^<>vv<>^^v><v<<^v><><><^<vv^>v^^>>>^^vv>^v>^<>vvv^v<^vv^<<^<^^<>>^<<><vv^>^>^^v^<v><v^>><^^>><<><<<<<<^>^><^v>^v>><v><v<>vvv>^^<^<<>v>>vv<v<><^<<^<>v<v>><><>^v><v<^^^<>>vvv>^^>>>v><v><^^>><<^<v><<^<v<<vv>>^vv<>v>^><><<<<<v>>>v^^v>^<>^<>v^^>>^<>>v^>^<>>>><>><v^v>>v>^<<^v^><<>>^v>><>><>>>><>vv<<>>^>v^v^<vvvvvvv^>v<<<^^<>vvvv^<<><<v^<<vv^^^v^^<<><v>v^^<^^v^^<>^v<>vvv>>^^v^^^<v>v^^vv<^^^<<>^v^>>^^<<^^v^^v<<vv^<<>>>v<>vv<v^v<<>vvv>^<v>v>^v<^^v<>^>^<><<v>v<>v^>v^v>><<><v><>>>>v^<^<^><>^v^<^><<v<^v><>>^v^^^v^><>^v>v<<^v>>^<<v<>v<^<<<<>>^><<<vv<^v^<^>^^><^^vvv^><v<><^^<>^v^>\nvvvv^vv^>>^v^v<^<vvv<>v>v>vv>^>^><^vv><v^v>v<><>v^v^>vvvv<<>v<^^^vv<^v><>^>^>v<>^>^vvv<>^>^<^^v^<><<>^>^v><v>^v>v^<v^<>>^^>^>v^>v>>^^<v><^<^vv>^vv^v^>v><^vv>^>v>^><>v>v^^>>v>^<<v^<vvv>>v<v>v^^<>^v^vv^<^^<v>>>v>>^v>vvv^^v^>v<vvv^<><v>v>v<>^^v^^<vv<>v<vvv>>><><<>>v>^^<^^^^><v>^>v<^<^>v^^>v>^>>^><<<^vv>vv^v^><v^<v>vv>^<>^vvvv^>vv>^>v^>v<<v^^<v^<v>>vvv<<v<>>>v^>^vv>^<v<>>^^v<vv<^>v<>^<<^^><>^^v>^v>>^<v>vv^v<<^^>^<v<><v>vv<><vv<>>v<^^^><<^^>^v<>vv<v>><<<v><<>>vv^>>^vvvv^><<v<vv^v<vv<>v<><v<<><v>vvv>>vv^^^<><^v<><v<^<v<v<^>>vv<><<>^^>><<v><^>vvv^>^vvv<>v^^<<^<vv>>v>^>v>^^><<>v<v^>^<<<<vv<<^^^>^>^>v<>>vv^><v<><<><^><><^^vv>>^<^vv<^^v<><<><>vvvv^^^<>v>>v^<vvv<v<vv><<v^v<v>>^v^<<^>>vvvv^v<<^<^vv<v<v>^v<^<^^>vv<v^^^>>^<^><^^v<v^v^>^^^v^v>^>^><^>>^v<v<^^^v^>>^v>vv>^v<>^v^^^v^v^>v>><^^<^v<<v<^v<>v^<>^<>^v<v^^v<^>v<v>^v<<><<<>^v><<<^>vvvvv^v^^^<<v>>v^>>^^<<v^^>vv^^vvvv>^>v^<<<^<>v><<^>^v^<^>><<<v<vv>vv<<^>^<^^><>>^^v>vvv^<^>^^^^<^v<<>^<>^>>v>^<><><>>^^vv^<<>><^<v><>^v^vvv<<>>^<>^>v<<^><<^>^<^>^<<><\n<<^<^>><<<vv>v<v<^<>>>v^>vv><>>vvvv<<^><<<>v<>v^v^<>v>v<^^<<v<vv^<<<vv>^<>^^vv<><v<<^v^v<^<v" <> ...]
+
```
+
+
```elixir
+
%{robot: [robot], wall: walls, box: boxes} =
+
map
+
|> String.split("\n", trim: true)
+
|> Enum.with_index()
+
|> Enum.flat_map(fn {row, y} ->
+
row
+
|> String.to_charlist()
+
|> Enum.with_index()
+
|> Enum.reject(fn {kind, _} -> kind == ?. end)
+
|> Enum.map(fn {kind, x} ->
+
kind =
+
case kind do
+
?# -> :wall
+
?O -> :box
+
?@ -> :robot
+
end
+
+
{{x, y}, kind}
+
end)
+
end)
+
|> Enum.group_by(&elem(&1, 1), &elem(&1, 0))
+
+
walls = MapSet.new(walls)
+
boxes = MapSet.new(boxes)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
MapSet.new([
+
{38, 2},
+
{29, 26},
+
{9, 34},
+
{47, 38},
+
{47, 44},
+
{22, 37},
+
{19, 38},
+
{27, 21},
+
{19, 22},
+
{16, 10},
+
{16, 38},
+
{35, 26},
+
{10, 32},
+
{36, 14},
+
{28, 48},
+
{17, 30},
+
{32, 18},
+
{40, 35},
+
{6, 23},
+
{28, 37},
+
{29, 47},
+
{29, 40},
+
{29, 10},
+
{6, 42},
+
{23, 46},
+
{10, 33},
+
{4, 46},
+
{43, 47},
+
{12, 8},
+
{3, 16},
+
{15, 3},
+
{20, 46},
+
{33, 48},
+
{35, 6},
+
{41, 9},
+
{25, 29},
+
{1, 2},
+
{3, 30},
+
{8, 5},
+
{18, 37},
+
{37, 43},
+
{3, 47},
+
{30, 26},
+
{41, 31},
+
{4, 15},
+
{33, 40},
+
{6, 21},
+
{5, 26},
+
{1, ...},
+
{...},
+
...
+
])
+
```
+
+
```elixir
+
moves = moves |> String.to_charlist() |> Enum.reject(& &1 not in ~c"^>v<")
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
~c">v>>>^>>v>vv^v^^v^^^<v^vv^vv<<>^v^^^<<<vv<>vv^^>v>v^^><>^<v<v><>>^>^<^^v>v<>^^v<><<^><v>v^v<<^>^>^>^>>vvv>^<<^^^^^><vv>>^>^^>^vv>><v^^v^<<<>^^<<<^^^vv^<^<<<>v<^v<v>^<>v<^>>^v^<>><><<^<>v>^>^>v>>v>vv^><v<v^v>vv>><^^<<>>vv<<^vv>^^vv>>><^v^>>v<<<<v>^<><>^>v^vv>v>><><^vvv>^><<>^<<<vvv^>^vv<<>v^^^>v<>^^vv>vv^<>^<>vvv<vvvv^^^<^vv^<v^<<vv^v<><vvvv^>vv<>><><<v>><^>v<>v<v<v>^v>^<>^v>>><^>>v<<<v^>^v>v>^^>^v<v^v^^<vv^v^><<^^<v^v>>^v>>>>>v<v^>^>^v^>vv^v^><^<v>^^<>^v^>><>>><vv<<>^v<^vvv<v^vvv^>v<<v>>^>><<^v^^v>^^>^<<<>v^^>><<v>^<v^<^>v>>>^^^<<vvv^>vvv>^><v>^>vvv^^^v^^>v^><v>><>^<v<<vv^^>>^^v>><vv>vvv>^>>>vv^><^<v<<<^^v>v^<v^^>^^<<<>v^vv<vvv>^v>v<^^>vv>v<>>vv<><v>v<^^<<^>>v<v^<>^<<v>><<vv^<<<<v^^^v^^<^<^<>v><^<>>v>v>v>v>v><v>>v<<^>>><v^v<v>>v^><^v^>>>^>^<<>>^^v><^<v^vv^<><>>v^^>v<vvv>v<>><<<<<>><<><v<>vv><^^^><vv<v<<>v^>v>>^^v^v^>vvv<v^<>><<<^>vvv><^^v>v<>v><^<v>v<^<<^<>v>>>>^<>^^^>v<v<<vv><v>>>^<^>v^><vv>^<<v<>><<^<>>>^v>><<>v^^v<^>v^v^>vvvv>vv<<>^^^<v>^<<v>>><<>>>vv^<^><><^^^>^v^<><>^<vv<^vv^^v>^<<^>vv>v>^^>^vvvv<<^><^<>>^<v>v>>^^<v><^<>><<<>^vv<>v<v^>>>^<<^<><<>^^vv^^<<><<vvv>v^^>vv^<v<<>>v><^>v^>>^^v<<<<^v<v<<>>v><v^>vv^<vv^>^v>^^>>><>v<><^v><vvvv^v<<>>^^v><>>vv^>v>v^>^>v<><^v>v^^<<>^v^>^>v<><^v<^^vv<>^^^v^>>><<><<<<v^v^><v<v<^^^><><^<<^^^vv<^^<^<v>v<<v^>>v<>>^<vv<^<v><>^<^v^>^v>>>^v>>v^>^^v^>><<v>>^<v>^vvv<v<<<v>^<>vv<^<v<>^<>v^v^>vv^v>><^>><>^^^<<v<vv^<vv>>v<^^^>vv<^^>vv^^^^<<^<v^>v<v>vvv<v<<^^><v<<^>^^<>v>>v><^v^<v>vv^<v<<v>v>vvv^>v<vv>>>>>^^v<<>^><>v^^^>^^>^>^^vvvv^v<v>>^^^v>>^<v<^^v>>><<>^^><<<^>v^^^v><v<v<v^v^><>^>v<v<^^^>>>vv><<^>><v>><<v<<vv><^^^<<^<>v>^v^v><<<<<<>>vv^<<<><<><><<^<^>^<v<^v>>>^>v^>^v>^v^<^>^v>><<<v>v^^vvv><<^>v^^<><v^>><<v><^^>>v<<<<<^>>><><vv>v<<>>^v<><<^>>v<<<^<^>>^>v^>^v<v>^v>>v<^>><<>><>vvv<<>vv^>v>><><<^><vvv>v><^>^<^v><>>v><v><^v^vv><>^^>>>v<^v^<^v>^v><vv<<v<<v><>>><v<vv<>>v^^>>>vv><v<<<<><v^^>>v>^<v^^>^v<<<><v>v>>^^<vv<v^v>><^<^^<>><v>^<^^<><^^^><>^<v^^^<v<^>>^v>vv^^<^v>><<vv><<v>><v>>>^>>><<<v<<><^vvv^<v>^>vvv^v>>v><<>v><<v<vvvvv^>^>><v^>vv^>>^vvv^v^><<v<>><><><<<^v>^v^><>^vvv<<^<<v^v<>>v<v^^>>^>v<v>^v<v^v>^<<vvv<^^v<<<<>v^v<<<v<^>><v^vv^vvvv^v><><v<<^>v>v^v^<v<v<^<><^>^vv<^^v<^^>vv<<>^^<>><<<<^^>>>^<^^>vv<>>>^^^^vv^>^v^v^^>^<<<>v^<v>^^^>v<^^<<^<v><^vvv>v>v>v<^>><^<^<>>>^^<<<vv^>>><>>v><>^<>^^<v^><<vv>vv^v<<>^>v><vvv>v^>>v^^^v<<>>^v><^<>^>^<^>^^<vv<>>><v^v^>>>^^>>^v^^^>>^v>v><^^^v<>>vv>>v^^<><^^v>v<^>>v<v^v^v^v^vv^vvv>v^vv>^v>vv<vv<^<<<v^v><<v>v<<^>vvv^^^^>>^>v>^^<>vv<>^^v><v<<^v><><><^<vv^>v^^>>>^^vv>^v>^<>vvv^v<^vv^<<^<^^<>>^<<><vv^>^>^^v^<v><v^>><^^>><<><<<<<<^>^><^v>^v>><v><v<>vvv>^^<^<<>v>>vv<v<><^<<^<>v<v>><><>^v><v<^^^<>>vvv>^^>>>v><v><^^>><<^<v><<^<v<<vv>>^vv<>v>^><><<<<<v>>>v^^v>^<>^<>v^^>>^<>>v^>^<>>>><>><v^v>>v>^<<^v^><<>>^v>><>><>>>><>vv<<>>^>v^v^<vvvvvvv^>v<<<^^<>vvvv^<<><<v^<<vv^^^v^^<<><v>v^^<^^v^^<>^v<>vvv>>^^v^^^<v>v^^vv<^^^<<>^v^>>^^<<^^v^^v<<vv^<<>>>v<>vv<v^v<<>vvv>^<v>v>^v<^^v<>^>^<><<v>v<>v^>v^v>><<><v><>>>>v^<^<^><>^v^<^><<v<^v><>>^v^^^v^><>^v>v<<^v>>^<<v<>v<^<<<<>>^><<<vv<^v^<^>^^><^^vvv^><v<><^^<>^v^>vvvv^vv^>>^v^v<^<vvv<>v>v>vv>^>^><^vv><v^v>v<><>v^v^>vvvv<<>v<^^^vv<^v><>^>^>v<>^>^vvv<>^>^<^^v^<><<>^>^v><v>^v>v^<v^<>>^^>^>v^>v>>^^<v><^<^vv>^vv^v^>v><^vv>^>v>^><>v>v^^>>v>^<<v^<vvv>>v<v>v^^<>^v^vv^<^^<v>>>v>>^v>vvv^^v^>v<vvv^<><v>v>v<>^^v^^<vv<>v<vvv>>><><<>>v>^^<^^^^><v>^>v<^<^>v^^>v>^>>^><<<^vv>vv^v^><v^<v>vv>^<>^vvvv^>vv>^>v^>v<<v^^<v^<v>>vvv<<v<>>>v^>^vv>^<v<>>^^v<vv<^>v<>^<<^^><>^^v>^v>>^<v>vv^v<<^^>^<v<><v>vv<><vv<>>v<^^^><<^^>^v<>vv<v>><<<v><<>>vv^>>^vvvv^><<v<vv^v<vv<>v<><v<<><v>vvv>>vv^^^<><^v<><v<^<v<v<^>>vv<><<>^^>><<v><^>vvv^>^vvv<>v^^<<^<vv>>v>^>v>^^><<>v<v^>^<<<<vv<<^^^>^>^>v<>>vv^><v<><<><^><><^^vv>>^<^vv<^^v<><<><>vvvv^^^<>v>>v^<vvv<v<vv><<v^v<v>>^v^<<^>>vvvv^v<<^<^vv<v<v>^v<^<^^>vv<v^^^>>^<^><^^v<v^v^>^^^v^v>^>^><^>>^v<v<^^^v^>>^v>vv>^v<>^v^^^v^v^>v>><^^<^v<<v<^v<>v^<>^<>^v<v^^v<^>v<v>^v<<><<<>^v><<<^>vvvvv^v^^^<<v>>v^>>^^<<v^^>vv^^vvvv>^>v^<<<^<>v><<^>^v^<^>><<<v<vv>vv<<^>^<^^><>>^^v>vvv^<^>^^^^<^v<<>^<>^>>v>^<><><>>^^vv^<<>><^<v><>^v^vvv<<>>^<>^>v<<^><<^>^<^>^<<><<<^<^>><<<vv>v<v<^<>>>v^>vv><>>vvvv<<^><<<>v<>v^v^<>v>v<^^<<v<vv^<<<vv>^<>^^vv<><v<<^v^v<^<v>>vv" ++ ...
+
```
+
+
## Part 1
+
+
```elixir
+
defmodule Warehouse.A do
+
def walk(start, path, walls, boxes) do
+
Enum.reduce(path, {start, boxes}, fn dir, {pos, boxes} ->
+
move(pos, walls, boxes, dir)
+
end)
+
|> elem(1)
+
end
+
+
def move({x, y}, walls, boxes, dir) do
+
next = next({x, y}, dir)
+
+
cond do
+
next in walls ->
+
{{x, y}, boxes}
+
+
next in boxes ->
+
if new_boxes = move_box(next, boxes, walls, dir) do
+
{next, new_boxes}
+
else
+
{{x, y}, boxes}
+
end
+
+
true ->
+
{next, boxes}
+
end
+
end
+
+
defp move_box(pos, boxes, walls, dir) do
+
next = next(pos, dir)
+
cond do
+
next in walls -> nil
+
+
next in boxes ->
+
if new_boxes = move_box(next, boxes, walls, dir) do
+
new_boxes |> MapSet.delete(pos) |> MapSet.put(next)
+
end
+
+
true ->
+
boxes |> MapSet.delete(pos) |> MapSet.put(next)
+
end
+
end
+
+
defp next({x, y}, ?^), do: {x, y - 1}
+
defp next({x, y}, ?>), do: {x + 1, y}
+
defp next({x, y}, ?v), do: {x, y + 1}
+
defp next({x, y}, ?<), do: {x - 1, y}
+
end
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:module, Warehouse.A, <<70, 79, 82, 49, 0, 0, 14, ...>>, {:next, 2}}
+
```
+
+
```elixir
+
robot
+
|> Warehouse.A.walk(moves, walls, boxes)
+
|> Enum.map(fn {x, y} -> x + y * 100 end)
+
|> Enum.sum()
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
1406628
+
```
+
+
## Part 2
+
+
```elixir
+
defmodule Warehouse.B do
+
def resize({x, y}, walls, boxes) do
+
start = {2 * x, y}
+
+
walls =
+
walls
+
|> Enum.flat_map(fn {x, y} ->
+
[{2 * x, y}, {2 * x + 1, y}]
+
end)
+
|> MapSet.new()
+
+
boxes =
+
boxes
+
|> Enum.flat_map(fn {x, y} ->
+
pos = [{2 * x, y}, {2 * x + 1, y}]
+
box = %{p: pos}
+
+
for p <- pos do
+
{p, box}
+
end
+
end)
+
+
{start, walls, boxes}
+
end
+
+
def walk(start, path, walls, boxes) do
+
Enum.reduce(path, {start, boxes}, fn dir, {pos, boxes} ->
+
move(pos, walls, boxes, dir)
+
end)
+
|> elem(1)
+
end
+
+
def move({x, y}, walls, boxes, dir) do
+
next = next({x, y}, dir)
+
+
cond do
+
next in walls ->
+
{{x, y}, boxes}
+
+
box = boxes[next] ->
+
if new_boxes = move_box(box, boxes, walls, dir) do
+
{next, new_boxes}
+
else
+
{{x, y}, boxes}
+
end
+
+
true ->
+
{next, boxes}
+
end
+
end
+
+
defp move_box(%{p: pos}, boxes, walls, dir) do
+
next = next(pos, dir)
+
+
cond do
+
Enum.any?(pos, & &1 in walls) ->
+
throw(:wall)
+
+
(next_boxes = select_boxes_at(pos, boxes)) != [] ->
+
if new_boxes = move_box(next, boxes, walls, dir) do
+
new_boxes |> MapSet.delete(pos) |> MapSet.put(next)
+
end
+
+
true ->
+
boxes |> Map.drop(pos) |> MapSet.put(next)
+
end
+
catch
+
:throw, :wall -> nil
+
end
+
+
defp select_boxes_at(pos, boxes) do
+
boxes
+
|> Map.take(pos)
+
|> Enum.uniq()
+
end
+
+
defp next({x, y}, ?^), do: {x, y - 1}
+
defp next({x, y}, ?>), do: {x + 1, y}
+
defp next({x, y}, ?v), do: {x, y + 1}
+
defp next({x, y}, ?<), do: {x - 1, y}
+
end
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
warning: variable "next_boxes" is unused (if the variable is not meant to be used, prefix it with an underscore)
+
โ””โ”€ Workspace/hauleth/advent-of-code/2024/day15.livemd#cell:3ajets4kgmkyknvu:59: Warehouse.B.move_box/4
+
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:module, Warehouse.B, <<70, 79, 82, 49, 0, 0, 20, ...>>, {:next, 2}}
+
```
+
+
<!-- livebook:{"offset":23559,"stamp":{"token":"XCP.GtnzBtRKuk3dCuG1gVPqYVHJwR27FPAQixvDel9XY7YKKtIR-fLOYjYE9q5s_RDyt_V8hQtSWHWE0pTlg7ukiaTmklnlkowdbH-y0AJ21EtpRoXXQ3C48_7vRp_64BdLpHY","version":2}} -->
+303
2024/day16.livemd
···
+
<!-- livebook:{"persist_outputs":true} -->
+
+
# Day 16
+
+
```elixir
+
Mix.install([:kino_aoc, :image])
+
```
+
+
## Setup
+
+
<!-- livebook:{"attrs":"eyJhc3NpZ25fdG8iOiJwdXp6bGVfaW5wdXQiLCJkYXkiOiIxNiIsInNlc3Npb25fc2VjcmV0IjoiQURWRU5UX09GX0NPREVfU0VTU0lPTiIsInllYXIiOiIyMDI0In0","chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2024", "16", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:ok,
+
"#############################################################################################################################################\n#.....#.......#.............#.........#.......................#.......#...#...............#.....#.#.................................#.#....E#\n#.#####.###.###.#######.###.#.#.#######.#.###.#####.###.#######.#.###.###.#.#####.#####.###.#.#.#.#.#####.###.#.###.#######.###.#.#.#.#.#.#.#\n#.......#...#...#.....#.#.#.#.#.#...#...#.....#...#.#...#.......#...#.#...#...#...#.#...#...............#...#...#.#.......#.#...#.#.#...#.#.#\n#########.#.#.###.#####.#.#.#.#.#.#.#.#########.#.#.###.#.#########.#.#.#.#.###.#.#.#.###.###.#####.###.###.#.#.#.###.###.#.#.###.#.#.###.#.#\n#.......#.#.#.#...#...#.#.#.#.#...#.....#.......#.#...#.#.#...#...#.#...#.#.#...#.....#...#.#...#...#.....#.#.....#.....#.#...#...#.#.#...#.#\n#.#####.#.###.#.#.#.#.#.#.#.###########.#######.#.###.#.#.###.#.#.#.#.#####.#.###.###.#.###.###.#.###.#.###.#.#.#.#.#.#.#.#.#.#.###.###.#####\n#...#...#.......#.#.#...#.#...........................#.#.#...#.#...#.#.....#.#.....#.#...#...#.....................#.#.#...................#\n#.#.#.#######.#####.#####.###########.#######.#####.#.###.#.###.#######.#####.###.#.#.###.#.#.#.#.#######.###.#.#####.#.#.#.#.###.###.#.###.#\n#.#...#.....#.#...#...#.......#.......#.....#...#...#.....#.#...#.....#...#...#.....#...#...#.#...#.......#...#.#...#.#.#.#.#...#.#...#...#.#\n#.#.###.###.###.#.#.#.###.###.#.#.#####.###.###.#.#########.#.###.###.###.#.###.#.###.#######.#####.#######.#.#.#.#.#.###.###.#.#.#.#######.#\n#.#.....#.......#.#.#...#.#...#.#...#...#.#.#.#.#.......#...#...#...#.......................#...#.#.#.....#.#.....#.#.........#...#.#.....#.#\n#.###.###########.#####.#.#####.#.#.#.#.#.#.#.#.###.###.#.#.###.###.#########.###.#.#.#.###.#.#.#.#.#####.#.#.#.#####.#######.#####.#.###.#.#\n#...#...................#.....#.#.#.#.#.#.....#.....#.#...#.#.#...#.....#...#.....#.#.#.#.#.....#.#.....#.#...#.#.........#...........#.....#\n#.#.#.#.###.#.###############.#.#.#.#.#.#############.#####.#.###.#####.#.#.#####.#.#.#.#.#######.#####.#.###.#.#.###.###.#.#.###.###########\n#.#.#.#.#.#.#.#.....#.......#.#...#...#...............#...#...#.#...#...#.#.......#.#.#.#.......#...#...#.....#.#.#.......#.#...#.#.........#\n#.#.###.#.#.###.###.###.#.#.#.###.#.#####.###.###.###.#.#.###.#.#.###.###.###.###.#.#.#.###.###.###.#.###.#####.#.#.#.###.#.#.#.###.#######.#\n#.#.....#.#...#.#.#...#.#.#.#...#.#.#...#...#...#...#...#...#...#.....#...#...#.......#.....#.#.....#...#.......#...#.#...#...#...#.#.#.....#\n#.#######.###.#.#.###.#.#.#.#.#.#.###.#.#####.#.#.#.#########.#.#######.#.#.#.#.#############.#####.###.#########.#####.###.#####.#.#.#.#.###\n#.#.......#.#.....#...#.#.#...#.#.#...#.....#.#.#.#.........#.#.........#.#.#.#.#.................#.#.#...#.......#.........#...#...#.#.....#\n#.#.#####.#.#######.#####.#######.#.#####.#.###.#.#########.#.#.#########.#.#.#.###.#######.#.#####.#.###.#.#######.#.###.###.#.#####.###.#.#\n#.#.....#.......#...#...#...#.....#.#...........#.#.......#...#.#...#.....#.#.#...#.#.......#.#...#...#...#.....#...#...#.#.................#\n#.#####.#######.#.###.#.###.#.#####.#######.#####.#.#.###.#####.#.#.###.###.#.###.###.#####.###.#.###.#.#######.#.#####.#.#####.#.#.###.#.#.#\n#.#...#.#.....#...#...#...#.#.......#.....#.#.....#.#...#.#...#.#.#...#.#...#.#.#...#.#...#.#...#...#.#.........#.....#.#.......#...#...#.#.#\n#.#.#.#.#.###.#.###.#####.#.#.#####.#.###.###.#########.###.#.#.#.###.#.#.###.#.###.#.#.#.###.###.###.###############.#.###########.#.###.#.#\n#.#.#.#.#.#.....#...#...#...#.....#...#.#...#.#...#...#.#...#.#...#...#.#.#.#.#.........#.#...#.#.....#.......#.......#.........#...#.#.....#\n#.#.#.#.#.#######.###.#.#.#.#####.###.#.###.#.#.#.#.#.#.#.###.#####.#####.#.#.#########.#.#.###.#######.#######.###############.#.###.#.#.###\n#.#.#...#.........#...#.#.#.....#...#...#.#.....#...#...#.#.#...#...#.....#.#.....#.....#...#.....#.....#.....#...#...#...#.....#...#.#.#...#\n#.#.#########.#######.#.#.#.###.###.###.#.###########.###.#.###.#.###.#.###.#####.#.#########.#.#.###.#.#.###.#.#.#.#.#." <> ...}
+
```
+
+
```elixir
+
%{?# => walls, ?S => [start], ?E => [finish]} =
+
puzzle_input
+
|> String.trim()
+
|> String.split("\n", trim: true)
+
|> Enum.with_index()
+
|> Enum.flat_map(fn {row, y} ->
+
row
+
|> String.trim()
+
|> String.to_charlist()
+
|> Enum.with_index()
+
|> Enum.map(fn {char, x} ->
+
{{x, y}, char}
+
end)
+
end)
+
|> Enum.group_by(&elem(&1, 1), &elem(&1, 0))
+
+
walls = MapSet.new(walls)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
MapSet.new([
+
{76, 13},
+
{112, 138},
+
{38, 2},
+
{124, 56},
+
{83, 76},
+
{140, 11},
+
{100, 134},
+
{75, 140},
+
{103, 106},
+
{68, 134},
+
{124, 60},
+
{35, 30},
+
{2, 132},
+
{8, 50},
+
{78, 98},
+
{101, 62},
+
{98, 136},
+
{95, 56},
+
{74, 12},
+
{102, 74},
+
{22, 38},
+
{14, 86},
+
{12, 135},
+
{86, 10},
+
{29, 26},
+
{4, 81},
+
{31, 42},
+
{9, 34},
+
{137, 16},
+
{86, 138},
+
{90, 0},
+
{14, 122},
+
{120, 42},
+
{102, 57},
+
{84, 102},
+
{138, 124},
+
{0, 101},
+
{116, 96},
+
{54, 138},
+
{18, 134},
+
{82, 60},
+
{15, 92},
+
{58, 58},
+
{78, 75},
+
{75, 0},
+
{16, 73},
+
{76, 2},
+
{58, 84},
+
{138, ...},
+
{...},
+
...
+
])
+
```
+
+
```elixir
+
{_, {w, h}} = Enum.min_max(walls)
+
+
w = w + 1
+
h = h + 1
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
141
+
```
+
+
```elixir
+
put_in(%{}, [Access.key(:a, %{}), :b], 10)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
%{a: %{b: 10}}
+
```
+
+
```elixir
+
defmodule Race.B do
+
@turns ~w'^ > v <'a
+
+
defguardp score(elements, pos, dir) when :erlang.map_get({pos, dir}, elements).score
+
+
def search_paths(start, finish, dir \\ :>, walls) when dir in @turns do
+
result = do_search([{0, [{start, dir}]}], walls, %{})
+
+
%{paths: visited, score: score} = result[{finish, :>}]
+
+
all = get_all(visited, result)
+
+
{score, all}
+
end
+
+
def get_all(path, seen) do
+
Enum.reduce(path, MapSet.new(), fn p, acc ->
+
path = MapSet.new(seen[p].paths, fn {p, _} -> p end)
+
MapSet.union(acc, path)
+
end)
+
end
+
+
def do_search([], _, visited), do: visited
+
+
def do_search([{cost, [{curr, dir} | _] = path} | rest], walls, visited)
+
when cost == score(visited, curr, dir) do
+
visited = Map.update!(visited, {curr, dir}, &%{&1 | paths: path})
+
+
do_search(rest, walls, visited)
+
end
+
+
def do_search([{cost, [{curr, prev} | _] = path} | rest], walls, visited)
+
when not is_map_key(visited, {curr, prev})
+
when cost < score(visited, curr, prev) do
+
visited = Map.put(visited, {curr, prev}, %{score: cost, paths: path})
+
+
@turns
+
|> Enum.map(fn dir -> {cost + cost(prev, dir), [{step(curr, dir), dir} | path]} end)
+
|> Enum.reject(fn {_cost, [{pos, _} | _]} -> pos in walls end)
+
|> sort_merge(rest)
+
|> do_search(walls, visited)
+
end
+
+
def do_search([{_, [_curr | _]} | rest], walls, visited),
+
do: do_search(rest, walls, visited)
+
+
# Going straight is cheap and turning is costly
+
defp cost(a, a), do: 1
+
defp cost(_, _), do: 1001
+
+
defp step({x, y}, :^), do: {x, y - 1}
+
defp step({x, y}, :>), do: {x + 1, y}
+
defp step({x, y}, :v), do: {x, y + 1}
+
defp step({x, y}, :<), do: {x - 1, y}
+
+
defp sort_merge([], bs), do: bs
+
defp sort_merge(as, []), do: as
+
+
defp sort_merge([a | as], [b | bs]) do
+
if a < b do
+
[a | sort_merge(as, [b | bs])]
+
else
+
[b | sort_merge([a | as], bs)]
+
end
+
end
+
end
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:module, Race.B, <<70, 79, 82, 49, 0, 0, 23, ...>>, {:sort_merge, 2}}
+
```
+
+
```elixir
+
{score, paths} = Race.B.search_paths(start, finish, walls)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{134588,
+
MapSet.new([
+
{77, 129},
+
{17, 138},
+
{17, 137},
+
{37, 139},
+
{19, 137},
+
{100, 131},
+
{139, 68},
+
{14, 139},
+
{79, 128},
+
{19, 138},
+
{50, 137},
+
{139, 67},
+
{137, 104},
+
{137, 117},
+
{131, 49},
+
{107, 125},
+
{3, 127},
+
{135, 64},
+
{4, 131},
+
{21, 134},
+
{63, 127},
+
{101, 124},
+
{5, 139},
+
{125, 14},
+
{129, 48},
+
{139, 70},
+
{21, 119},
+
{17, 129},
+
{137, 120},
+
{17, 136},
+
{131, 120},
+
{32, 139},
+
{133, 21},
+
{102, 123},
+
{12, 111},
+
{123, 19},
+
{112, 127},
+
{73, 129},
+
{7, 116},
+
{127, 22},
+
{7, 137},
+
{9, 131},
+
{24, 133},
+
{137, 95},
+
{8, 133},
+
{134, 7},
+
{129, ...},
+
{...},
+
...
+
])}
+
```
+
+
## Part 1
+
+
```elixir
+
score
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
134588
+
```
+
+
```elixir
+
Image.new!(w, h)
+
|> Image.mutate(fn img ->
+
for {x, y} <- walls do
+
Image.Draw.point(img, x, y, color: [128, 0, 0])
+
end
+
+
for {x, y} <- paths do
+
Image.Draw.point(img, x, y, color: [0, 255, 0])
+
end
+
+
img
+
end)
+
|> elem(1)
+
|> Image.resize!(6, interpolate: :nearest)
+
```
+
+
## Part 2
+
+
```elixir
+
MapSet.size(paths)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
625
+
```
+
+
<!-- livebook:{"offset":9337,"stamp":{"token":"XCP.AVI7h-Nq9jZKx9YmL5qYerJkeKKqddhzKrKUkab-HwNDUM8nQItD1O_rd2ROsJxc96gwIzwrMAixlIdLeZAgOVhtCs22LZM44Wl1VwcpYbg3RNCdgwIjqGheO5YrCGrEGJc","version":2}} -->
+206
2024/day17.livemd
···
+
<!-- livebook:{"persist_outputs":true} -->
+
+
# Day 17
+
+
```elixir
+
Mix.install([:kino_aoc])
+
```
+
+
## Section
+
+
<!-- livebook:{"attrs":"eyJhc3NpZ25fdG8iOiJwdXp6bGVfaW5wdXQiLCJkYXkiOiIxNyIsInNlc3Npb25fc2VjcmV0IjoiQURWRU5UX09GX0NPREVfU0VTU0lPTiIsInllYXIiOiIyMDI0In0","chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2024", "17", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:ok,
+
"Register A: 66245665\nRegister B: 0\nRegister C: 0\n\nProgram: 2,4,1,7,7,5,1,7,4,6,0,3,5,5,3,0"}
+
```
+
+
```elixir
+
defmodule Computer do
+
@instructions ~w[adv bxl bst jnz bxc out bdv cdv]a
+
|> Enum.with_index()
+
|> Map.new(fn {name, ins} -> {ins, name} end)
+
+
def load(opcodes) do
+
opcodes
+
|> Enum.chunk_every(2)
+
|> Enum.map(fn [opcode, op] ->
+
{@instructions[opcode], op}
+
end)
+
|> List.to_tuple()
+
end
+
+
def process(program, reg) do
+
reg = Map.merge(%{a: 0, b: 0, c: 0}, Map.new(reg))
+
do_process(program, 0, reg, [])
+
end
+
+
defp do_process(program, idx, _reg, out) when idx >= tuple_size(program) do
+
Enum.reverse(out)
+
end
+
+
defp do_process(program, idx, reg, out) do
+
ins = elem(program, idx)
+
+
case compute(ins, reg) do
+
new_reg when is_map(new_reg) ->
+
do_process(program, idx + 1, new_reg, out)
+
+
{:out, op} ->
+
do_process(program, idx + 1, reg, [op | out])
+
+
{:jump, op} ->
+
do_process(program, op, reg, out)
+
end
+
end
+
+
def compute({:adv, op}, reg),
+
do: %{reg | a: div(reg.a, 2 ** combo(op, reg))}
+
+
def compute({:bdv, op}, reg),
+
do: %{reg | b: div(reg.a, 2 ** combo(op, reg))}
+
+
def compute({:cdv, op}, reg),
+
do: %{reg | c: div(reg.a, 2 ** combo(op, reg))}
+
+
def compute({:bxl, op}, reg),
+
do: %{reg | b: Bitwise.bxor(reg.b, op)}
+
+
def compute({:bxc, _op}, reg),
+
do: %{reg | b: Bitwise.bxor(reg.b, reg.c)}
+
+
def compute({:bst, op}, reg),
+
do: %{reg | b: Bitwise.band(combo(op, reg), 0b111)}
+
+
def compute({:out, op}, reg),
+
do: {:out, Bitwise.band(combo(op, reg), 0b111)}
+
+
def compute({:jnz, op}, reg) do
+
if reg.a != 0 do
+
{:jump, op}
+
else
+
reg
+
end
+
end
+
+
defp combo(v, _) when v in 0..3, do: v
+
defp combo(4, %{a: a}), do: a
+
defp combo(5, %{b: b}), do: b
+
defp combo(6, %{c: c}), do: c
+
end
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:module, Computer, <<70, 79, 82, 49, 0, 0, 21, ...>>, {:combo, 2}}
+
```
+
+
```elixir
+
[
+
"Register A: " <> a,
+
"Register B: " <> b,
+
"Register C: " <> c,
+
"Program: " <> raw_code
+
] = String.split(puzzle_input, "\n", trim: true)
+
+
reg = %{
+
a: String.to_integer(a),
+
b: String.to_integer(b),
+
c: String.to_integer(c)
+
} |> dbg()
+
+
code =
+
raw_code
+
|> String.split(",")
+
|> Enum.map(&String.to_integer/1)
+
+
program = Computer.load(code)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
%{a: 66245665, b: 0, c: 0}
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{{:bst, 4}, {:bxl, 7}, {:cdv, 5}, {:bxl, 7}, {:bxc, 6}, {:adv, 3}, {:out, 5}, {:jnz, 0}}
+
```
+
+
## Part 1
+
+
```elixir
+
out = Computer.process(program, reg)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
[1, 4, 6, 1, 6, 4, 3, 0, 3]
+
```
+
+
```elixir
+
IO.puts(Enum.join(out, ","))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
1,4,6,1,6,4,3,0,3
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
:ok
+
```
+
+
## Part 2
+
+
```elixir
+
defmodule Quine do
+
def find(program, target) do
+
do_find(program, Enum.reverse(target), Enum.to_list(0..7))
+
end
+
+
def do_find(_program, [], out), do: out
+
+
def do_find(program, [n | rest], out) do
+
potential =
+
for a <- out,
+
i <- 0..7,
+
hd(Computer.process(program, a: a * 8 + i)) == n,
+
do: a * 8 + i
+
+
do_find(program, rest, potential)
+
end
+
end
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:module, Quine, <<70, 79, 82, 49, 0, 0, 10, ...>>, {:do_find, 3}}
+
```
+
+
```elixir
+
Quine.find(program, code) |> Enum.min()
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
265061364597659
+
```
+
+
<!-- livebook:{"offset":4021,"stamp":{"token":"XCP.PwUWTErrjClVJj6ZS87ZLrfbzleELwxqD__HBvfB1y_Yc633Wj72_Jigo2Z3T7V2ONi1nVguQ_AE_NSyLCF5sjSmWldUKuW294o_wsQqiM_gKhXOjSLzJOnslN9iIEFIEww","version":2}} -->
+194
2024/day18.livemd
···
+
<!-- livebook:{"persist_outputs":true} -->
+
+
# Day 18
+
+
```elixir
+
Mix.install([:kino_aoc, :image])
+
```
+
+
## Section
+
+
<!-- livebook:{"attrs":"eyJhc3NpZ25fdG8iOiJwdXp6bGVfaW5wdXQiLCJkYXkiOiIxOCIsInNlc3Npb25fc2VjcmV0IjoiQURWRU5UX09GX0NPREVfU0VTU0lPTiIsInllYXIiOiIyMDI0In0","chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2024", "18", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:ok,
+
"21,9\n69,53\n31,24\n2,9\n50,53\n2,5\n3,44\n69,49\n25,26\n50,31\n68,41\n54,67\n19,8\n11,9\n9,29\n1,31\n13,12\n28,5\n69,41\n51,66\n53,43\n65,35\n40,67\n43,13\n21,34\n49,3\n65,61\n25,9\n39,21\n59,37\n11,24\n9,30\n63,62\n41,69\n6,29\n68,47\n45,1\n9,1\n11,14\n59,19\n67,54\n12,5\n41,44\n59,45\n3,28\n57,42\n7,25\n43,11\n31,19\n9,6\n53,60\n29,8\n53,67\n17,1\n11,17\n31,3\n55,35\n2,21\n67,61\n37,5\n6,1\n51,24\n39,1\n31,1\n69,58\n61,19\n49,63\n40,21\n28,25\n59,59\n66,69\n30,1\n7,5\n53,49\n4,17\n39,23\n23,20\n62,67\n51,36\n55,39\n41,3\n57,30\n18,7\n6,37\n29,25\n55,48\n37,16\n65,69\n21,5\n43,48\n3,11\n3,9\n63,39\n23,23\n43,67\n47,3\n69,47\n67,53\n65,24\n67,52\n35,20\n46,45\n57,26\n15,32\n35,68\n15,16\n41,1\n63,29\n15,3\n15,18\n51,50\n60,43\n50,1\n35,12\n41,10\n58,39\n27,18\n50,69\n55,40\n2,3\n51,47\n1,11\n16,9\n23,9\n19,7\n29,12\n37,3\n1,15\n11,1\n25,11\n65,56\n37,70\n60,41\n48,69\n62,29\n53,38\n12,35\n67,42\n49,67\n31,5\n39,7\n65,43\n5,25\n23,24\n43,68\n11,11\n9,32\n62,39\n69,39\n51,46\n38,21\n67,37\n5,26\n62,19\n27,21\n48,51\n55,62\n11,33\n25,4\n13,20\n61,58\n62,55\n41,66\n11,40\n16,7\n9,17\n67,65\n1,1\n9,33\n7,35\n1,3\n11,4\n29,21\n47,47\n61,67\n41,70\n42,65\n55,47\n54,49\n36,13\n61,36\n18,23\n26,23\n45,5\n9,18\n61,27\n36,21\n59,32\n4,9\n6,35\n51,23\n1,17\n12,11\n65,67\n41,65\n37,65\n1,24\n21,8\n59,28\n17,14\n63,68\n20,19\n17,10\n63,69\n57,44\n55,56\n45,64\n25,27\n27,4\n22,23\n5,13\n19,14\n47,46\n49,4\n21,15\n63,58\n60,31\n25,28\n6,3\n61,38\n33,5\n58,37\n11,32\n21,7\n44,61\n55,45\n55,37\n35,22\n10,15\n36,5\n19,11\n59,31\n33,19\n30,5\n69,69\n69,63\n57,69\n5,33\n60,27\n29,7\n57,43\n61,61\n3,26\n13,33\n57,59\n66,39\n63,27\n33,11\n51,1\n52,67\n5,29\n35,3\n17,2\n9,31\n37,24\n61,23\n9,5\n68,35\n21,28\n2,25\n51,48\n68,49\n4,19\n43,66\n7,34\n13,15\n36,1\n42,63\n13,0\n23,7\n48,47\n56,31\n55,43\n47,45\n18,15\n56,45\n61,64\n48,45\n69,65\n40,11\n51,68\n51,51\n53,46\n3,30\n49,62\n4,13\n17,27\n38,69\n41,0\n5,23\n65,32\n9,35\n55,21\n65,55\n51,39\n67,51\n5,9\n39,5\n58,49\n21,17\n63,41\n21,18\n57,65\n53,51\n2,13\n53,0\n53,6\n27,17\n55,59\n61,42\n27,7\n25,25\n39,13\n62,53\n51,44\n2,27\n19,17\n58,65\n8,1\n30,23\n14,5\n33,3\n43,65\n18,27\n35,7\n11,35\n12,29\n57,68\n59,63\n44,19\n36,25\n68,37\n15,19\n53,39\n62,69\n35,4\n61,55\n59,43\n23,17\n69,45\n18,5\n50,59\n39,6\n69,32\n17,5\n11,8\n21,2\n39,4\n64,65\n33,2\n17,22\n33,50\n25,24\n44,51\n31,7\n11,38\n11,25\n63,59\n25,21\n42,7\n8,11\n33,9\n45,63\n62,63\n33,4\n66,59\n61,29\n5,27\n59,27\n55,20\n38,9\n8,7\n51,3\n23,1\n53,65\n69,55\n1,34\n70,49\n61,57\n22,9\n17,26\n17,12\n61,69\n49,43\n9,28\n33,26\n15,35\n13,34\n55,27\n68,45\n45,61\n59,47\n13,29\n59,33\n65,53\n10,1\n35,21\n13,27\n28,1\n23,10\n61,37\n69,57\n23,21\n5,28\n57,48\n41,21\n11,13\n20,11\n1,21\n61,66\n66,47\n63,26\n5,15\n3,20\n17,4\n43,5\n16,29\n63,44\n63,55\n55,69\n5,22\n37,11\n50,39\n59,39\n25,16\n48,1\n43,60\n13,6\n49,37\n3,32\n57,23\n46,69\n2,35\n37,1\n53,27\n31,22\n63,36\n46,43\n68,57\n45,67\n32,9\n48,65\n15,15\n8,29\n13,1\n55,41\n65,65\n13,31\n49,69\n19,6\n29,19\n32,23\n49,41\n15,24\n65,22\n15,33\n6,21\n7,9\n69,64\n63,23\n5,21\n15,1\n44,1\n11,27\n63,34\n15,13\n39,9\n63,20\n58,29\n28,21\n7,37\n39,65\n41,16\n21,6\n49,47\n47,61\n50,63\n23,15\n68,67\n64,57\n19,13\n69,61\n1,22\n27,3\n28,13\n19,31\n23,2\n3,31\n25,6\n61,47\n51,63\n59,64\n27,2\n7,33\n63,63\n65,42\n5,12\n12,15\n27,9\n15,7\n6,17\n17,17\n15,2\n59,61\n63,47\n57,33\n13,17\n47,67\n11,26\n20,3\n13,7\n17,33\n10,5\n57,32\n58,53\n7,18\n66,65\n6,5\n11,5\n41,9\n21,21\n69,43\n11,20\n41,14\n38,3\n67,69\n15,17\n45,58\n51,61\n54,23\n49,39\n59,29\n53,63\n45,69\n16,1\n55,51\n21,13\n56,47\n63,40\n63,37\n37,19\n43,3\n7,17\n27,5\n14,25\n17,3\n44,69\n31,8\n14,9\n14,7\n63,45\n4,1\n49,34\n19,44\n46,53\n38,17\n33,0\n50,55\n27,25\n63,21\n19,12\n35,10\n54,3\n65,50\n47,62\n38,65\n61,39\n33,1\n65,52\n5,5\n0,3\n63,33\n30,27\n29,27\n29,1\n48,67\n33,23\n46,5\n60,35\n39,14\n59,46\n51,49\n64,21\n69,60\n3,3\n59,58\n9,36\n9,37\n48,41\n23,5\n7,3\n61,65\n61,22\n3,15\n4,37\n43,20\n66,45\n69,66\n43,12\n54,43\n52,49\n15,23\n33,21\n36,67\n61,24\n5,7\n37,7\n60,55\n53,70\n52,1\n21,33\n53,69\n67,43\n61,34\n6,31\n55,55\n59,40\n16,17\n65,25\n24,29\n59,21\n66,63\n61,41\n17,24\n0,15\n17,19\n1,13\n23,3\n49,45\n39,2\n59,49\n31,25\n65,40\n7,7\n70,43\n57,63\n65,54\n18,1\n41,15\n25,19\n33,18\n5,24\n13,3\n64,37\n43,7\n31,9\n30,11\n56,63\n65,34\n67,39\n17,18\n65,37\n49,56\n59,25\n7,11\n65,38\n37,18\n5,3\n21,22\n47,69\n19,9\n70,39\n15,14\n40,3\n5,31\n19,21\n55,34\n67,49\n45,11\n17,23\n41,5\n33,6\n37,10\n55,2\n17,9\n57,39\n5,1\n9,10\n17,7\n60,23\n55,68\n5,11\n63,67\n59,65\n7,19\n51,56\n26,1\n30,3\n15,20\n19,15\n3,21\n59,51\n11,7\n61,26\n19,23\n22,11\n25,8\n18,17\n27,26\n17,29\n7,13\n65,33\n44,5\n22,13\n56,65\n24,19\n25,17\n55,66\n65,39\n32,19\n3,19\n9,15\n54,63\n55,23\n61,59\n21,11\n46,39\n57,40\n65,19\n65,59\n65,48\n64,47\n32,21\n1,5\n15,11\n65,23\n4,2" <> ...}
+
```
+
+
```elixir
+
bytes =
+
puzzle_input
+
|> String.split("\n", trim: true)
+
|> Enum.map(fn row ->
+
[x, y] = String.split(row, ",")
+
+
{String.to_integer(x), String.to_integer(y)}
+
end)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
[
+
{21, 9},
+
{69, 53},
+
{31, 24},
+
{2, 9},
+
{50, 53},
+
{2, 5},
+
{3, 44},
+
{69, 49},
+
{25, 26},
+
{50, 31},
+
{68, 41},
+
{54, 67},
+
{19, 8},
+
{11, 9},
+
{9, 29},
+
{1, 31},
+
{13, 12},
+
{28, 5},
+
{69, 41},
+
{51, 66},
+
{53, 43},
+
{65, 35},
+
{40, 67},
+
{43, 13},
+
{21, 34},
+
{49, 3},
+
{65, 61},
+
{25, 9},
+
{39, 21},
+
{59, 37},
+
{11, 24},
+
{9, 30},
+
{63, 62},
+
{41, 69},
+
{6, 29},
+
{68, 47},
+
{45, 1},
+
{9, 1},
+
{11, 14},
+
{59, 19},
+
{67, 54},
+
{12, 5},
+
{41, 44},
+
{59, 45},
+
{3, 28},
+
{57, 42},
+
{7, 25},
+
{43, 11},
+
{31, ...},
+
{...},
+
...
+
]
+
```
+
+
```elixir
+
Image.new!(71, 71, color: :forestgreen)
+
|> Image.mutate(fn img ->
+
for x <- 0..70, y <- 0..70, {x, y} in Enum.take(bytes, 1024) do
+
Image.Draw.point(img, x, y, color: :firebrick)
+
end
+
+
img
+
end)
+
|> elem(1)
+
|> Image.resize!(4, interpolate: :nearest)
+
```
+
+
```elixir
+
defmodule Memory do
+
@d [{-1, 0}, {1, 0}, {0, -1}, {0, 1}]
+
def find_path(from, to, bytes), do: do_find([{0, from}], to, MapSet.new(bytes), %{})
+
+
def do_find([], _, _, _), do: :none
+
+
def do_find([{dist, to} | _], to, _, _visited), do: dist
+
+
def do_find([{dist, {x, y} = p} | rest], {w, h} = to, bytes, visited)
+
when not is_map_key(visited, p)
+
when dist < :erlang.map_get(p, visited)
+
do
+
visited = Map.put(visited, p, dist)
+
+
next =
+
for {dx, dy} <- @d,
+
(x + dx) in 0..w,
+
(y + dy) in 0..h,
+
p = {x + dx, y + dy},
+
p not in bytes,
+
not is_map_key(visited, p),
+
do: {dist + 1, p}
+
+
next
+
|> Enum.concat(rest)
+
|> Enum.sort()
+
|> do_find(to, bytes, visited)
+
end
+
+
def do_find([_ | rest], to, bytes, visited), do: do_find(rest, to, bytes, visited)
+
end
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:module, Memory, <<70, 79, 82, 49, 0, 0, 13, ...>>, {:do_find, 4}}
+
```
+
+
## Part 1
+
+
## Part 1
+
+
```elixir
+
Memory.find_path({0, 0}, {70, 70}, Enum.take(bytes, 1024))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
250
+
```
+
+
## Part 2
+
+
```elixir
+
{x, y} =
+
bytes
+
|> Enum.reverse()
+
|> Stream.unfold(fn
+
[] -> nil
+
[_ | rest] = curr -> {curr, rest}
+
end)
+
|> Enum.find_value(fn [pos | fallen] ->
+
path = Memory.find_path({0, 0}, {70, 70}, fallen)
+
+
if path != :none do
+
pos
+
end
+
end)
+
+
IO.puts("#{x},#{y}")
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
56,8
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
:ok
+
```
+
+
<!-- livebook:{"offset":7984,"stamp":{"token":"XCP.CPT4l_BNbZGxGbR_fK_dYfzmCSPzRQfyiJPfaGWsNChhlNQI36bgn8XXEOmsc56qlDi2H-j-H4aYpxwTYXzlirEAyckZaTUuHdujjNaTLq1pQEjB3uTTMbVmMkdf1KvN3g0","version":2}} -->
+126
2024/day19.livemd
···
+
<!-- livebook:{"persist_outputs":true} -->
+
+
# Day 19
+
+
```elixir
+
Mix.install([:kino_aoc])
+
```
+
+
## Section
+
+
<!-- livebook:{"attrs":"eyJhc3NpZ25fdG8iOiJwdXp6bGVfaW5wdXQiLCJkYXkiOiIxOSIsInNlc3Npb25fc2VjcmV0IjoiQURWRU5UX09GX0NPREVfU0VTU0lPTiIsInllYXIiOiIyMDI0In0","chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2024", "19", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:ok,
+
"rrbb, rgrb, rbbwbw, ruw, grwb, wbg, rrggu, wugbb, gwr, rrgu, wbbb, bwrgugb, rgww, brrw, gwwg, brgbb, ubbbu, rbgruw, bwub, rru, grbu, grw, bwrbr, wrwbwu, bgbr, urrb, bbb, guggb, gwuwuw, ubu, wbr, bb, ubwwrb, bruuwu, buw, wrr, gbgrr, ggw, ru, wub, uub, gbrw, uwrwrb, uwuu, wbbu, gwu, brrr, grggur, wugrbrw, rwuurgg, wrbg, wuugrgw, brr, wrgwu, rwwuur, wgug, guu, brru, bgr, buwruw, bbg, bw, brwuwbb, buwbrgrb, wrwuw, ubb, rgu, wru, ugw, rruubrr, bwur, rrb, uwg, wwbbuwu, rbw, uwrgbr, ubuw, uurwr, uggw, uuguur, guuww, bbrgw, ubuwbuu, buwgg, gru, uuu, u, wgguw, bruu, bu, gwurrw, rbgwur, gubg, ubgrubw, buwrgw, uu, rwgw, rrw, wgru, gwrb, bgguu, gwugwu, urrbg, ruwwb, wuw, wwgg, wwbbu, gggb, rgrruwrw, uugr, rwb, rggw, gbr, guuurru, wurubggw, gww, wuugb, rbbww, urwgb, wrruurr, guuurgg, bwbgbg, bubwb, ggrwwg, gugr, uwrrr, guurbu, uruw, gbguruu, grb, bwr, wrubggr, rbu, wgwgru, buuww, gub, wu, uw, rrbrb, ur, wrgbb, gbbu, wgw, ggwbgwb, wb, urwr, uggwbwu, wwwg, rbru, bwbw, brb, wbugw, r, gbb, rw, bru, wbbwbr, gwww, wgrr, rugg, bgrbrub, w, gwwb, wrwgu, wwgb, uwgbgwwb, wrrwb, ubw, rr, gbbuug, bbr, wugb, rbuww, uur, wgur, ugg, wwu, wwrww, uuwur, rwbbww, gbu, bgbuur, rrbugguw, ugrgwg, wurruu, rrrgww, ggbbgbb, bgbb, brrb, rwwr, brwwr, ubrbru, uburwwb, ggwu, rwbgrbu, bbwuwbr, urwggbwr, bbrgu, wbbuww, rbwwuwr, gu, brbb, wbwgu, ugbrrguw, urbu, gbgbbrub, gbuuuww, rww, gwwgwwg, buwu, bur, uubrw, rur, rgurr, rwbgrg, urr, wugw, wuur, wuub, wbgb, bgb, uubrbur, rrbugbu, ugru, guwr, uwu, uru, wbw, wugrwgb, ggwg, guw, ubbbg, grbuwg, gw, wgb, bbrbwgub, gr, rbruu, urwwu, gbuwbw, bug, rgrgb, uwr, wrw, urb, wgbw, rbbgr, rwww, wbubur, buubw, ruwgwbug, wwwgggub, uuwrwbww, burr, rubg, wgub, bww, urbuubb, bubugrb, rgwbbw, rb, ggu, gwg, rgw, ruwggbg, wrrwbg, gur, wwbgugb, ruu, rrgg, rwrr, uwb, bwbbwbg, rbgg, rwgwg, rrgrwg, gb, bgbg, urubwugb, ruww, grbbg, gwb, bugrr, wgwr, wuug, b, gbwgr, uugw, wwr, wuu, ggr, bbwb, ubbbwrg, wugbw, gguuw, bbw, ugr, wbbrrbu, grbub, ubuwuw, bwgw, bggw, bwu, ub, bwubw, rgru, brg, uruwr, rug, wrwwuubg, brw, wggurb, br, wgr, gug, wrww, gg, uuw, bguwbru, rrrw, uubgb, gbww, buu, rbbuw, bgru, ubbwr, bg, gbgrww, wrg, ugubw, rgrg, bwbbgw, ggubrwbg, uurgwg, gbw, ww, wr, wbgu, bbu, brrwb, wug, uurug, rgb, gwbwbgg, uuubg, ugub, bruw, rub, rgggrr, ruubrwuw, brguru, wbrbg, rrwr, bgrwbbr, ugu, grwbb, rgg, wwg, rgbuwr, wuwur, bbgub, ubg, rrg, wrur, bggbr, wgg, bbwbbru, bwwbrgu, rugrr, rgwbu, ugubwbgu, wwb, ggg, bwwu, gwuguu, rrwgwg, uuwu, rrug, bgwruw, brrgrb, rurg, bugb, grwbg, rwr, urug, rwg, bgg, gbggr, rrr, gbbrw, wgu, bwbg, bbgurggg, wuwguw, wwwuru, grg, grggbw, rubu, burw, grr, bgbbw, wgrbgg, rwrww, gwurgr, bruww, bub, wbu, rbb, uwgbb, rgr, ugb, buubb, wg, wwwgr, bgw, wbwr, wuwruu, wrgrrrw, rbr, wuwwr, wrwb, ggwgwbrw, urw, uwrubb, wuwg, wguu, ugwwuw, ggb, rrggr, wrb, urwgub, bgwwrw, rwu, wurug, gbgu, brrwbb, wwbub, uwrgw, bwb, ubr, uww, gbg, wgrugwbb, bwg, wbb, bbwwgr, www\n\nbgrwwwbuugwrruurrwgbgrbwrrruurgbuwbgbwuuruubwuubruwgubw\nugguwugrwrgwruwguuwurubggwgwbrwwwubburwrburg\nrbbbgwgbbbrrrubguwggubwburbrrwgbbuwgbwwuwrbwugurbbwuubruu\nwuuuwbwuwuwgbugwggwwuwurrgwubbugbbuuubbrwbgbubr\nubbrubwuurgbuwgguubgbrguwbguuwbwruguubwbbgguwrrgwwbubwb\nrbbwuwrrrgwrwwbwgwrruubggrrggbbgwuwbrgubgwwrbwwbggwwrwrwgb\nbgggbruguuguwwwurruwgubrwrruubgbrbwwwgrrgurb\ngubugrguurwgwwubrwguggbgbbuubbubuwurgbgugrubgrgggruugw\ngwrggrbrrrbwwrrggwrwggrwuguubgggrrwwrggubruwrrgbubg\nbgubggrrbuwwwggbwbrbguwuwwbburgururuguwuwgbguuwwwub\nuuggggggurgrgugugrwbrbrwururwurburrurggwgwbrwrwwwuuugwu\nuuubwrurwwrbbgrbrrbuwbrbwrurgrrwwwgugugrbugwu\nwbbbwrgbwrbgggwgbbwbbwrwbbbwwbbwbgbwuwubbrrggurbugwrgwbuug\nuruwrwugbbwruugrguuwrrbbguwwrrrruubrwgwrruug\nbguurwugrrgurubbuwbrgrbwggrrgrwguwgrwubgbubbw\nwwgubbbbgggrgrwwwuwwwbbbbbbrwwwguggrwurgwbguwgwubww\nwgbrwgbbgwuuwbwwuwwrruruwururwbwbguuwgbrgw\nwbrgwrrurwuubrruruwwbgwrgwrbbrwrbbbrwwbwwrgwbr\nggwgwrrwwruubruwgbwwuwrbwbgurubwugbbwurwbwrbuggubwwww\nbuurbrbwrgbgbgwgwbruwubbbgwgguruggrrwwgwgwuruwggrbbbbbugw\nbubgwugwubwwwgrurgurbubwbguurrwbubuubggbgbrbuwgrwbbgbuwr\ngggbbwgugrguguwubrbwbrgwwbubwuwwgbwrbrgbuugwrrb\nbgguuuwwbrubgrubwrwugbbwwrruwrgrrubwwuubgwrwwrgrgbgbg\nw" <> ...}
+
```
+
+
```elixir
+
[towels | patterns] = String.split(puzzle_input, "\n", trim: true)
+
+
towels =
+
towels
+
|> String.split(", ")
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
["rrbb", "rgrb", "rbbwbw", "ruw", "grwb", "wbg", "rrggu", "wugbb", "gwr", "rrgu", "wbbb", "bwrgugb",
+
"rgww", "brrw", "gwwg", "brgbb", "ubbbu", "rbgruw", "bwub", "rru", "grbu", "grw", "bwrbr",
+
"wrwbwu", "bgbr", "urrb", "bbb", "guggb", "gwuwuw", "ubu", "wbr", "bb", "ubwwrb", "bruuwu", "buw",
+
"wrr", "gbgrr", "ggw", "ru", "wub", "uub", "gbrw", "uwrwrb", "uwuu", "wbbu", "gwu", "brrr",
+
"grggur", "wugrbrw", "rwuurgg", ...]
+
```
+
+
```elixir
+
defmodule Towels do
+
def count(target, towels) do
+
possible =
+
towels
+
|> Enum.filter(&String.contains?(target, &1))
+
|> Enum.sort()
+
+
do_count([{target, 1}], possible)
+
end
+
+
defp do_count([], _), do: 0
+
defp do_count([{"", count} | _], _), do: count
+
+
defp do_count([{target, score} | rest], towels) do
+
towels
+
|> Enum.reduce(rest, fn h, acc ->
+
case target do
+
^h <> rest -> insert(acc, {rest, score})
+
_ -> acc
+
end
+
end)
+
|> do_count(towels)
+
end
+
+
defp insert([{longest, _} = top | t], {text, _} = new)
+
when byte_size(text) < byte_size(longest) do
+
[top | insert(t, new)]
+
end
+
+
defp insert([{same, count} | t], {same, add}),
+
do: [{same, count + add} | t]
+
+
defp insert(t, new), do: [new | t]
+
end
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:module, Towels, <<70, 79, 82, 49, 0, 0, 12, ...>>, {:insert, 2}}
+
```
+
+
```elixir
+
ways = Enum.map(patterns, &Towels.count(&1, towels))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
[6620974293119, 0, 35074418436970, 51307147748, 1695253946038, 12806406135744, 4413048272,
+
52744440529, 21533960420, 189633269638, 308662314336, 28930988196, 0, 0, 2335754782, 105920229640,
+
6464319032, 87075196587, 3720984622862, 2177845982468, 5546717284590, 8535586138, 834112091460,
+
6647844832, 21252082644, 5923960105816, 22344301329, 0, 0, 582455705324, 5162034941182,
+
368835846080, 30797645913, 0, 5315701730, 1953742172864, 910841596, 5512526952, 673582370688,
+
2029241325402, 13227054560, 81761616492, 0, 184404641300, 19196318323832, 773246829645,
+
97032877104, 0, 0, 0, ...]
+
```
+
+
## Part 1
+
+
```elixir
+
Enum.count(ways, & &1 > 0)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
306
+
```
+
+
## Part 2
+
+
```elixir
+
Enum.sum(ways)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
604622004681855
+
```
+
+
<!-- livebook:{"offset":7059,"stamp":{"token":"XCP.002DySFes8xjfbs_CVpc_QP75dkQcDFc5l37WdKhIJnRNctYjy9B2s3kTIev5coTlF4OCw1O-s8QuxIAU1HRaVoeZUHdw248FBapl1Ki5EyAYF1LHsn0MfuWbSukOOamT4I","version":2}} -->
+420
2024/day20.livemd
···
+
<!-- livebook:{"persist_outputs":true} -->
+
+
# Day 20
+
+
```elixir
+
Mix.install([:kino_aoc])
+
```
+
+
## Section
+
+
<!-- livebook:{"attrs":"eyJhc3NpZ25fdG8iOiJwdXp6bGVfaW5wdXQiLCJkYXkiOiIyMCIsInNlc3Npb25fc2VjcmV0IjoiQURWRU5UX09GX0NPREVfU0VTU0lPTiIsInllYXIiOiIyMDI0In0","chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2024", "20", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:ok,
+
"#############################################################################################################################################\n#...#...#...#...#.........#.........###...#.....#...#.....#...#.......#...#...###...#...#...###.......#.........#...#...#...#...............#\n#.#.#.#.#.#.#.#.#.#######.#.#######.###.#.#.###.#.#.#.###.#.#.#.#####.#.#.#.#.###.#.#.#.#.#.###.#####.#.#######.#.#.#.#.#.#.#.#############.#\n#.#.#.#.#.#...#.#.....#...#.#.......#...#.#...#.#.#.#...#...#.#.#.....#.#.#.#.#...#...#.#.#...#...#...#.....#...#.#.#.#...#...#.........#...#\n#.#.#.#.#.#####.#####.#.###.#.#######.###.###.#.#.#.###.#####.#.#.#####.#.#.#.#.#######.#.###.###.#.#######.#.###.#.#.#########.#######.#.###\n#.#.#.#.#...#...#...#.#...#.#.#.....#...#...#.#.#.#...#.#.....#.#.###...#.#.#.#.......#.#.#...#...#.....###.#.....#...#...#...#.......#...###\n#.#.#.#.###.#.###.#.#.###.#.#.#.###.###.###.#.#.#.###.#.#.#####.#.###.###.#.#.#######.#.#.#.###.#######.###.###########.#.#.#.#######.#######\n#.#.#.#.#...#...#.#.#.#...#.#.#.#...###...#.#.#.#.#...#.#...#...#...#...#...#.....###.#.#.#...#.....#...#...#.......#...#...#...#.....#.....#\n#.#.#.#.#.#####.#.#.#.#.###.#.#.#.#######.#.#.#.#.#.###.###.#.#####.###.#########.###.#.#.###.#####.#.###.###.#####.#.#########.#.#####.###.#\n#.#.#.#.#.....#.#.#...#.#...#...#.....#...#...#.#.#...#.#...#.....#...#...#.......#...#...#...#.....#...#...#.....#.#.........#...#.....#...#\n#.#.#.#.#####.#.#.#####.#.###########.#.#######.#.###.#.#.#######.###.###.#.#######.#######.###.#######.###.#####.#.#########.#####.#####.###\n#.#...#.....#.#.#.#.....#...#.....#...#...#.....#...#.#.#...#...#...#.#...#.......#.......#...#.......#.....#.....#...........#...#.....#...#\n#.#########.#.#.#.#.#######.#.###.#.#####.#.#######.#.#.###.#.#.###.#.#.#########.#######.###.#######.#######.#################.#.#####.###.#\n#.#...#...#...#...#...#####.#...#...#####.#.###...#.#.#.#...#.#.....#...#...#.....###...#.#...#...###...#...#.#...#...#.....###.#.###...#...#\n#.#.#.#.#.###########.#####.###.#########.#.###.#.#.#.#.#.###.###########.#.#.#######.#.#.#.###.#.#####.#.#.#.#.#.#.#.#.###.###.#.###.###.###\n#...#...#...#.......#...#...#...#...###...#...#.#.#.#.#.#.###.......#.....#...#...#...#.#.#.###.#.#...#.#.#.#...#...#...#...#...#...#...#...#\n###########.#.#####.###.#.###.###.#.###.#####.#.#.#.#.#.#.#########.#.#########.#.#.###.#.#.###.#.#.#.#.#.#.#############.###.#####.###.###.#\n#...###...#...#...#...#...#...#...#.#...#...#.#.#.#.#...#...###...#.#.....#.....#.#...#...#.#...#.#.#.#.#.#...#...........#...#.....#...#...#\n#.#.###.#.#####.#.###.#####.###.###.#.###.#.#.#.#.#.#######.###.#.#.#####.#.#####.###.#####.#.###.#.#.#.#.###.#.###########.###.#####.###.###\n#.#.#...#.....#.#...#.....#...#.#...#...#.#...#.#...#.......#...#.#.#.....#.....#.###.....#.#...#.#.#.#...#...#...........#...#.....#.#...###\n#.#.#.#######.#.###.#####.###.#.#.#####.#.#####.#####.#######.###.#.#.#########.#.#######.#.###.#.#.#.#####.#############.###.#####.#.#.#####\n#.#...#.....#.#.#...#...#...#...#.#...#.#...#...#.....#.....#...#.#.#.......#...#...#...#.#.....#.#.#.#.....#.............#...#.....#.#.#...#\n#.#####.###.#.#.#.###.#.###.#####.#.#.#.###.#.###.#####.###.###.#.#.#######.#.#####.#.#.#.#######.#.#.#.#####.#############.###.#####.#.#.#.#\n#.#...#.#...#...#.....#.....#.....#.#.#.#...#...#.#...#...#.....#.#.#.....#.#.....#...#.#...#.....#.#.#.....#.#...###...###.#...#...#.#.#.#.#\n#.#.#.#.#.###################.#####.#.#.#.#####.#.#.#.###.#######.#.#.###.#.#####.#####.###.#.#####.#.#####.#.#.#.###.#.###.#.###.#.#.#.#.#.#\n#.#.#...#.................#...#...#.#.#.#.#.....#.#.#.###.......#.#.#...#...#...#...#...#...#.#.....#.#...#.#.#.#.....#.....#.....#...#...#.#\n#.#.#####################.#.###.#.#.#.#.#.#.#####.#.#.#########.#.#.###.#####.#.###.#.###.###.#.#####.#.#.#.#.#.###########################.#\n#.#.....#.................#.###.#.#.#.#.#.#...#...#.#...#...#...#.#.#...#...#.#.#...#...#...#.#...#...#.#.#.#.#.#.....#.......#.....#...#...#\n#.#####.#.#################.###.#.#.#.#.#.###.#.###.###.#.#.#.###.#.#.###.#.#.#.#.#####.###.#.###.#.###.#.#.#.#.#.###.#." <> ...}
+
```
+
+
```elixir
+
#puzzle_input =
+
"""
+
###############
+
#...#...#.....#
+
#.#.#.#.#.###.#
+
#S#...#.#.#...#
+
#######.#.#.###
+
#######.#.#...#
+
#######.#.###.#
+
###..E#...#...#
+
###.#######.###
+
#...###...#...#
+
#.#####.#.###.#
+
#.#...#.#.#...#
+
#.#.#.#.#.#.###
+
#...#...#...###
+
###############
+
"""
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
warning: outdented heredoc line. The contents inside the heredoc should be indented at the same level as the closing """. The following is forbidden:
+
+
def text do
+
"""
+
contents
+
"""
+
end
+
+
Instead make sure the contents are indented as much as the heredoc closing:
+
+
def text do
+
"""
+
contents
+
"""
+
end
+
+
The current heredoc line is indented too little
+
โ””โ”€ Workspace/hauleth/advent-of-code/2024/day20.livemd#cell:iyjl3w4kz3srtwoq:3:3
+
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
"###############\n#...#...#.....#\n#.#.#.#.#.###.#\n#S#...#.#.#...#\n#######.#.#.###\n#######.#.#...#\n#######.#.###.#\n###..E#...#...#\n###.#######.###\n#...###...#...#\n#.#####.#.###.#\n#.#...#.#.#...#\n#.#.#.#.#.#.###\n#...#...#...###\n###############\n"
+
```
+
+
```elixir
+
map =
+
puzzle_input
+
|> String.split("\n")
+
|> Enum.with_index()
+
|> Enum.flat_map(fn {row, y} ->
+
row
+
|> String.split("", trim: true)
+
|> Enum.with_index()
+
|> Enum.map(fn {c, x} ->
+
{{x, y}, c}
+
end)
+
end)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
[
+
{{0, 0}, "#"},
+
{{1, 0}, "#"},
+
{{2, 0}, "#"},
+
{{3, 0}, "#"},
+
{{4, 0}, "#"},
+
{{5, 0}, "#"},
+
{{6, 0}, "#"},
+
{{7, 0}, "#"},
+
{{8, 0}, "#"},
+
{{9, 0}, "#"},
+
{{10, 0}, "#"},
+
{{11, 0}, "#"},
+
{{12, 0}, "#"},
+
{{13, 0}, "#"},
+
{{14, 0}, "#"},
+
{{15, 0}, "#"},
+
{{16, 0}, "#"},
+
{{17, 0}, "#"},
+
{{18, 0}, "#"},
+
{{19, 0}, "#"},
+
{{20, 0}, "#"},
+
{{21, 0}, "#"},
+
{{22, 0}, "#"},
+
{{23, 0}, "#"},
+
{{24, 0}, "#"},
+
{{25, 0}, "#"},
+
{{26, 0}, "#"},
+
{{27, 0}, "#"},
+
{{28, 0}, "#"},
+
{{29, 0}, "#"},
+
{{30, 0}, "#"},
+
{{31, 0}, "#"},
+
{{32, 0}, "#"},
+
{{33, 0}, "#"},
+
{{34, 0}, "#"},
+
{{35, 0}, "#"},
+
{{36, 0}, "#"},
+
{{37, 0}, "#"},
+
{{38, 0}, "#"},
+
{{39, 0}, "#"},
+
{{40, 0}, "#"},
+
{{41, 0}, "#"},
+
{{42, 0}, "#"},
+
{{43, 0}, "#"},
+
{{44, 0}, "#"},
+
{{45, 0}, "#"},
+
{{46, 0}, "#"},
+
{{47, ...}, "#"},
+
{{...}, ...},
+
{...},
+
...
+
]
+
```
+
+
```elixir
+
%{"#" => walls, "." => road, "S" => [start], "E" => [finish]} =
+
Enum.group_by(map, &elem(&1, 1), &elem(&1, 0))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
%{
+
"#" => [
+
{0, 0},
+
{1, 0},
+
{2, 0},
+
{3, 0},
+
{4, 0},
+
{5, 0},
+
{6, 0},
+
{7, 0},
+
{8, 0},
+
{9, 0},
+
{10, 0},
+
{11, 0},
+
{12, 0},
+
{13, 0},
+
{14, 0},
+
{15, 0},
+
{16, 0},
+
{17, 0},
+
{18, 0},
+
{19, 0},
+
{20, 0},
+
{21, 0},
+
{22, 0},
+
{23, 0},
+
{24, 0},
+
{25, 0},
+
{26, 0},
+
{27, 0},
+
{28, 0},
+
{29, 0},
+
{30, 0},
+
{31, 0},
+
{32, 0},
+
{33, 0},
+
{34, 0},
+
{35, 0},
+
{36, 0},
+
{37, 0},
+
{38, 0},
+
{39, 0},
+
{40, 0},
+
{41, 0},
+
{42, 0},
+
{43, 0},
+
{44, 0},
+
{45, 0},
+
{46, 0},
+
{47, ...},
+
{...},
+
...
+
],
+
"." => [
+
{1, 1},
+
{2, 1},
+
{3, 1},
+
{5, 1},
+
{6, 1},
+
{7, 1},
+
{9, 1},
+
{10, 1},
+
{11, 1},
+
{13, 1},
+
{14, 1},
+
{15, 1},
+
{17, 1},
+
{18, 1},
+
{19, 1},
+
{20, 1},
+
{21, 1},
+
{22, 1},
+
{23, 1},
+
{24, 1},
+
{25, 1},
+
{27, 1},
+
{28, 1},
+
{29, 1},
+
{30, 1},
+
{31, 1},
+
{32, 1},
+
{33, 1},
+
{34, 1},
+
{35, 1},
+
{39, 1},
+
{40, 1},
+
{41, 1},
+
{43, 1},
+
{44, 1},
+
{45, 1},
+
{46, 1},
+
{47, 1},
+
{49, 1},
+
{50, 1},
+
{51, 1},
+
{53, 1},
+
{54, 1},
+
{55, 1},
+
{56, 1},
+
{57, 1},
+
{59, ...},
+
{...},
+
...
+
],
+
"E" => [{27, 59}],
+
"S" => [{49, 53}]
+
}
+
```
+
+
```elixir
+
defmodule Race do
+
def distances(start, finish, walls) do
+
do_distances(start, finish, 0, MapSet.new(walls), %{})
+
end
+
+
defp do_distances(finish, finish, n, _, acc),
+
do: Map.put(acc, finish, n)
+
+
defp do_distances(current, finish, n, walls, acc) do
+
acc = Map.put(acc, current, n)
+
+
current
+
|> neigh()
+
|> Enum.reject(&(&1 in walls or Map.has_key?(acc, &1)))
+
|> hd()
+
|> do_distances(finish, n + 1, walls, acc)
+
end
+
+
def neigh({x, y}, d \\ 1) do
+
for {dx, dy} <- [{0, d}, {0, -d}, {d, 0}, {-d, 0}], do: {x + dx, y + dy}
+
end
+
+
def neighbours({x, y}, r \\ 1) do
+
for dx <- -r..r,
+
dy <- -r..r,
+
{dx, dy} != {0, 0},
+
d = abs(dx) + abs(dy),
+
d <= r,
+
do: {x + dx, y + dy}
+
end
+
+
def d({xa, ya}, {xb, yb}) do
+
abs(xa - xb) + abs(ya - yb)
+
end
+
end
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:module, Race, <<70, 79, 82, 49, 0, 0, 17, ...>>, {:d, 2}}
+
```
+
+
```elixir
+
steps = Race.distances(start, finish, walls)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
%{
+
{18, 103} => 8261,
+
{61, 121} => 7060,
+
{65, 63} => 2098,
+
{77, 129} => 6964,
+
{1, 26} => 695,
+
{116, 69} => 4441,
+
{83, 76} => 4281,
+
{117, 125} => 5656,
+
{103, 106} => 5785,
+
{30, 113} => 8041,
+
{89, 14} => 2511,
+
{35, 30} => 1133,
+
{37, 53} => 32,
+
{11, 39} => 384,
+
{131, 5} => 2998,
+
{65, 43} => 1754,
+
{139, 46} => 3615,
+
{12, 135} => 7871,
+
{65, 131} => 7046,
+
{49, 117} => 7412,
+
{29, 25} => 1108,
+
{83, 36} => 2319,
+
{47, 27} => 1556,
+
{4, 81} => 8645,
+
{13, 124} => 8295,
+
{121, 77} => 4608,
+
{103, 39} => 3756,
+
{119, 60} => 4389,
+
{13, 85} => 8604,
+
{63, 81} => 6682,
+
{111, 108} => 5755,
+
{111, 103} => 5764,
+
{15, 92} => 8587,
+
{1, 101} => 8500,
+
{20, 3} => 939,
+
{61, 95} => 6878,
+
{23, 67} => 9208,
+
{78, 75} => 6545,
+
{79, 17} => 2358,
+
{17, 137} => 7852,
+
{124, 93} => 4933,
+
{138, 9} => 3283,
+
{58, 33} => 1667,
+
{67, 105} => 6818,
+
{47, 44} => 1195,
+
{122, 137} => 5595,
+
{13, 55} => 154,
+
{97, 138} => 6129,
+
{75, ...} => 2165,
+
{...} => 1616,
+
...
+
}
+
```
+
+
## Part 1
+
+
```elixir
+
Enum.reduce(steps, 0, fn {pos, start}, acc ->
+
count =
+
steps
+
|> Map.take(Race.neighbours(pos, 2))
+
|> Enum.count(fn {last, finish} ->
+
finish - start - Race.d(pos, last) >= 100
+
end)
+
+
count + acc
+
end)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
1393
+
```
+
+
## Part 2
+
+
We can notice that we are looking for shortcuts in circle of radius $r$ defined in Taxicab metric ($d(a, b) = \sum_{i} |a_i - b_i|$). That makes code pretty simple and allows us to reuse ideas from Part 1.
+
+
```elixir
+
steps
+
|> Task.async_stream(
+
fn {pos, start} ->
+
steps
+
|> Map.take(Race.neighbours(pos, 20))
+
|> Enum.count(fn {last, finish} ->
+
finish - start - Race.d(pos, last) >= 100
+
end)
+
end,
+
ordered: false
+
)
+
|> Enum.reduce(0, fn {:ok, count}, acc ->
+
count + acc
+
end)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
990096
+
```
+
+
<!-- livebook:{"offset":11400,"stamp":{"token":"XCP.ONwDp6zRpWXsXASH95Q0puANk15Li1hG2FDCrv6Gqu42Q7k9pb_Te_6RDoUE0dp3yYbG7jry8-6iHGJvcZtsDFstlznyVHk9HVhXRZiC2uQczaOfF4K8HQL9QuzNguTht7A","version":2}} -->
+182
2024/day21.livemd
···
+
<!-- livebook:{"persist_outputs":true} -->
+
+
# Day 21
+
+
```elixir
+
Mix.install([:kino_aoc])
+
```
+
+
## Section
+
+
<!-- livebook:{"attrs":"eyJhc3NpZ25fdG8iOiJwdXp6bGVfaW5wdXQiLCJkYXkiOiIyMSIsInNlc3Npb25fc2VjcmV0IjoiQURWRU5UX09GX0NPREVfU0VTU0lPTiIsInllYXIiOiIyMDI0In0","chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2024", "21", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:ok, "638A\n965A\n780A\n803A\n246A"}
+
```
+
+
```elixir
+
codes =
+
puzzle_input
+
|> String.split("\n", trim: true)
+
|> Enum.map(fn <<num::3-binary>> <> "A" = code ->
+
{String.to_charlist(code), String.to_integer(num)}
+
end)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
[{~c"638A", 638}, {~c"965A", 965}, {~c"780A", 780}, {~c"803A", 803}, {~c"246A", 246}]
+
```
+
+
```elixir
+
dirpad = %{
+
[?A, ?>] => ~c[vA],
+
[?A, ?^] => ~c[<A],
+
[?A, ?v] => ~c[<vA],
+
[?A, ?<] => ~c[v<<A],
+
+
[?>, ?A] => ~c[^A],
+
[?>, ?^] => ~c[<^A],
+
[?>, ?v] => ~c[<A],
+
[?>, ?<] => ~c[<<A],
+
+
[?^, ?A] => ~c[>A],
+
[?^, ?>] => ~c[v>A],
+
[?^, ?v] => ~c[vA],
+
[?^, ?<] => ~c[v<A],
+
+
[?<, ?A] => ~c[>>^A],
+
[?<, ?^] => ~c[>^A],
+
[?<, ?v] => ~c[>A],
+
[?<, ?>] => ~c[>>A],
+
+
[?v, ?A] => ~c[>^A],
+
[?v, ?^] => ~c[^A],
+
[?v, ?<] => ~c[<A],
+
[?v, ?>] => ~c[>A]
+
}
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
%{
+
~c"<>" => ~c">>A",
+
~c"<A" => ~c">>^A",
+
~c"<^" => ~c">^A",
+
~c"<v" => ~c">A",
+
~c"><" => ~c"<<A",
+
~c">A" => ~c"^A",
+
~c">^" => ~c"<^A",
+
~c">v" => ~c"<A",
+
~c"A<" => ~c"v<<A",
+
~c"A>" => ~c"vA",
+
~c"A^" => ~c"<A",
+
~c"Av" => ~c"<vA",
+
~c"^<" => ~c"v<A",
+
~c"^>" => ~c"v>A",
+
~c"^A" => ~c">A",
+
~c"^v" => ~c"vA",
+
~c"v<" => ~c"<A",
+
~c"v>" => ~c">A",
+
~c"vA" => ~c">^A",
+
~c"v^" => ~c"^A"
+
}
+
```
+
+
```elixir
+
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
nil
+
```
+
+
```elixir
+
defmodule Keypad do
+
def naive(input, lut) do
+
[?A | input]
+
|> Enum.chunk_every(2, 1, :discard)
+
|> Enum.flat_map(&Map.get(lut, &1, [?A]))
+
end
+
+
def expand(input, lut) do
+
Stream.concat([?A], input)
+
|> Stream.chunk_every(2, 1, :discard)
+
|> Stream.flat_map(&Map.get(lut, &1, [?A]))
+
end
+
end
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:module, Keypad, <<70, 79, 82, 49, 0, 0, 9, ...>>, {:expand, 2}}
+
```
+
+
```elixir
+
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
nil
+
```
+
+
```elixir
+
Keypad.expand(~c[<A^A>^^AvvvA], dirpad)
+
|> Enum.count()
+
+
#|> Enum.map(fn {k, v} ->
+
# [?A | Map.get(dirpad, k, [?A])]
+
# |> Enum.chunk_every(2, 1, :discard)
+
# |> Enum.map()
+
#end)
+
#|> Enum.group_by(&elem(&1, 0), &elem(&1, 1))
+
#|> Map.new(fn {k, v} -> {k, Enum.sum(v)} end)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
28
+
```
+
+
```elixir
+
Keypad.naive(~c[<A^A>^^AvvvA], dirpad)
+
|> Keypad.naive(dirpad)
+
|> Enum.chunk_every(2, 1, [?A])
+
|> Enum.frequencies()
+
|> Map.values()
+
|> Enum.sum()
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
68
+
```
+
+
```elixir
+
~c"<vA<AA>>^AvAA<^A>Av<<A>>^AvA^A<vA>^Av<<A>^A>AAvA^Av<<A>A>^AAAvA<^A>A"
+
~c"<vA<AA>>^AvAA<^A>A<v<A>>^AvA^A<vA>^A<v<A>^A>AAvA^A<v<A>A>^AAAvA<^A>A" |> length
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
68
+
```
+
+
<!-- livebook:{"offset":3144,"stamp":{"token":"XCP.rEBKR0PbENlE02mf_Mo6R3RTWsHU-tFuA9VTPd907vq3-8e37LytxC6qWBmZAHZHLc_e1t3ZaG85X5KBWsYq0WGEzo7HC0U9-oE0dpPKGKeF7oBGgFeiEoDsX6GDKTwp76o","version":2}} -->
+198
2024/day22.livemd
···
+
<!-- livebook:{"persist_outputs":true} -->
+
+
# Day 22
+
+
```elixir
+
Mix.install([:kino_aoc])
+
```
+
+
## Section
+
+
<!-- livebook:{"attrs":"eyJhc3NpZ25fdG8iOiJwdXp6bGVfaW5wdXQiLCJkYXkiOiIyMiIsInNlc3Npb25fc2VjcmV0IjoiQURWRU5UX09GX0NPREVfU0VTU0lPTiIsInllYXIiOiIyMDI0In0","chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2024", "22", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:ok,
+
"4832674\n14802956\n7210529\n7709095\n6063251\n12294789\n15666951\n12074106\n15427686\n1214891\n15165649\n3609602\n10200989\n16451437\n10915511\n3479515\n173864\n1238342\n3381843\n14767788\n16088065\n15637051\n15981887\n15854806\n4988920\n7980791\n11263142\n8044640\n4572291\n328777\n11851557\n13706949\n16451719\n15991644\n14668984\n8852039\n1685443\n13814197\n14117797\n6281998\n12395020\n1681090\n16476099\n2171296\n10155667\n15490827\n6723206\n7272972\n1788575\n2950054\n10917267\n6862495\n8153949\n16559239\n8572595\n1821668\n3417901\n11375457\n3878450\n10863466\n10890116\n13055126\n7451580\n5815531\n8335506\n431487\n201975\n5841753\n11744013\n4498615\n9261071\n9953929\n4630027\n2227105\n6260342\n10375281\n3015284\n3789175\n15843612\n14432075\n14847622\n11501912\n9079366\n2550341\n6931972\n13371306\n9601571\n14504463\n6162939\n5361897\n14900517\n12748562\n7519640\n14694035\n5566950\n7688680\n13810532\n5654369\n10957671\n6886767\n13114128\n9355299\n14808826\n11001280\n4983663\n9915373\n3356476\n16519750\n15826279\n11122172\n12902904\n1010762\n16214923\n9519057\n15931832\n15664252\n12750269\n1110882\n7854151\n3509827\n10328167\n1494530\n8712493\n396534\n15995697\n7396815\n3419574\n14789278\n14099072\n15389372\n6910648\n649063\n3609071\n6004556\n5054128\n13730203\n3554012\n2766085\n7133343\n7566747\n1194302\n10446649\n1529903\n9036124\n11725198\n6479244\n10287711\n2219155\n2360315\n8169407\n7841353\n7486466\n15297309\n9336789\n7225072\n6248515\n16154198\n11100038\n8584563\n3753173\n7371112\n2481160\n10954049\n8009781\n7381801\n280810\n11001420\n14114713\n4242475\n1237360\n6496866\n15267044\n1880781\n8798544\n5033766\n5079684\n11633848\n16509688\n8226900\n15858455\n16041151\n5334220\n15421957\n2633967\n8343560\n14729378\n9702409\n5482505\n2041087\n9712582\n3430735\n10644043\n9195957\n1784419\n14046333\n2031279\n12766582\n12165573\n14207224\n14929506\n11436548\n13623882\n12370036\n7592923\n228169\n8988171\n6688080\n5492092\n8212636\n3736928\n15352784\n2612376\n14843761\n12308540\n8404032\n11632730\n4404470\n2599992\n6807809\n12044159\n9795957\n5307557\n13144362\n13941181\n9362743\n4957570\n9950852\n4069207\n699043\n13667685\n12869414\n5834836\n8434557\n13512362\n5446646\n16663243\n10059682\n231185\n14405863\n10532295\n13752653\n3266523\n12926376\n9013886\n15683001\n10524950\n325867\n15226063\n15175724\n15991383\n13961546\n15823957\n9310375\n5534565\n2674761\n13444598\n9915920\n1755544\n1429896\n14788650\n5453166\n10081466\n2149840\n16613385\n2519989\n7555351\n7295534\n12099546\n3223009\n2684428\n8436395\n5406395\n836225\n9962036\n2847179\n12880336\n13215841\n3498334\n5985622\n7700379\n5785351\n9938722\n15810882\n2349820\n906893\n2513825\n10432278\n13789913\n2913486\n9683268\n2862417\n4807276\n16264545\n6607564\n10222512\n2190055\n11839341\n2132714\n153996\n10874457\n12023939\n7748310\n13452955\n3246986\n2892967\n9561561\n3280827\n991231\n13105708\n16641479\n273523\n4832864\n13832855\n7903624\n13242917\n13379831\n9085055\n1473661\n11031255\n4126827\n12754058\n456062\n14316218\n6580848\n11147440\n1828704\n15262845\n557484\n2406569\n10393027\n3363996\n15821838\n16365523\n5566374\n3723957\n5186897\n501767\n10639559\n3256585\n2354615\n1888438\n11574106\n11798800\n12629659\n6316600\n3119025\n14801938\n7025953\n14949782\n7577552\n14785389\n8868837\n11642113\n14574465\n8689963\n16223594\n14705685\n16363438\n1393194\n5961465\n16603208\n8121071\n15143692\n7531645\n6777163\n8168251\n15905711\n2373414\n1269213\n2506356\n1080789\n2154403\n11578189\n6232867\n10065427\n15116084\n15449140\n12675436\n14126594\n8470014\n2106625\n12556109\n12771090\n1437370\n16145074\n6244539\n6832665\n13217078\n5152936\n15205635\n12092447\n15115231\n2112929\n13215959\n11124896\n14598714\n15256810\n9994507\n11687859\n11599901\n5330801\n13829820\n1720133\n11040068\n4351948\n9597919\n10673331\n6148104\n12360792\n9687192\n11668420\n10272257\n7823976\n6113203\n8827921\n5600165\n6950138\n9581746\n15917691\n6453798\n11788226\n15057269\n9639028\n5073513\n15459362\n14118507\n7979569\n4210224\n5726357\n10649449\n14645020\n3062620\n14613306\n13963982\n14770179\n15097265\n1789308\n12405157\n7360698\n6983540\n9752726\n8200080\n5784060\n13456865\n4677699\n3783161\n13650051\n9865655\n13066800\n1868022\n5855823\n15061710\n11742417\n2116233\n15002417\n904747\n9455335\n5203086\n704685\n902384\n15284593\n8328120\n13587250\n11550241\n10950646\n14876694\n11393724\n14576237\n898540\n8874901\n5548732\n11351523\n2315166\n9532824\n11462685\n1297628\n3862586\n16331382\n9291789\n2887008\n2582973\n4861709\n15301133\n8978897\n533818\n1565155\n3829639\n8438476\n11901529" <> ...}
+
```
+
+
```elixir
+
inits =
+
puzzle_input
+
|> String.split("\n", trim: true)
+
|> Enum.map(&String.to_integer/1)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
[4832674, 14802956, 7210529, 7709095, 6063251, 12294789, 15666951, 12074106, 15427686, 1214891,
+
15165649, 3609602, 10200989, 16451437, 10915511, 3479515, 173864, 1238342, 3381843, 14767788,
+
16088065, 15637051, 15981887, 15854806, 4988920, 7980791, 11263142, 8044640, 4572291, 328777,
+
11851557, 13706949, 16451719, 15991644, 14668984, 8852039, 1685443, 13814197, 14117797, 6281998,
+
12395020, 1681090, 16476099, 2171296, 10155667, 15490827, 6723206, 7272972, 1788575, 2950054, ...]
+
```
+
+
```elixir
+
defmodule Buyer do
+
def hash(number, rounds \\ 2000) do
+
Enum.map_reduce(1..rounds//1, number, fn _, acc ->
+
r = do_round(acc)
+
{rem(r, 10), r}
+
end)
+
end
+
+
defp do_round(num) do
+
num = subround(num, num * 64)
+
num = subround(num, div(num, 32))
+
subround(num, num * 2048)
+
end
+
+
defp subround(a, b), do: rem(Bitwise.bxor(a, b), 16_777_216)
+
+
def sequences(prices) do
+
prices
+
|> Enum.chunk_every(5, 1, :discard)
+
|> Enum.reduce(%{}, fn seq, map ->
+
Map.put_new(map, diffs(seq), List.last(seq))
+
end)
+
end
+
+
defp diffs(vals) do
+
vals
+
|> Enum.chunk_every(2, 1, :discard)
+
|> Enum.map(fn [a, b] -> b - a end)
+
|> Integer.undigits(256)
+
end
+
end
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:module, Buyer, <<70, 79, 82, 49, 0, 0, 13, ...>>, {:diffs, 1}}
+
```
+
+
```elixir
+
hashes = Enum.map(inits, &Buyer.hash(&1))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
[
+
{[5, 9, 7, 9, 4, 6, 2, 9, 4, 3, 6, 5, 0, 6, 5, 7, 2, 7, 9, 7, 0, 2, 5, 8, 8, 2, 0, 8, 4, 8, 3, 1,
+
4, 3, 3, 8, 0, 5, 2, 1, 2, 8, 6, 2, 2, 3, 6, 9, ...], 8186085},
+
{[8, 6, 8, 8, 3, 4, 6, 9, 0, 1, 1, 5, 4, 9, 5, 4, 1, 2, 5, 2, 6, 7, 8, 7, 5, 4, 4, 2, 5, 6, 4, 6,
+
2, 4, 5, 9, 5, 8, 5, 0, 6, 9, 3, 2, 3, 4, 4, ...], 16060909},
+
{[6, 0, 5, 8, 8, 7, 3, 6, 0, 9, 1, 0, 7, 2, 7, 5, 6, 4, 0, 5, 4, 0, 1, 9, 6, 5, 7, 1, 7, 9, 9, 9,
+
5, 6, 0, 7, 3, 0, 9, 4, 8, 4, 0, 2, 2, 7, ...], 3581487},
+
{[6, 3, 1, 0, 2, 6, 8, 9, 1, 6, 7, 4, 5, 0, 9, 9, 8, 9, 1, 0, 6, 4, 9, 0, 1, 0, 9, 3, 0, 0, 9, 1,
+
9, 6, 6, 7, 2, 1, 7, 2, 7, 3, 2, 7, 3, ...], 14331752},
+
{[3, 5, 1, 7, 1, 4, 6, 0, 4, 9, 8, 3, 7, 3, 3, 2, 2, 9, 1, 3, 3, 4, 9, 2, 3, 2, 5, 6, 9, 4, 3, 8,
+
1, 6, 7, 3, 8, 8, 7, 5, 3, 3, 2, 3, ...], 11096256},
+
{[9, 5, 4, 8, 1, 3, 9, 8, 2, 6, 7, 9, 0, 8, 6, 3, 4, 8, 7, 0, 0, 2, 2, 7, 2, 2, 0, 9, 7, 4, 9, 5,
+
7, 1, 3, 1, 7, 9, 3, 3, 6, 2, 4, ...], 8119288},
+
{[3, 0, 8, 6, 0, 0, 3, 4, 2, 0, 0, 8, 7, 6, 3, 7, 5, 2, 4, 8, 4, 4, 5, 4, 8, 9, 2, 1, 6, 8, 3, 9,
+
2, 8, 0, 5, 0, 9, 7, 2, 5, 9, ...], 4175670},
+
{[9, 6, 3, 2, 9, 6, 8, 1, 7, 8, 0, 7, 2, 2, 0, 8, 6, 5, 5, 3, 9, 6, 5, 7, 1, 4, 6, 7, 9, 7, 2, 4,
+
6, 2, 0, 2, 9, 7, 8, 0, 9, ...], 9128738},
+
{[5, 8, 5, 2, 2, 9, 4, 4, 8, 8, 9, 9, 8, 3, 4, 9, 2, 2, 9, 1, 2, 2, 0, 8, 1, 2, 3, 4, 0, 4, 6, 4,
+
3, 6, 8, 1, 9, 6, 1, 5, ...], 13899897},
+
{[0, 9, 4, 3, 5, 9, 1, 2, 1, 1, 8, 1, 8, 8, 3, 8, 4, 4, 3, 7, 7, 2, 9, 8, 5, 8, 8, 4, 4, 8, 4, 0,
+
5, 9, 7, 0, 3, 3, 6, ...], 12087848},
+
{[5, 6, 7, 3, 2, 0, 5, 4, 8, 8, 2, 6, 8, 4, 9, 7, 2, 0, 9, 3, 4, 1, 3, 0, 6, 5, 2, 6, 4, 6, 9, 4,
+
3, 9, 9, 9, 7, 2, ...], 11514818},
+
{[0, 9, 7, 9, 2, 6, 4, 9, 7, 0, 3, 1, 6, 4, 3, 2, 0, 2, 8, 4, 7, 6, 7, 7, 1, 1, 5, 2, 6, 6, 1, 4,
+
9, 5, 6, 9, 3, ...], 4150418},
+
{[5, 5, 0, 8, 5, 6, 2, 7, 0, 5, 4, 2, 1, 0, 5, 6, 6, 3, 6, 2, 4, 3, 9, 4, 3, 0, 8, 0, 6, 7, 1, 8,
+
0, 2, 7, 1, ...], 2679493},
+
{[4, 0, 8, 1, 5, 9, 0, 3, 6, 0, 2, 8, 5, 7, 1, 1, 9, 1, 5, 1, 5, 0, 7, 3, 5, 5, 4, 3, 9, 4, 3, 9,
+
6, 9, 6, ...], 84072},
+
{[0, 5, 2, 6, 6, 4, 1, 2, 5, 2, 3, 8, 4, 1, 2, 4, 7, 5, 2, 7, 7, 0, 8, 0, 6, 0, 6, 3, 4, 3, 7, 0,
+
5, 8, ...], 3938870},
+
{[5, 5, 5, 5, 6, 0, 6, 9, 2, 0, 0, 5, 3, 0, 3, 3, 0, 7, 7, 0, 1, 5, 8, 8, 6, 5, 3, 3, 2, 5, 8, 8,
+
8, ...], 15186439},
+
{[5, 1, 6, 4, 5, 2, 2, 2, 0, 9, 6, 3, 2, 1, 5, 6, 2, 6, 0, 4, 2, 8, 9, 2, 8, 7, 8, 7, 9, 2, 5, 1,
+
...], 4224277},
+
{[8, 7, 6, 6, 8, 0, 1, 8, 9, 1, 7, 5, 0, 6, 4, 4, 9, 2, 1, 6, 1, 5, 4, 1, 9, 9, 9, 4, 7, 3, 0,
+
...], 6637814},
+
{[7, 4, 4, 8, 3, 9, 5, 6, 1, 1, 7, 4, 7, 2, 5, 3, 8, 5, 3, 4, 7, 7, 0, 0, 4, 1, 7, 1, 4, 5, ...],
+
15335578},
+
{[1, 3, 9, 5, 1, 4, 9, 6, 9, 0, 6, 7, 7, 5, 4, 8, 8, 4, 4, 0, 3, 0, 0, 2, 8, 8, 8, 7, 5, ...],
+
14808063},
+
{[3, 8, 6, 7, 8, 8, 1, 5, 4, 2, 3, 3, 6, 0, 4, 4, 6, 3, 6, 3, 5, 3, 3, 7, 4, 7, 1, 8, ...],
+
2236221},
+
{[4, 2, 4, 3, 0, 3, 6, 2, 7, 9, 6, 6, 9, 3, 2, 0, 1, 8, 1, 5, 7, 7, 3, 8, 8, 1, 9, ...], 9777274},
+
{[8, 5, 1, 6, 9, 9, 1, 6, 3, 9, 9, 4, 5, 9, 4, 2, 8, 5, 7, 9, 2, 1, 6, 9, 0, 9, ...], 14777742},
+
{[4, 6, 0, 4, 6, 3, 2, 3, 8, 0, 2, 3, 2, 2, 0, 7, 7, 4, 5, 8, 8, 2, 8, 9, 4, ...], 3528684},
+
{[3, 6, 3, 3, 3, 2, 5, 2, 8, 8, 8, 0, 3, 1, 2, 2, 6, 2, 3, 1, 2, 6, 1, 9, ...], 15225220},
+
{[2, 1, 2, 4, 0, 6, 0, 8, 6, 5, 9, 5, 1, 7, 1, 3, 9, 3, 2, 8, 5, 4, 8, ...], 4484251},
+
{[1, 5, 9, 2, 0, 5, 7, 4, 6, 2, 3, 4, 7, 9, 9, 7, 9, 8, 3, 4, 2, 3, ...], 12505941},
+
{[3, 2, 8, 0, 7, 6, 7, 8, 6, 2, 0, 4, 7, 6, 2, 8, 2, 7, 3, 0, 3, ...], 12324709},
+
{[3, 6, 3, 2, 2, 5, 4, 5, 3, 2, 2, 8, 5, 8, 7, 6, 5, 9, 3, 0, ...], 12840916},
+
{[7, 4, 1, 3, 5, 7, 1, 9, 4, 8, 2, 0, 2, 6, 7, 1, 7, 8, 4, ...], 13939301},
+
{[0, 4, 4, 4, 6, 9, 8, 0, 2, 3, 9, 9, 4, 0, 6, 0, 4, 2, ...], 7392065},
+
{[7, 8, 0, 0, 4, 1, 6, 1, 5, 9, 0, 3, 1, 4, 5, 8, 9, ...], 13395486},
+
{[5, 5, 1, 7, 9, 8, 0, 1, 5, 5, 6, 2, 1, 6, 6, 5, ...], 14846825},
+
{[4, 1, 5, 9, 7, 1, 3, 6, 6, 5, 8, 9, 1, 0, 7, ...], 15647415},
+
{[5, 0, 0, 5, 4, 4, 9, 3, 4, 0, 4, 9, 0, 0, ...], 15491670},
+
{[5, 3, 1, 3, 6, 7, 3, 2, 8, 6, 2, 5, 0, ...], 12602693},
+
{[9, 6, 3, 2, 6, 3, 9, 6, 6, 5, 2, 6, ...], 16470307},
+
{[8, 4, 3, 6, 0, 4, 0, 8, 5, 5, 9, ...], 10819101},
+
{[0, 9, 4, 4, 6, 0, 2, 4, 0, 3, ...], 8658998},
+
{[0, 2, 8, 3, 0, 4, 5, 0, 5, ...], 11616760},
+
{[4, 8, 3, 5, 2, 8, 0, 8, ...], 4294043},
+
{[8, 1, 0, 8, 2, 1, 0, ...], 11210309},
+
{[5, 8, 6, 9, 6, 8, ...], 1113711},
+
{[1, 6, 5, 5, 4, ...], 16530315},
+
{[5, 1, 3, 9, ...], 8014000},
+
{[7, 4, 5, ...], 13932057},
+
{[8, 9, ...], 9987703},
+
{[4, ...], 10745797},
+
{[...], ...},
+
{...},
+
...
+
]
+
```
+
+
## Part 1
+
+
```elixir
+
hashes
+
|> Enum.map(&elem(&1, 1))
+
|> Enum.sum()
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
13461553007
+
```
+
+
## Part 2
+
+
```elixir
+
hashes
+
|> Task.async_stream(
+
fn {prices, _} -> Buyer.sequences(prices) end,
+
ordered: false
+
)
+
|> Enum.reduce(%{}, fn {:ok, a}, b -> Map.merge(a, b, fn _k, v, k -> v + k end) end)
+
|> Enum.max_by(&elem(&1, 1))
+
|> elem(1)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
1499
+
```
+
+
<!-- livebook:{"offset":11738,"stamp":{"token":"XCP.GjkWCjlMBRZbt2b3Ic6te1lRoiRN-o788mezmoiandQKEk9mR1MC2aSWY6otgof8lHDa_afMMYYnBV9YHmLjoK0wooHF17OPyx6ruqV5hYpKoVBVZuhSx_gT8_2Ac2S73Pk","version":2}} -->
+203
2024/day23.livemd
···
+
<!-- livebook:{"persist_outputs":true} -->
+
+
# Day 23
+
+
```elixir
+
Mix.install([:kino_aoc, {:libgraph, github: "bitwalker/libgraph"}, :combination])
+
```
+
+
## Section
+
+
<!-- livebook:{"attrs":"eyJhc3NpZ25fdG8iOiJwdXp6bGVfaW5wdXQiLCJkYXkiOiIyMyIsInNlc3Npb25fc2VjcmV0IjoiQURWRU5UX09GX0NPREVfU0VTU0lPTiIsInllYXIiOiIyMDI0In0","chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2024", "23", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
{:ok,
+
"on-za\nbp-hs\nvc-bg\ntm-us\nzf-ox\nib-lc\nuo-zs\nov-qj\nll-eb\niy-tq\nbg-by\nun-ix\ngi-do\nrv-ou\nyp-qu\nqb-um\nqs-dn\nru-ro\net-fw\nyx-jt\nns-iz\nod-rc\nny-ap\nvb-fd\nwf-wr\nyh-qy\nfa-ct\nqo-fv\nig-jv\nqi-ff\nnj-ii\nsa-gg\ncp-un\nez-kh\nvs-du\ngp-qs\npt-qj\nyp-my\njf-sz\nyo-gm\nfn-xw\niu-xr\nse-ox\nmw-ie\nfw-br\nxy-iu\nqw-wi\nxc-dq\nvb-cq\ntw-zj\nka-aq\ngo-ds\nvi-cn\npz-kz\npy-nd\npt-ws\nog-lw\nlb-hj\nef-ac\ncv-qa\nsq-jv\nfw-xk\nlu-fc\nbj-bp\nzh-fi\ntg-nm\nsp-at\nke-dh\nut-ly\ngr-vr\nko-qg\nxg-df\nrc-up\nbd-it\ngz-en\nqj-ev\nwf-dx\nxn-hi\npq-th\nkr-gw\ngu-sm\ncv-xr\nzq-fp\nep-kq\nfv-dx\nlc-rw\ney-ef\nek-rw\ntw-eg\nfc-zw\nxm-ho\ngj-oy\nhy-og\nec-tw\npy-hw\nqr-jh\nvh-ea\nvz-ja\nov-ev\nyh-vh\nyk-fc\nfm-yi\nyf-kx\ner-bi\nbi-qq\ngc-fk\nie-gf\njk-fn\nxl-il\nbs-dl\nsh-op\npy-vx\ncn-jl\ntl-ee\nxw-wn\nzv-br\nkr-yn\ndj-wd\nwj-bz\nhf-bg\nzh-ql\nbs-ls\ntq-jk\nmz-dz\nav-jr\ngj-dr\npo-iy\nof-aq\nun-fw\nnv-bx\njz-nl\nze-ae\nvd-df\nix-et\nrn-ik\ndz-ou\nmz-ej\nec-kx\nxr-cf\njt-vr\nix-fw\nes-er\nbv-no\nwj-df\nyv-cl\njd-xl\nlu-vo\nxo-td\nvq-ow\nlc-vm\nca-lf\noq-on\nwj-xg\nfn-rp\nka-np\nbx-ez\ndz-sz\nkt-xl\ndd-jd\nla-qn\nqe-pt\ngl-ly\nqj-cc\nat-rf\nke-om\ndc-hu\nqb-rr\nov-ku\ntq-xw\nfz-tn\nma-hi\nbr-yw\nno-sp\ndj-kn\nyn-gw\ngo-ir\nbz-xg\nwo-se\nrz-wa\nqy-sx\nqn-ym\npo-tq\nxr-jh\ndf-tn\noe-vi\nsw-el\nvm-vr\ntg-nf\ncg-zt\nwf-fl\ncd-nc\nsw-qa\nfo-jg\nhj-av\nwd-rn\nwc-wq\noq-vw\nkx-ux\nop-nq\nsm-ru\nch-fw\nqx-uy\nti-fw\nrp-qm\npo-tj\nse-nw\npj-rs\nbo-sn\nsy-ur\niy-jb\ntm-rz\ndg-jt\nfa-sq\nok-th\nzq-ps\nhr-kr\npz-zs\nwq-ze\nms-an\nnp-aq\ntl-ka\npw-dh\nbm-sz\nuu-gm\nft-vb\nau-ab\nlx-lw\ncp-ri\nep-xm\nry-hk\nyi-gf\ncj-qr\nfl-lu\nbv-za\nyw-xk\nne-ss\nln-wv\nwf-vo\nlx-jy\noy-xy\nkq-fa\neh-lv\nuq-mi\nis-mx\nwn-eo\nqr-xy\nlr-ms\nkt-jd\nyk-lu\nqe-cc\naj-si\nqq-bp\nlw-xa\nus-pp\nen-mq\nct-te\nod-db\ncp-br\nrg-ou\nev-ku\nqg-ec\nuv-np\njn-sw\nxj-ie\nqr-xr\ntr-zp\nha-gg\nrx-pz\nsa-fl\ngx-vz\nmg-oi\nyc-zn\nxw-jo\nae-ou\nhj-gn\nix-ri\nsq-ct\nwo-xr\nbl-wl\ntt-ac\nbs-ij\nmh-re\nhg-lv\nwu-fh\nrt-rq\nsn-vq\nzy-vh\nyh-zy\ntu-oz\nbk-ai\nds-gq\nss-ob\ndv-di\nvw-on\nxr-zb\nfr-jl\nro-om\nrk-mg\nyc-hi\nvv-nf\nkz-nt\nrt-qw\nzj-ux\nox-wv\nfz-dc\nya-xo\ngq-du\nmx-fk\nsi-mo\nmo-ef\ndb-ex\nhw-rc\njy-qd\noz-lb\nvi-cm\nvx-ec\nxr-aa\nnx-ni\nny-fv\nta-vc\nnq-yi\nzt-gp\nnd-iu\nvv-yd\nsh-gf\nyf-hm\ndq-ee\nbg-bt\nnc-kz\ngq-py\nek-sy\nty-le\njo-eo\ndy-ko\nxa-qd\nrm-ns\ngk-xp\ngz-jr\ncr-ez\nwr-fc\nhe-cg\nin-og\ndw-sh\nuk-bf\nbr-un\nok-gi\nch-gr\ncx-gz\ndv-ho\nbx-cr\nex-go\nik-nv\nkh-wb\nol-vk\nhg-bf\nod-du\nvj-qk\nyd-uj\nfu-lq\nbi-bj\nvl-il\ncd-ob\nax-us\nmw-nq\nvr-rw\nhx-uf\nwz-vb\nem-xe\nee-of\nhm-ec\nek-ds\nys-sy\nqq-jq\ngu-jg\nzc-oi\nji-yb\nou-kw\nep-lh\nid-nx\ngp-wp\nph-ns\ncn-io\nwn-tq\nrw-vm\nnx-fv\nce-gn\nvr-lt\nxl-dd\nzw-sa\nwr-ty\nkz-jx\njd-rx\nna-hk\nnc-ob\nnw-re\nwt-jq\naj-sw\nkc-bi\nwq-qx\njt-ib\ncb-ly\nuj-zp\ncy-ps\nsm-om\nbu-bd\nux-ko\nxa-hy\nbc-uq\nsi-sw\nyc-ma\nyk-sa\ngf-mw\nbp-eq\nfh-zh\nmn-bo\nbw-hj\nes-bj\nop-xj\nup-hh\nds-db\ngx-qu\nyo-fp\nwg-ls\net-zc\ndn-vw\nyb-bt\nsk-sb\nxe-ea\nni-ap\nhw-go\ndn-zc\nno-vw\npt-cc\nrv-wc\nwc-xq\njg-ke\noo-jg\ndo-ss\nie-nq\npq-is\nrf-oq\nzn-vb\neb-ef\ngp-rs\npt-pf\nmd-lb\nle-zw\nxn-tf\nui-cb\nbz-fz\npj-gp\nzr-ee\npp-ax\nkl-jq\nxc-of\nox-lr\nuy-rv\nvd-sb\nyy-bh\nvn-dq\ndt-hg\nnp-vn\nla-fh\ngw-eh\ncq-wz\nno-ia\nqj-ws\npl-pt\ndf-ge\nzq-vj\njg-om\nnq-sh\nzy-kr\npv-im\naq-vn\nsq-yx\nsb-df\nih-gx\ngn-av\ndc-ff\nwg-ph\nsm-fo\nux-dk\ngi-kv\nhr-dt\nrc-go\nax-tm\npp-bo\nnn-xe\njf-mz\nvl-jd\nfs-cl\ngz-gn\nui-ly\nrx-hy\nrn-dj\nqe-pf\njx-gy\ntr-qb\neu-lr\nyt-ih\ntr-oi\nnc-ss\nnh-pb\nir-nd\nel-qf\ntl-aq\nkj-es\nru-fo\nfw-bu\nps-qk\nlq-lx\ncm-fg\nel-si\nvs-hw\neg-ux\nmt-lh\ntt-yy\njz-sq\nfm-nq\nvx-ko\nbl-lx\nrc-ex\nby-ji\neq-kl\ntk-vd\nmo-qf\nzr-xd\nbt-vc\nux-mi\nha-us\nvr-ib\nhx-rq\nat-no\nui-tx\nvs-od\nfp-ay\nzj-kx\nvs-ds\nqo-vk\nhw-db\npf-ku\nmd-jr\nfp-fe\nyg-tx\nmz-gs\nnl-ct\ncn-oe\nxj-ri\nya-ku\nnw-mh\nvh-ff\nft-hz\nen-md\nps-fp\naf-rx\nvx-kx\nkv-fd\nkr-lf\nae-rg\nsp-vw\nvn-zr\nea-pi\nat-vw\nrw-ax\nkg-vh\nxy-cv\nca-gw\nem-nn\nhj-en\ngw-ra\nfr-cy\ned-wu\nyf-tw\nuo-lz\ngc-pq\ntw-ux\nqy-kg\ncx-fo\nit-ly\nuj-mg\nrp-po\nsq-yv\nzh-zs\nth-ne\nes-fe\nrn-nv\naa-gj\nzb-aa\nwt-kl\nwu-uo\nbb-ce\nby-bt\nqb-gv\nbp-es\nbd-tx\nma-cq\nyt-qu\nuu-mn\nke-fa\nmx-jn\ndq-ew\nax-ow\nhv-dx\nyh-sx\ngx-ry\njz-jv\nsb-wj\ndo-ok\ngj-qn\nbr-ri\nlu-zw\nsb-ge\nkg-ao\nuu-fp\nus-xh\ndd-jb\nxp-wi\ncf-cj\nhm-zj\nle-sa\nwf-ty\nqx-xq\noi-rr\nbl-og\nmq-hj\ndw-xi\naw-ap\nsk-cs\nwu-yq\ngm-zq\nna-ry\nwp-pj\nne-gy\ndt-yn\nau-bm\nrk-ur\nnm-oi\naf-zm\ncd-ss\ndj-ez\ncf-oy\nce-md\nth-kz\nnt-cd\nrm-iz\njz-fs\nni-qo\njx-do\nzy-xe\nls-uq\nsy-jt\nwa-xh\nlf-lv\nys-jt\nij-wg\njw-mw\nbk-ef\nyx-ek\nvr-cm\njv-sk\ndw-ej\nmo-pq\nov-pl\nfz-ge\nmt-ep\ncq-hz\nza-zc\nlj-uy\nrv-ae\nse-ln\nkw-ze\nwo-ln\nvo-zw\nwd-fd\nxo-pl\nmx-gc\nln-lr\nsy-rw\ngy-fs\nzy-ea\nkc-er\nfl-l" <> ...}
+
```
+
+
```elixir
+
connections =
+
puzzle_input
+
|> String.split("\n", trim: true)
+
|> Enum.map(fn <<a::binary-2, "-", b::binary-2>> ->
+
{a, b}
+
end)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
[
+
{"on", "za"},
+
{"bp", "hs"},
+
{"vc", "bg"},
+
{"tm", "us"},
+
{"zf", "ox"},
+
{"ib", "lc"},
+
{"uo", "zs"},
+
{"ov", "qj"},
+
{"ll", "eb"},
+
{"iy", "tq"},
+
{"bg", "by"},
+
{"un", "ix"},
+
{"gi", "do"},
+
{"rv", "ou"},
+
{"yp", "qu"},
+
{"qb", "um"},
+
{"qs", "dn"},
+
{"ru", "ro"},
+
{"et", "fw"},
+
{"yx", "jt"},
+
{"ns", "iz"},
+
{"od", "rc"},
+
{"ny", "ap"},
+
{"vb", "fd"},
+
{"wf", "wr"},
+
{"yh", "qy"},
+
{"fa", "ct"},
+
{"qo", "fv"},
+
{"ig", "jv"},
+
{"qi", "ff"},
+
{"nj", "ii"},
+
{"sa", "gg"},
+
{"cp", "un"},
+
{"ez", "kh"},
+
{"vs", "du"},
+
{"gp", "qs"},
+
{"pt", "qj"},
+
{"yp", "my"},
+
{"jf", "sz"},
+
{"yo", "gm"},
+
{"fn", "xw"},
+
{"iu", "xr"},
+
{"se", "ox"},
+
{"mw", "ie"},
+
{"fw", "br"},
+
{"xy", "iu"},
+
{"qw", "wi"},
+
{"xc", "dq"},
+
{"vb", ...},
+
{...},
+
...
+
]
+
```
+
+
```elixir
+
party =
+
Graph.new(type: :undirected)
+
|> Graph.add_edges(connections)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
#Graph<type: undirected, num_vertices: 520, num_edges: 3380>
+
```
+
+
```elixir
+
cliques = Graph.cliques(party)
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
[
+
["yf", "dk", "dy", "hm", "vx", "zj", "ec", "eg", "ko", "kx", "tw", "ux"],
+
["yf", "dk", "hm", "vx", "zj", "ec", "eg", "qg", "ko", "kx", "tw", "ux"],
+
["yf", "ob"],
+
["xa", "wl", "lx", "lq", "jy", "in", "hy", "lw", "qd", "fu", "ub", "og"],
+
["xa", "wl", "lx", "jy", "bl", "in", "hy", "lw", "qd", "fu", "ub", "og"],
+
["xa", "wi"],
+
["bd", "cb", "it", "ut", "fq", "hs", "ur", "ly", "tx", "yg", "ui", "gl"],
+
["bd", "cb", "it", "ut", "fq", "ur", "ly", "tx", "yg", "ui", "gl", "rk"],
+
["bd", "bu"],
+
["nm", "qb", "gv", "nf", "oi", "tg", "uj", "yd", "rr", "tr", "vv", "mg"],
+
["nm", "qb", "gv", "nf", "oi", "tg", "uj", "yd", "rr", "tr", "vv", "zp"],
+
["nm", "ge"],
+
["dk", "jn"],
+
["cn", "lh", "di", "xm", "cm", "oe", "vi", "ho", "fg", "mt", "io", "dv"],
+
["cn", "zt"],
+
["cn", "jl"],
+
["qp", "xd"],
+
["qp", "zq", "qk", "uu", "cy", "fp", "ay", "yo", "gm", "vj", "ps", "fr"],
+
["qp", "zq", "qk", "uu", "cy", "ay", "yo", "gm", "vj", "jl", "ps", "fr"],
+
["xq", "qx", "rg", "wc", "um", "rv", "ae", "kw", "lj", "ze", "wq", "ou"],
+
["xq", "kg"],
+
["xq", "qo"],
+
["ti", "et", "bu", "xk", "ix", "fw", "un", "ri", "cp", "br", "gr", "ch"],
+
["ti", "et", "bu", "xk", "fw", "un", "ri", "cp", "br", "gr", "ch", "yw"],
+
["ti", "ab"],
+
["nh", "hv", "id", "ap", "fv", "ny", "pb", "ni", "aw", "nx", "vk", "qo"],
+
["nh", "pj"],
+
["nh", "lk"],
+
["ys", "ib", "dg", "vr", "yx", "jt", "ek", "lt", "sy", "vm", "lc", "rw"],
+
["ys", "ib", "dg", "yx", "jt", "pg", "ek", "lt", "sy", "vm", "lc", "rw"],
+
["ys", "tl"],
+
["cb", "ha"],
+
["ue", "dd", "kd", "zm", "kt", "il", "af", "xx", "vl", "xl", "jd", "rx"],
+
["ue", "dd", "kd", "kt", "il", "af", "xx", "vl", "xl", "jd", "rx", "pz"],
+
["ue", "bh"],
+
["jg", "cx", "fo", "ro", "ru", "oo", "dh", "as", "zx", "ke", "om", "gu"],
+
["jg", "cx", "fo", "ro", "ru", "dh", "as", "sm", "zx", "ke", "om", "gu"],
+
["jg", "cy"],
+
["bz", "fz", "qi", "tn", "xg", "dc", "ge", "sb", "df", "hu", "vd", ...],
+
["bz", "ae"],
+
["bz", "gm"],
+
["im", "dz", "ab", "sz", "ej", "mz", "pv", "rj", ...],
+
["im", "dz", "sz", "ej", "mz", "pv", "rj", ...],
+
["im", "ps"],
+
["sw", "gc", "si", "aj", "is", ...],
+
["sw", "gc", "si", "aj", ...],
+
["sw", "fn"],
+
["cg", "zt", ...],
+
["cg", ...],
+
[...],
+
...
+
]
+
```
+
+
## Part 1
+
+
```elixir
+
cliques
+
|> Stream.flat_map(fn clique ->
+
if length(clique) >= 3 do
+
Combination.combine(clique, 3)
+
else
+
[]
+
end
+
end)
+
|> Stream.filter(fn clique -> Enum.any?(clique, &String.starts_with?(&1, "t")) end)
+
|> MapSet.new()
+
|> MapSet.size()
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
1248
+
```
+
+
## Part 2
+
+
```elixir
+
cliques
+
|> Enum.max_by(&length/1)
+
|> Enum.sort()
+
|> Enum.join(",")
+
```
+
+
<!-- livebook:{"output":true} -->
+
+
```
+
"aa,cf,cj,cv,dr,gj,iu,jh,oy,qr,xr,xy,zb"
+
```
+
+
<!-- livebook:{"offset":9387,"stamp":{"token":"XCP.YMMjV81j86GOTx0hGVW-U0w7aqvuBdig59tmj2pqELbNIP0HXjbZA1WSQwLRMCUIuzZ1PLs6_0ehAVdgp7sj4Wuc6QaM8KCZ3j-zJrTUmr2_hxaACLOnkijsz6m2hIS8E6Q","version":2}} -->
+67
2025/day01.livemd
···
+
# Day 01
+
+
```elixir
+
Mix.install([:kino_aoc])
+
```
+
+
## Setup
+
+
<!-- livebook:{"attrs":"eyJhc3NpZ25fdG8iOiJwdXp6bGVfaW5wdXQiLCJkYXkiOiIxIiwic2Vzc2lvbl9zZWNyZXQiOiJBRFZFTlRfT0ZfQ09ERV9TRVNTSU9OIiwieWVhciI6IjIwMjUifQ","chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2025", "1", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
```elixir
+
instructions =
+
puzzle_input
+
|> String.split("\n", trim: true)
+
|> Enum.map(fn <<dir>> <> rest ->
+
num = String.to_integer(rest)
+
+
if dir == ?R do
+
{div(num, 100), rem(num, 100)}
+
else
+
{div(num, 100), -rem(num, 100)}
+
end
+
end)
+
```
+
+
<!-- livebook:{"branch_parent_index":0} -->
+
+
## Part 1
+
+
```elixir
+
Enum.scan(instructions, 50, fn {_rot, val}, curr ->
+
Integer.mod(curr + val, 100)
+
end)
+
|> Enum.count(& &1 == 0)
+
```
+
+
<!-- livebook:{"branch_parent_index":0} -->
+
+
## Part 2
+
+
```elixir
+
<<0x434C49434B::40>>
+
```
+
+
```elixir
+
Enum.reduce(instructions, {50, 0}, fn {rot, val}, {curr, sum} ->
+
next = curr + val
+
+
pass =
+
cond do
+
curr == 0 and next < 0 -> 0
+
next not in 0..99 -> 1
+
rem(next, 100) == 0 -> 1
+
true -> 0
+
end
+
+
{Integer.mod(next, 100), sum + pass + rot}
+
end)
+
|> elem(1)
+
```
+
+
<!-- livebook:{"offset":1270,"stamp":{"token":"XCP.fAfBqYepop325WQHLC6mJPz_Wpl7bDiz0qRbslvjG31mRJWcHALfstxgj_iOj3nf9_GCzh_WmPiNR4MnzZidF2bz_zMMXHTEo18hp1z3gQDdi5hTSO8UG4YSYnUEtGxO2g","version":2}} -->
+85
2025/day02.livemd
···
+
# Day 02
+
+
```elixir
+
Mix.install([:kino_aoc])
+
```
+
+
## Parsing
+
+
<!-- livebook:{"attrs":"eyJhc3NpZ25fdG8iOiJwdXp6bGVfaW5wdXQiLCJkYXkiOiIyIiwic2Vzc2lvbl9zZWNyZXQiOiJBRFZFTlRfT0ZfQ09ERV9TRVNTSU9OIiwieWVhciI6IjIwMjUifQ","chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2025", "2", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
```elixir
+
ranges =
+
puzzle_input
+
|> String.trim()
+
|> String.split(",")
+
|> Enum.map(fn range ->
+
range
+
|> String.split("-")
+
|> Enum.map(&String.to_integer/1)
+
|> then(&apply(Range, :new, &1))
+
end)
+
|> Enum.sort_by(& &1.last)
+
```
+
+
## Implementation
+
+
```elixir
+
defmodule ElfRanges do
+
def valid?(num) do
+
len = floor(:math.log10(num)) + 1
+
+
valid_n?(num, len, 2)
+
end
+
+
def valid_any?(num) do
+
len = floor(:math.log10(num)) + 1
+
+
Enum.all?(2..len//1, &valid_n?(num, len, &1))
+
end
+
+
def valid_n?(num, len, n) do
+
if rem(len, n) == 0 do
+
step = 10 ** div(len, n)
+
+
Stream.unfold(num, fn
+
0 -> nil
+
val -> {rem(val, step), div(val, step)}
+
end)
+
|> Enum.dedup()
+
|> then(&(not match?([_], &1)))
+
else
+
true
+
end
+
end
+
end
+
```
+
+
<!-- livebook:{"branch_parent_index":1} -->
+
+
## Part 1
+
+
```elixir
+
ranges
+
|> Stream.flat_map(& &1)
+
|> Stream.reject(&ElfRanges.valid?/1)
+
|> Enum.sum()
+
```
+
+
<!-- livebook:{"branch_parent_index":1} -->
+
+
## Part 2
+
+
```elixir
+
ranges
+
|> Stream.flat_map(& &1)
+
|> Stream.reject(&ElfRanges.valid_any?/1)
+
|> Enum.sum()
+
```
+
+
<!-- livebook:{"offset":1551,"stamp":{"token":"XCP.GvC7N5ZC0xuQ3hRuVxd-rh5rJDKVZKJfmwspDkAuCFbjn8qdOUksP9Iy1GRtd7t5yLCV6nkfhXZlp_lTw8eZZBcwItn6IlML-jrjiORJQvkuXOHvzlOY17rIAaASRKvS3w","version":2}} -->
+56
2025/day03.livemd
···
+
# Day 03
+
+
```elixir
+
Mix.install([:kino_aoc])
+
```
+
+
## Parse
+
+
<!-- livebook:{"attrs":"eyJhc3NpZ25fdG8iOiJwdXp6bGVfaW5wdXQiLCJkYXkiOiIzIiwic2Vzc2lvbl9zZWNyZXQiOiJBRFZFTlRfT0ZfQ09ERV9TRVNTSU9OIiwieWVhciI6IjIwMjUifQ","chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2025", "3", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
```elixir
+
batteries =
+
puzzle_input
+
|> String.split("\n", trim: true)
+
|> Enum.map(fn row ->
+
row
+
|> String.to_charlist()
+
|> Enum.map(& &1 - ?0)
+
end)
+
```
+
+
```elixir
+
defmodule Joltage do
+
def make_largest(list, n) do
+
to_remove = length(list) - n
+
Enum.reduce(1..to_remove, list, fn _, acc -> make_larger(acc) end)
+
end
+
+
def make_larger([_]), do: []
+
def make_larger([a, b | rest]) when a < b, do: [b | rest]
+
def make_larger([b | rest]), do: [b | make_larger(rest)]
+
end
+
```
+
+
<!-- livebook:{"branch_parent_index":0} -->
+
+
## Part 1
+
+
```elixir
+
Enum.sum_by(batteries, &Integer.undigits(Joltage.make_largest(&1, 2)))
+
```
+
+
<!-- livebook:{"branch_parent_index":0} -->
+
+
## Part 2
+
+
```elixir
+
Enum.sum_by(batteries, &Integer.undigits(Joltage.make_largest(&1, 12)))
+
```
+
+
<!-- livebook:{"offset":1212,"stamp":{"token":"XCP.fo1ohV8LylIz8VmOAj7rlJ4Jn5KPGtiiFfsDRmp0pFSXCESjhfmQ11wOwEVmq9HM-Zn8fozQDsOoJbfgbM5LJPVE9c0pw2tYKbteOOGNqHI3PTIkuBnv8ZPW6oYwWAZy4A","version":2}} -->
+82
2025/day04.livemd
···
+
# Day 04
+
+
```elixir
+
Mix.install([:kino_aoc])
+
```
+
+
## Parse
+
+
<!-- livebook:{"attrs":"eyJhc3NpZ25fdG8iOiJwdXp6bGVfaW5wdXQiLCJkYXkiOiI0Iiwic2Vzc2lvbl9zZWNyZXQiOiJBRFZFTlRfT0ZfQ09ERV9TRVNTSU9OIiwieWVhciI6IjIwMjUifQ","chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2025", "4", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
```elixir
+
rolls =
+
puzzle_input
+
|> String.split("\n", trim: true)
+
|> Enum.with_index()
+
|> Enum.flat_map(fn {line, row} ->
+
line
+
|> String.to_charlist()
+
|> Enum.with_index()
+
|> Enum.filter(&(elem(&1, 0) == ?@))
+
|> Enum.map(&{elem(&1, 1), row})
+
end)
+
|> MapSet.new()
+
```
+
+
## Implementation
+
+
```elixir
+
defmodule PaperRolls do
+
defp adjacent({x, y}) do
+
for dx <- -1..1,
+
dy <- -1..1,
+
{dx, dy} != {0, 0},
+
do: {x + dx, y + dy}
+
end
+
+
def movable?(pos, map) do
+
pos
+
|> adjacent()
+
|> Enum.count(&(&1 in map))
+
|> then(&(&1 < 4))
+
end
+
end
+
```
+
+
<!-- livebook:{"branch_parent_index":1} -->
+
+
## Part 1
+
+
```elixir
+
Enum.count(rolls, &PaperRolls.movable?(&1, rolls))
+
```
+
+
<!-- livebook:{"branch_parent_index":1} -->
+
+
## Part 2
+
+
```elixir
+
cleaned =
+
Stream.repeatedly(fn -> [] end)
+
|> Enum.reduce_while(rolls, fn _, acc ->
+
removable =
+
Enum.filter(acc, &PaperRolls.movable?(&1, acc))
+
|> MapSet.new()
+
+
case MapSet.difference(acc, removable) do
+
^acc -> {:halt, acc}
+
remaining -> {:cont, remaining}
+
end
+
end)
+
```
+
+
```elixir
+
MapSet.size(rolls) - MapSet.size(cleaned)
+
```
+
+
<!-- livebook:{"offset":1586,"stamp":{"token":"XCP.-_kcJR24r3dthl7SnpOh24JBI5hDpqMlFjQQDQ0pxtv4UHyaTlGoG4rG5iZxKtgxQoNAxw0K-mowSwehidDfrqewK3r9FHoOcAOIDbOMFd3QGH2X2Ta6KeXd4PlzWSYDBw","version":2}} -->
+54
2025/day05.livemd
···
+
# Day 05
+
+
```elixir
+
Mix.install([
+
:kino_aoc,
+
:range_set
+
])
+
```
+
+
## Parse
+
+
<!-- livebook:{"attrs":"eyJhc3NpZ25fdG8iOiJwdXp6bGVfaW5wdXQiLCJkYXkiOiI1Iiwic2Vzc2lvbl9zZWNyZXQiOiJBRFZFTlRfT0ZfQ09ERV9TRVNTSU9OIiwieWVhciI6IjIwMjUifQ","chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2025", "5", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
```elixir
+
[fresh, ingridients] = String.split(puzzle_input, "\n\n")
+
+
fresh =
+
fresh
+
|> String.split()
+
|> Enum.map(fn range ->
+
[a, b] = range |> String.split("-") |> Enum.map(&String.to_integer/1)
+
+
a..b//1
+
end)
+
|> RangeSet.new()
+
+
ingridients =
+
ingridients
+
|> String.split()
+
|> Enum.map(&String.to_integer/1)
+
```
+
+
<!-- livebook:{"branch_parent_index":0} -->
+
+
## Part 1
+
+
```elixir
+
Enum.count(ingridients, & &1 in fresh)
+
```
+
+
<!-- livebook:{"branch_parent_index":0} -->
+
+
## Part 2
+
+
```elixir
+
Enum.count(fresh)
+
```
+
+
<!-- livebook:{"offset":973,"stamp":{"token":"XCP.GHEtbWlG6LHz6I0d5Y_d4738EDILulvQyP1NtPISLeYWo9atG0Ailm43-eswn0JGS5h2z5Yxb8Xi8nGJLqUkj41eqpnT_u7NxVCT4ceeKMBsd5R-EuxBw0P7vLlBab68MA","version":2}} -->
+68
2025/day06.livemd
···
+
# Day 06
+
+
```elixir
+
Mix.install([:kino_aoc])
+
```
+
+
## Setup
+
+
<!-- livebook:{"attrs":"eyJhc3NpZ25fdG8iOiJwdXp6bGVfaW5wdXQiLCJkYXkiOiI2Iiwic2Vzc2lvbl9zZWNyZXQiOiJBRFZFTlRfT0ZfQ09ERV9TRVNTSU9OIiwieWVhciI6IjIwMjUifQ","chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2025", "6", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
```elixir
+
{tasks, [ops]} =
+
puzzle_input
+
|> String.split("\n", trim: true)
+
|> Enum.split(-1)
+
```
+
+
```elixir
+
ops =
+
ops
+
|> String.split()
+
|> Enum.map(&String.to_atom/1)
+
```
+
+
<!-- livebook:{"branch_parent_index":0} -->
+
+
## Part 1
+
+
```elixir
+
tasks
+
|> Enum.map(&String.split/1)
+
|> Enum.zip_with(fn numbers -> Enum.map(numbers, &String.to_integer/1) end)
+
|> Enum.zip(ops)
+
|> Enum.sum_by(fn
+
{nums, :+} -> Enum.sum(nums)
+
{nums, :*} -> Enum.product(nums)
+
end)
+
```
+
+
<!-- livebook:{"branch_parent_index":0} -->
+
+
## Part 2
+
+
```elixir
+
tasks
+
|> Enum.map(&String.to_charlist/1)
+
|> Enum.zip_with(&(&1 |> List.to_string() |> String.trim()))
+
|> Enum.chunk_while(
+
[],
+
fn
+
"", acc -> {:cont, acc, []}
+
num, acc -> {:cont, [String.to_integer(num) | acc]}
+
end,
+
&{:cont, &1, []}
+
)
+
|> Enum.zip(ops)
+
|> Enum.sum_by(fn
+
{nums, :+} -> Enum.sum(nums)
+
{nums, :*} -> Enum.product(nums)
+
end)
+
```
+
+
<!-- livebook:{"offset":1319,"stamp":{"token":"XCP.wqKPUf7KHN-UzqY1O8_n61vLL2ksAE_kGnIsQL0IpamJTD-NEX9_HbYK4H0y_NM8lKhqDz4rZ-TMFsXjuQ3n2-URGSNh_SCmDtJIbJBAP3mbiCwyN52oyGL0Nq5eD424MQ","version":2}} -->
+117
2025/day07.livemd
···
+
# Day 07
+
+
```elixir
+
Mix.install([:kino_aoc, :image])
+
```
+
+
## Parse
+
+
<!-- livebook:{"attrs":"eyJhc3NpZ25fdG8iOiJwdXp6bGVfaW5wdXQiLCJkYXkiOiI3Iiwic2Vzc2lvbl9zZWNyZXQiOiJBRFZFTlRfT0ZfQ09ERV9TRVNTSU9OIiwieWVhciI6IjIwMjUifQ","chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2025", "7", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
```elixir
+
[start | rest] = String.split(puzzle_input)
+
+
start_col = byte_size(start) - byte_size(String.trim_leading(start, "."))
+
```
+
+
```elixir
+
splitters =
+
Enum.map(rest, fn row ->
+
row
+
|> String.to_charlist()
+
|> Enum.with_index()
+
|> Enum.filter(&(elem(&1, 0) == ?^))
+
|> MapSet.new(&elem(&1, 1))
+
end)
+
```
+
+
<!-- livebook:{"branch_parent_index":0} -->
+
+
## Part 1
+
+
```elixir
+
Enum.reduce(splitters, {MapSet.new([start_col]), 0}, fn splits, {beams, count} ->
+
import MapSet, only: [intersection: 2, difference: 2, union: 2]
+
+
hits = intersection(beams, splits)
+
new_beams = for hit <- hits, dx <- [-1, 1], into: MapSet.new(), do: hit + dx
+
beams = beams |> difference(hits) |> union(new_beams)
+
+
{beams, MapSet.size(hits) + count}
+
end)
+
```
+
+
<!-- livebook:{"branch_parent_index":0} -->
+
+
## Part 2
+
+
```elixir
+
Enum.reduce(splitters, %{start_col => 1}, fn splits, beams ->
+
Enum.reduce(splits, beams, fn s, acc ->
+
case Map.pop(acc, s) do
+
{nil, map} ->
+
map
+
+
{count, map} ->
+
Map.merge(
+
map,
+
%{
+
(s + 1) => count,
+
(s - 1) => count
+
},
+
fn _k, a, b -> a + b end
+
)
+
end
+
end)
+
end)
+
|> Enum.sum_by(&elem(&1, 1))
+
```
+
+
<!-- livebook:{"branch_parent_index":0} -->
+
+
## Image
+
+
```elixir
+
height = length([start | rest])
+
width = byte_size(start)
+
+
{height, width}
+
```
+
+
```elixir
+
Image.new!(width, height)
+
|> Image.mutate(fn img ->
+
Image.Draw.point!(img, start_col, 0, color: :yellow)
+
+
splitters
+
|> Enum.with_index(1)
+
|> Enum.reduce(MapSet.new([start_col]), fn {splits, y}, beams ->
+
import MapSet, only: [intersection: 2, difference: 2, union: 2]
+
+
for x <- beams do
+
Image.Draw.point(img, x, y, color: :green)
+
end
+
+
for x <- splits do
+
Image.Draw.point(img, x, y, color: :red)
+
end
+
+
hits = intersection(beams, splits)
+
new_beams = for hit <- hits, dx <- [-1, 1], into: MapSet.new(), do: hit + dx
+
beams = beams |> difference(hits) |> union(new_beams)
+
+
beams
+
end)
+
+
img
+
end)
+
|> then(fn {:ok, img} -> img end)
+
|> Image.resize!(5, interpolate: :nearest)
+
```
+
+
<!-- livebook:{"offset":2553,"stamp":{"token":"XCP.6lQNAY-yntHErm41fMi4xgwAxGSGZ7l6ekgYSe6b3Exm48kBKgyIoCK62LLVaeQP-1PfZFpd3tzHwAIA8OWTsnRBuWsxmex5qixMa-l4DaThm-jrSaVsE3Qj4aO-TrqdqA","version":2}} -->
+116
2025/day08.livemd
···
+
# Day 08
+
+
```elixir
+
Mix.install([:kino_aoc])
+
```
+
+
## Parse
+
+
<!-- livebook:{"attrs":"eyJhc3NpZ25fdG8iOiJwdXp6bGVfaW5wdXQiLCJkYXkiOiI4Iiwic2Vzc2lvbl9zZWNyZXQiOiJBRFZFTlRfT0ZfQ09ERV9TRVNTSU9OIiwieWVhciI6IjIwMjUifQ","chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2025", "8", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
```elixir
+
boxes =
+
puzzle_input
+
|> String.split()
+
|> Enum.map(fn raw ->
+
raw
+
|> String.split(",")
+
|> Enum.map(&String.to_integer/1)
+
|> List.to_tuple()
+
end)
+
|> Enum.sort()
+
```
+
+
## Setup
+
+
```elixir
+
defmodule JunctionBoxes do
+
def all_pairs([]), do: []
+
+
def all_pairs([x | rest]) do
+
for(y <- rest, do: {x, y}) ++ all_pairs(rest)
+
end
+
+
def dist2({ax, ay, az}, {bx, by, bz}) do
+
dx = ax - bx
+
dy = ay - by
+
dz = az - bz
+
+
dx ** 2 + dy ** 2 + dz ** 2
+
end
+
+
def group([], {a, b}), do: [MapSet.new([a, b])]
+
def group([set | rest], {a, b}) do
+
cond do
+
a in set and b in set -> [set | rest]
+
a in set or b in set -> set |> MapSet.put(a) |> MapSet.put(b) |> do_squash(rest, a, b, [])
+
true -> [set | group(rest, {a, b})]
+
end
+
end
+
+
defp do_squash(curr, [], _, _, acc), do: [curr | acc]
+
defp do_squash(curr, [x | rest], a, b, acc) do
+
if a in x or b in x do
+
[MapSet.union(curr, x) | acc ++ rest]
+
else
+
do_squash(curr, rest, a, b, [x | acc])
+
end
+
end
+
end
+
```
+
+
```elixir
+
sorted_pairs =
+
JunctionBoxes.all_pairs(boxes)
+
|> Enum.sort_by(fn {a, b} -> JunctionBoxes.dist2(a, b) end)
+
```
+
+
<!-- livebook:{"branch_parent_index":1} -->
+
+
## Part 1
+
+
```elixir
+
sorted_pairs
+
|> Enum.take(1000)
+
|> Enum.reduce([], &JunctionBoxes.group(&2, &1))
+
|> Enum.map(&MapSet.size/1)
+
|> Enum.sort(:desc)
+
|> Enum.take(3)
+
|> Enum.product()
+
```
+
+
<!-- livebook:{"branch_parent_index":1} -->
+
+
## Part 2
+
+
```elixir
+
box_count = length(boxes)
+
```
+
+
```elixir
+
{a, b} =
+
sorted_pairs
+
|> Enum.reduce_while([], fn pair, acc ->
+
new_acc = JunctionBoxes.group(acc, pair)
+
+
if MapSet.size(hd(new_acc)) == box_count do
+
{:halt, pair}
+
else
+
{:cont, new_acc}
+
end
+
end)
+
```
+
+
```elixir
+
{ax, _, _} = a
+
{bx, _, _} = b
+
+
ax * bx
+
```
+
+
<!-- livebook:{"offset":2222,"stamp":{"token":"XCP.sY5bJOGXuU_ZotobOVN6-zcg0TDJGEWVaJESs_-qDHzeEplFoStZ8_c6TRpS5eVpqnzoaj-gsLs_drksuYvMCDcM3T7_M6p9s09DRSKgMU2YB_Ogb0CB6_gAZamF2zEIUw","version":2}} -->
+167
2025/day09.livemd
···
+
# Day 09
+
+
```elixir
+
Mix.install([:kino_aoc, :image])
+
```
+
+
## Setup
+
+
<!-- livebook:{"attrs":"eyJhc3NpZ25fdG8iOiJwdXp6bGVfaW5wdXQiLCJkYXkiOiI5Iiwic2Vzc2lvbl9zZWNyZXQiOiJBRFZFTlRfT0ZfQ09ERV9TRVNTSU9OIiwieWVhciI6IjIwMjUifQ","chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2025", "9", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
```elixir
+
tiles =
+
puzzle_input
+
|> String.split()
+
|> Enum.map(fn raw ->
+
raw
+
|> String.split(",")
+
|> Enum.map(&String.to_integer/1)
+
|> List.to_tuple()
+
end)
+
```
+
+
## Implementation
+
+
```elixir
+
defmodule Combinatorics do
+
def combinations2(list) do
+
Stream.unfold(list, fn
+
[] -> nil
+
[x | rest] ->
+
curr = for y <- rest, do: [x, y]
+
+
{curr, rest}
+
end)
+
|> Stream.flat_map(& &1)
+
end
+
end
+
```
+
+
```elixir
+
defmodule Rect do
+
require Record
+
+
Record.defrecordp(:rect, l: 0, t: 0, r: 0, b: 0)
+
+
def new({ax, ay}, {bx, by}) do
+
rect(l: min(ax, bx), r: max(ax, bx), t: min(ay, by), b: max(ay, by))
+
end
+
+
def area(rect() = r) do
+
width(r) * height(r)
+
end
+
+
def intersect?(
+
rect(l: al, r: ar, t: at, b: ab),
+
rect(l: bl, r: br, t: bt, b: bb)
+
) do
+
al < br and ar > bl and at < bb and ab > bt
+
end
+
+
def width(rect(r: r, l: l)), do: r - l + 1
+
def height(rect(t: t, b: b)), do: b - t + 1
+
+
def to_svg(rect(l: x, t: y) = r, opts \\ []) do
+
~s"""
+
<rect x="#{x}" y="#{y}" width="#{width(r)}" height="#{height(r)}"
+
#{Enum.map_join(opts, " ", fn {k, v} -> ~s(#{k}="#{v}") end)} />
+
"""
+
end
+
end
+
```
+
+
```elixir
+
rects =
+
Combinatorics.combinations2(tiles)
+
|> Stream.map(fn [a, b] -> Rect.new(a, b) end)
+
|> Enum.sort()
+
```
+
+
<!-- livebook:{"branch_parent_index":1} -->
+
+
## Part 1
+
+
```elixir
+
rects
+
|> Enum.max_by(&Rect.area/1)
+
|> IO.inspect()
+
|> Rect.area()
+
```
+
+
<!-- livebook:{"branch_parent_index":1} -->
+
+
## Part 2
+
+
```elixir
+
edges =
+
tiles
+
|> Enum.chunk_every(2, 1, tiles)
+
|> Enum.map(&apply(Rect, :new, &1))
+
|> Enum.sort()
+
```
+
+
```elixir
+
# [{1916, 50285}, {94619, 50285}, {94619, 48466}, {1668, 48466}]
+
# |> Stream.flat_map(fn a ->
+
# for b <- tiles do
+
# Rect.new(a, b)
+
# end
+
# end)
+
rects
+
|> Enum.reduce({0, nil}, fn r, {max, p} ->
+
a = Rect.area(r)
+
+
if a > max and not Enum.any?(edges, &Rect.intersect?(r, &1)) do
+
{a, r}
+
else
+
{max, p}
+
end
+
end)
+
```
+
+
## Draw
+
+
```elixir
+
{{min_x, _}, {max_x, _}} = Enum.min_max(tiles)
+
```
+
+
```elixir
+
{{_, min_y}, {_, max_y}} = Enum.min_max_by(tiles, &elem(&1, 1))
+
```
+
+
```elixir
+
h = max_y + min_y
+
w = max_x + min_x
+
```
+
+
```elixir
+
{x, y} = hd(tiles)
+
+
p1 = {:rect, 16055, 14805, 85282, 83613}
+
p2 = {:rect, 5741, 50285, 94619, 67351}
+
+
svg = """
+
<svg xmlns="http://www.w3.org/2000/svg" width="500" viewBox="0 0 #{w} #{h}">
+
<rect width="100%" height="100%" fill="black" />
+
<path d="M#{x} #{y}#{
+
for {x, y} <- tl(tiles), do: "L#{x} #{y} "
+
} L#{x} #{y}" stroke="darkgreen" fill="green" stroke-width="200" />
+
#{Rect.to_svg(p1, stroke: :orange, fill: :transparent, "stroke-width": 200)}
+
#{Rect.to_svg(p2, stroke: :yellow, fill: :transparent, "stroke-width": 200)}
+
#{
+
for {x, y} <- tiles do
+
~s(<rect x="#{x - 100}" y="#{y - 100}" width="200" height="200" fill="red" />)
+
end
+
}
+
</svg>
+
"""
+
+
Kino.Image.new(svg, :svg)
+
```
+
+
<!-- livebook:{"offset":3329,"stamp":{"token":"XCP.SSlM8wg30CucU7IP0n8MTbPIvnvvcZRXcglo9DY17kk0O0fwtLfUUiYJauWdspkXUlp0Axl5YscQNBKK5mSycPLd0iNdz8JFPfjCg4rS2pyM3JuQj73ipXd27t8Yd0ylig","version":2}} -->
+188
2025/day10.livemd
···
+
# Day 10
+
+
```elixir
+
Mix.install([:kino_aoc, {:dantzig, github: "hauleth/dantzig", ref: "use-proper-binary"}],
+
config: [
+
dantzig: [
+
highs_binary_path: System.find_executable("highs")
+
]
+
])
+
```
+
+
## Section
+
+
<!-- livebook:{"attrs":"eyJhc3NpZ25fdG8iOiJwdXp6bGVfaW5wdXQiLCJkYXkiOiIxMCIsInNlc3Npb25fc2VjcmV0IjoiQURWRU5UX09GX0NPREVfU0VTU0lPTiIsInllYXIiOiIyMDI1In0","chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2025", "10", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
```elixir
+
defmodule Decoder do
+
def decode("[" <> pattern), do: do_lights(String.reverse(String.trim_trailing(pattern, "]")), 0)
+
+
def decode("(" <> rest) do
+
<<seq::binary-size(byte_size(rest) - 1), ")">> = rest
+
+
seq
+
|> String.split(",")
+
|> Enum.map(&String.to_integer/1)
+
end
+
+
def decode("{" <> rest) do
+
<<seq::binary-size(byte_size(rest) - 1), "}">> = rest
+
+
seq
+
|> String.split(",")
+
|> Enum.map(&String.to_integer/1)
+
end
+
+
defp do_lights("", num), do: num
+
defp do_lights("." <> rest, num), do: do_lights(rest, 2 * num)
+
defp do_lights("#" <> rest, num), do: do_lights(rest, 2 * num + 1)
+
end
+
```
+
+
```elixir
+
indicators =
+
puzzle_input
+
|> String.split("\n", trim: true)
+
|> Enum.map(fn raw ->
+
[lights | rest] =
+
raw
+
|> String.split()
+
|> Enum.map(&Decoder.decode/1)
+
+
{buttons, [whatever]} = Enum.split(rest, -1)
+
+
{lights, buttons, whatever}
+
end)
+
```
+
+
<!-- livebook:{"branch_parent_index":0} -->
+
+
## Part 1
+
+
We are looking for such sequence of buttons that will provide pattern we are looking for. It can be solved by brute force with simple observation that buttons $a_n$ as well as light pattern $p$ can be represented by binary pattern. This allows us to use $\oplus$ (exclusive or, aka `XOR`) as an operation for pressing button.
+
+
Thanks to that observation we can see, that order in which we press buttons doesn't matter, as $\oplus$ is reflexive, i.e.:
+
+
$$
+
\begin{equation}
+
a \oplus b = b \oplus a
+
\end{equation}
+
$$
+
+
Additionally, wrt. $\oplus$ we have identity element $0$ and inverse element is the same as an original element, i.e.
+
+
$$
+
\begin{align}
+
a \oplus 0 = a \\
+
a \oplus a = 0
+
\end{align}
+
$$
+
+
Additionally we can observe that:
+
+
$$
+
\begin{equation}
+
(a \oplus b) \oplus c = a \oplus (b \oplus c)
+
\end{equation}
+
$$
+
+
With that observation we can deduce that each button will be pressed at most once and the order in which we press buttons doesn't matter.
+
+
---
+
+
So now we look for set $A = \{a_n\}$ of buttons that
+
+
$$
+
A \in \mathcal{P}(\text{Buttons}) \\
+
\forall_{i, j} \; i \ne j \implies a_i \ne a_j \\
+
\bigoplus A = p
+
$$
+
+
```elixir
+
defmodule Comb do
+
def all_possible([]), do: [[]]
+
def all_possible([a | rest]) do
+
sub = all_possible(rest)
+
+
sub ++ Enum.map(sub, &[a | &1])
+
end
+
end
+
```
+
+
```elixir
+
indicators
+
|> Enum.sum_by(fn {p, a, _} ->
+
a
+
|> Enum.map(&Enum.sum_by(&1, fn p -> 2 ** p end))
+
|> Comb.all_possible()
+
|> Enum.sort_by(&length/1)
+
|> Enum.find(fn seq ->
+
r = Enum.reduce(seq, 0, &Bitwise.bxor/2)
+
+
p == r
+
end)
+
|> length()
+
end)
+
```
+
+
<!-- livebook:{"branch_parent_index":0} -->
+
+
## Part 2
+
+
```elixir
+
defmodule Joltage do
+
alias Dantzig.Polynomial
+
alias Dantzig.Constraint
+
alias Dantzig.Problem
+
+
def solve({_pat, buttons, goal}) do
+
p = Problem.new(direction: :minimize)
+
+
{vars, {p, map}} =
+
buttons
+
|> Enum.with_index()
+
|> Enum.map_reduce({p, %{}}, fn {list, idx}, {p, acc} ->
+
{p, var} = Problem.new_variable(p, "v#{idx}", min: 0, type: :integer)
+
+
acc =
+
Enum.reduce(list, acc, fn key, map ->
+
Map.update(map, key, [var], &[var | &1])
+
end)
+
+
{var, {p, acc}}
+
end)
+
+
p =
+
map
+
|> Enum.sort()
+
|> Enum.map(&elem(&1, 1))
+
|> Enum.zip(goal)
+
|> Enum.reduce(p, fn {vars, target}, p ->
+
poly = Polynomial.sum(vars)
+
const = Constraint.new(poly, :==, target)
+
+
Problem.add_constraint(p, const)
+
end)
+
+
p = Problem.increment_objective(p, Polynomial.sum(vars))
+
+
{:ok, s} = Dantzig.HiGHS.solve(p)
+
+
Enum.sum_by(vars, &Dantzig.Solution.evaluate(s, &1))
+
end
+
end
+
```
+
+
```elixir
+
indicators
+
|> Task.async_stream(&Joltage.solve/1, ordered: false)
+
|> Enum.sum_by(&elem(&1, 1))
+
|> trunc()
+
```
+
+
<!-- livebook:{"offset":4336,"stamp":{"token":"XCP.sfoBGIHkFvWbEHVrY-dL-QiEcwRz_ZCIjn3lQ0RFHActIOwEapmOPBt0ygbQAmrnEjYPlFm5KrcWx4LfIPbSznxxcea0fYORG9GbBBpRCm-tYbGXYTCGgqgTvOsifyWDNg","version":2}} -->
+85
2025/day11.livemd
···
+
# Day 11
+
+
```elixir
+
Mix.install([:kino_aoc])
+
```
+
+
## Parse
+
+
<!-- livebook:{"attrs":"eyJhc3NpZ25fdG8iOiJwdXp6bGVfaW5wdXQiLCJkYXkiOiIxMSIsInNlc3Npb25fc2VjcmV0IjoiQURWRU5UX09GX0NPREVfU0VTU0lPTiIsInllYXIiOiIyMDI1In0","chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2025", "11", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
```elixir
+
graph =
+
puzzle_input
+
|> String.split("\n", trim: true)
+
|> Map.new(fn <<from::binary-3>> <> ": " <> rest ->
+
{from, String.split(rest)}
+
end)
+
```
+
+
## Implementation
+
+
```elixir
+
defmodule Servers do
+
def paths(graph, from, to), do: paths(graph, from, to, [from])
+
+
defp paths(_graph, to, to, acc), do: [Enum.reverse(acc)]
+
+
defp paths(graph, from, to, acc) do
+
if next = graph[from] do
+
Stream.flat_map(next, &paths(graph, &1, to, [&1 | acc]))
+
else
+
[]
+
end
+
end
+
+
def paths_through(graph, from, to, required),
+
do: path_through(graph, from, to, MapSet.new(required), %{})
+
+
defp path_through(_graph, to, to, required, memo),
+
do: {if(Enum.empty?(required), do: 1, else: 0), memo}
+
+
defp path_through(graph, from, to, required, memo) do
+
state = MapSet.delete(required, from)
+
+
with :error <- Map.fetch(memo, {from, state}),
+
{:ok, next} <- Map.fetch(graph, from) do
+
{sum, memo} =
+
Enum.reduce(next, {0, memo}, fn n, {sum, acc} ->
+
{c, next_acc} = path_through(graph, n, to, state, acc)
+
+
{c + sum, next_acc}
+
end)
+
+
{sum, Map.put(memo, {from, state}, sum)}
+
else
+
:error -> {0, memo}
+
{:ok, val} -> {val, memo}
+
end
+
end
+
end
+
```
+
+
<!-- livebook:{"branch_parent_index":1} -->
+
+
## Part 1
+
+
```elixir
+
Servers.paths(graph, "you", "out") |> Enum.count()
+
```
+
+
<!-- livebook:{"branch_parent_index":1} -->
+
+
## Part 2
+
+
```elixir
+
Servers.paths_through(graph, "svr", "out", ["dac", "fft"])
+
|> elem(0)
+
```
+
+
<!-- livebook:{"offset":1933,"stamp":{"token":"XCP.fzzPot48c9xb6ftw8IEb1V6uTX6csBICnoXjN1PU6c3DylXjP-bco9PgawAoc2GSeNJRzS3NCPmJ9aO9Jm2ehPXnam5fN-bZvUbEcxKmNA8SqH2_fJ5o_qp8rIaxpH6DRQ","version":2}} -->
+73
2025/day12.livemd
···
+
# Day 12
+
+
```elixir
+
Mix.install([:kino_aoc])
+
```
+
+
## Parsing
+
+
<!-- livebook:{"attrs":"eyJhc3NpZ25fdG8iOiJwdXp6bGVfaW5wdXQiLCJkYXkiOiIxMiIsInNlc3Npb25fc2VjcmV0IjoiQURWRU5UX09GX0NPREVfU0VTU0lPTiIsInllYXIiOiIyMDI1In0","chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} -->
+
+
```elixir
+
{:ok, puzzle_input} =
+
KinoAOC.download_puzzle("2025", "12", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
+
```
+
+
```elixir
+
{areas, boxes} =
+
puzzle_input
+
|> String.split("\n\n")
+
|> List.pop_at(-1)
+
```
+
+
```elixir
+
areas =
+
areas
+
|> String.split("\n")
+
|> Enum.map(fn raw ->
+
[area | counts] = String.split(raw)
+
+
area =
+
area
+
|> String.trim(":")
+
|> String.split("x")
+
|> Enum.map(&String.to_integer/1)
+
|> Enum.product()
+
+
counts = Enum.map(counts, &String.to_integer/1)
+
+
{area, counts}
+
end)
+
```
+
+
```elixir
+
boxes =
+
boxes
+
|> Enum.map(fn <<_::binary-3>> <> rest ->
+
rest
+
|> String.to_charlist()
+
|> Enum.count(&(&1 == ?#))
+
end)
+
```
+
+
<!-- livebook:{"branch_parent_index":0} -->
+
+
## Part 1
+
+
```elixir
+
areas
+
|> Enum.count(fn {max, counts} ->
+
counts
+
|> Enum.zip_with(boxes, &*/2)
+
|> Enum.sum()
+
|> then(& &1 <= max)
+
end)
+
```
+
+
<!-- livebook:{"branch_parent_index":0} -->
+
+
## Part 2
+
+
FIN
+
+
<!-- livebook:{"offset":1266,"stamp":{"token":"XCP.VAO97d30rTEs0AWIHkPD4J0fLm3S60tQ3fKoA-riReFbzMnqL1jIoxttGhvNSnCfZVNfeUBuSYVe6PrIshxVGBwjr3pjNHCyFLSb4iSPNh277lkMmh6Gtrlfr8dvsYvw0g","version":2}} -->