Skip to content

Commit 2ec0a13

Browse files
committed
day22
1 parent f70ba1f commit 2ec0a13

File tree

2 files changed

+122
-0
lines changed

2 files changed

+122
-0
lines changed

22/sample_input

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
1,0,1~1,2,1
2+
0,0,2~2,0,2
3+
0,2,3~2,2,3
4+
0,0,4~0,2,4
5+
2,0,5~2,2,5
6+
0,1,6~2,1,6
7+
1,1,8~1,1,9

22/sol.exs

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
defmodule Day22 do
2+
def read_input(file_path) do
3+
file_path
4+
|> File.read!()
5+
|> String.split("\n", trim: true)
6+
|> Enum.map(&parse/1)
7+
|> Enum.sort()
8+
|> Enum.with_index()
9+
|> Enum.map(&top_bot_layers/1)
10+
|> insert_bricks()
11+
end
12+
13+
def parse(line) do
14+
[x1, y1, z1, x2, y2, z2] =
15+
line |> String.split(~r/(,)|(\~)|(\ )/, trim: true) |> Enum.map(&String.to_integer/1)
16+
17+
{{z1, y1, x1}, {z2, y2, x2}, {z2 - z1, y2 - y1, x2 - x1}}
18+
end
19+
20+
def get_zmax({_, y, x}, z_map), do: Map.get(z_map, {x, y}, -1)
21+
22+
def top_bot_layers({{{z, y, x1}, {_z, _y, x2}, {0, 0, _}}, idx}) do
23+
top_bot =
24+
x1..x2
25+
|> Enum.map(fn x -> {z, y, x} end)
26+
27+
%{top: top_bot, bot: top_bot, dz: 1, idx: idx}
28+
end
29+
30+
def top_bot_layers({{{z, y1, x}, {_z, y2, _x}, {0, _, 0}}, idx}) do
31+
top_bot =
32+
y1..y2
33+
|> Enum.map(fn y -> {z, y, x} end)
34+
35+
%{top: top_bot, bot: top_bot, dz: 1, idx: idx}
36+
end
37+
38+
def top_bot_layers({{bot, top, {dz, 0, 0}}, idx}) do
39+
%{top: [top], bot: [bot], dz: dz + 1, idx: idx}
40+
end
41+
42+
def shift_to_zm1(%{bot: bot, top: top, dz: dz} = b, zm) do
43+
new_bot = bot |> Enum.map(fn {_, y, x} -> {zm + 1, y, x} end)
44+
new_top = top |> Enum.map(fn {_, y, x} -> {zm + dz, y, x} end)
45+
b |> Map.put(:top, new_top) |> Map.put(:bot, new_bot)
46+
end
47+
48+
def insert_bricks([], _, inserted_bricks), do: inserted_bricks
49+
50+
def insert_bricks([b | bricks], z_map, inserted_bricks) do
51+
zm = b[:bot] |> Enum.map(&get_zmax(&1, z_map)) |> Enum.max()
52+
new_b = shift_to_zm1(b, zm)
53+
new_z_map = Enum.reduce(new_b[:top], z_map, fn {z, y, x}, acc -> Map.put(acc, {x, y}, z) end)
54+
insert_bricks(bricks, new_z_map, [new_b | inserted_bricks])
55+
end
56+
57+
def insert_bricks(bricks), do: insert_bricks(bricks, Map.new(), [])
58+
59+
def is_support_to(%{top: top}, %{bot: bot}) do
60+
Enum.any?(top, fn {z, y, x} -> Enum.member?(bot, {z + 1, y, x}) end)
61+
end
62+
63+
def supports_of(brick, bricks) do
64+
{brick[:idx],
65+
bricks
66+
|> Enum.filter(fn b -> is_support_to(b, brick) end)
67+
|> Enum.map(fn %{idx: idx} -> idx end)}
68+
end
69+
70+
def supports(bricks), do: bricks |> Enum.map(&supports_of(&1, bricks)) |> Map.new()
71+
72+
def is_cone_to(a, b) do
73+
is_support_to(b, a)
74+
end
75+
76+
def cones_of(brick, bricks) do
77+
{brick[:idx],
78+
bricks
79+
|> Enum.filter(fn b -> is_cone_to(b, brick) end)
80+
|> Enum.map(fn %{idx: idx} -> idx end)}
81+
end
82+
83+
def cones(bricks), do: bricks |> Enum.map(&cones_of(&1, bricks)) |> Map.new()
84+
85+
def partA(file_path) do
86+
bricks = file_path |> read_input()
87+
sup = supports(bricks) |> Enum.map(fn {_, x} -> x end)
88+
89+
bricks
90+
|> Enum.reject(fn x -> Enum.member?(sup, [x[:idx]]) end)
91+
|> length()
92+
end
93+
94+
def partB(file_path) do
95+
bricks = file_path |> read_input()
96+
sup = supports(bricks)
97+
con = cones(bricks)
98+
counts = sup |> Map.to_list() |> Enum.sort() |> Enum.map(fn {_, s} -> length(s) end)
99+
100+
bricks
101+
|> Enum.map(fn x -> count_falls(con, counts, [x[:idx]], -1) end)
102+
|> Enum.sum()
103+
end
104+
105+
def count_falls(_, _, [], acc), do: acc
106+
107+
def count_falls(con, counts, [x | xs], acc) do
108+
nc = con[x] |> Enum.reduce(counts, fn s, c -> List.update_at(c, s, &(&1 - 1)) end)
109+
nx = con[x] |> Enum.filter(fn k -> Enum.at(nc, k) == 0 end)
110+
count_falls(con, nc, nx ++ xs, acc + 1)
111+
end
112+
end
113+
114+
IO.puts(Day22.partA("./input"))
115+
IO.puts(Day22.partB("./input"))

0 commit comments

Comments
 (0)