Skip to content

Commit 14b8747

Browse files
committed
Remove erlang solution
1 parent 77ec551 commit 14b8747

14 files changed

Lines changed: 386 additions & 644 deletions

lib/2022/day_08.ex

Lines changed: 86 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,96 @@ defmodule AdventOfCode.Y2022.Day08 do
33
--- Day 8: Treetop Tree House ---
44
Problem Link: https://adventofcode.com/2022/day/8
55
Difficulty: m
6-
Tags: erlang grid
6+
Tags: grid graph traversal
77
"""
8-
alias AdventOfCode.Helpers.InputReader
8+
alias AdventOfCode.Helpers.{InputReader, Transformers}
9+
alias Yog.Builder.Grid
10+
alias Yog.Traversal.Implicit
911

1012
def input, do: InputReader.read_from_file(2022, 8)
1113

1214
def run(input \\ input()) do
13-
:day_22_8.solve(input)
15+
grid_data = input |> Transformers.lines() |> Enum.map(&Transformers.digits/1)
16+
grid = Grid.from_2d_list(grid_data, :directed, Grid.always())
17+
18+
{part1(grid), part2(grid)}
19+
end
20+
21+
defp part1(grid) do
22+
for r <- 0..(grid.rows - 1),
23+
c <- 0..(grid.cols - 1),
24+
visible?(grid, r, c),
25+
reduce: 0 do
26+
acc -> acc + 1
27+
end
28+
end
29+
30+
defp part2(grid) do
31+
for r <- 0..(grid.rows - 1),
32+
c <- 0..(grid.cols - 1) do
33+
scenic_score(grid, r, c)
34+
end
35+
|> Enum.max()
36+
end
37+
38+
defp visible?(grid, r, c) do
39+
if r == 0 or r == grid.rows - 1 or c == 0 or c == grid.cols - 1 do
40+
true
41+
else
42+
{:ok, h} = Grid.get_cell(grid, r, c)
43+
44+
Enum.any?([{-1, 0}, {1, 0}, {0, -1}, {0, 1}], fn {dr, dc} ->
45+
directional_walk(grid, r + dr, c + dc, dr, dc)
46+
|> Enum.all?(fn other_h -> other_h < h end)
47+
end)
48+
end
1449
end
50+
51+
defp scenic_score(grid, r, c) do
52+
{:ok, h} = Grid.get_cell(grid, r, c)
53+
54+
Enum.reduce([{-1, 0}, {1, 0}, {0, -1}, {0, 1}], 1, fn {dr, dc}, acc ->
55+
acc * viewing_distance(grid, r + dr, c + dc, dr, dc, h)
56+
end)
57+
end
58+
59+
defp directional_walk(grid, r, c, dr, dc) do
60+
Implicit.implicit_fold(
61+
from: {r, c},
62+
using: :breadth_first,
63+
successors_of: fn {curr_r, curr_c} ->
64+
nr = curr_r + dr
65+
nc = curr_c + dc
66+
if in_bounds?(grid, nr, nc), do: [{nr, nc}], else: []
67+
end,
68+
initial: [],
69+
with: fn acc, {curr_r, curr_c}, _meta ->
70+
{:ok, h} = Grid.get_cell(grid, curr_r, curr_c)
71+
{:continue, [h | acc]}
72+
end
73+
)
74+
end
75+
76+
defp viewing_distance(grid, r, c, dr, dc, h) do
77+
if not in_bounds?(grid, r, c) do
78+
0
79+
else
80+
Implicit.implicit_fold(
81+
from: {r, c},
82+
using: :breadth_first,
83+
successors_of: fn {curr_r, curr_c} ->
84+
{:ok, curr_h} = Grid.get_cell(grid, curr_r, curr_c)
85+
nr = curr_r + dr
86+
nc = curr_c + dc
87+
if curr_h < h and in_bounds?(grid, nr, nc), do: [{nr, nc}], else: []
88+
end,
89+
initial: 0,
90+
with: fn acc, _coord, _meta ->
91+
{:continue, acc + 1}
92+
end
93+
)
94+
end
95+
end
96+
97+
defp in_bounds?(grid, r, c), do: r >= 0 and r < grid.rows and c >= 0 and c < grid.cols
1598
end

lib/2022/day_09.ex

Lines changed: 59 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,69 @@ defmodule AdventOfCode.Y2022.Day09 do
33
--- Day 9: Rope Bridge ---
44
Problem Link: https://adventofcode.com/2022/day/9
55
Difficulty: m
6-
Tags: erlang grid walk
6+
Tags: grid walk
77
"""
8-
alias AdventOfCode.Helpers.InputReader
8+
alias AdventOfCode.Helpers.{InputReader, Transformers}
99

1010
def input, do: InputReader.read_from_file(2022, 9)
1111

1212
def run(input \\ input()) do
13-
:day_22_9.solve(input)
13+
instructions = parse(input)
14+
{part1(instructions), part2(instructions)}
1415
end
16+
17+
defp part1(instructions), do: solve(instructions, 2)
18+
defp part2(instructions), do: solve(instructions, 10)
19+
20+
defp solve(instructions, count) do
21+
start_rope = List.duplicate({0, 0}, count)
22+
23+
{_rope, visited} =
24+
Enum.reduce(instructions, {start_rope, MapSet.new([{0, 0}])}, fn {dir, steps}, acc ->
25+
Enum.reduce(1..steps, acc, fn _, {rope, visited} ->
26+
[head | tails] = rope
27+
new_head = move_head(head, dir)
28+
29+
# Each knot follows the one before it
30+
new_rope =
31+
Enum.scan(tails, new_head, fn tail, prev ->
32+
follow(prev, tail)
33+
end)
34+
35+
full_rope = [new_head | new_rope]
36+
{full_rope, MapSet.put(visited, List.last(full_rope))}
37+
end)
38+
end)
39+
40+
MapSet.size(visited)
41+
end
42+
43+
defp parse(input) do
44+
input
45+
|> Transformers.lines()
46+
|> Enum.map(fn line ->
47+
[dir, steps] = String.split(line, " ")
48+
{dir, String.to_integer(steps)}
49+
end)
50+
end
51+
52+
defp move_head({r, c}, "U"), do: {r - 1, c}
53+
defp move_head({r, c}, "D"), do: {r + 1, c}
54+
defp move_head({r, c}, "L"), do: {r, c - 1}
55+
defp move_head({r, c}, "R"), do: {r, c + 1}
56+
57+
defp follow({hr, hc}, {tr, tc}) do
58+
dr = hr - tr
59+
dc = hc - tc
60+
61+
if abs(dr) <= 1 and abs(dc) <= 1 do
62+
{tr, tc}
63+
else
64+
{tr + sign(dr), tc + sign(dc)}
65+
end
66+
end
67+
68+
defp sign(0), do: 0
69+
defp sign(n) when n > 0, do: 1
70+
defp sign(n) when n < 0, do: -1
1571
end

lib/2022/day_10.ex

Lines changed: 55 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,66 @@
11
defmodule AdventOfCode.Y2022.Day10 do
22
@moduledoc """
3-
--- Day 10: Cathode-Ray Tube ---p
3+
--- Day 10: Cathode-Ray Tube ---
44
Problem Link: https://adventofcode.com/2022/day/10
55
Difficulty: m
6-
Tags: erlang visual-result op-code
6+
Tags: visual-result op-code
77
"""
8-
alias AdventOfCode.Helpers.InputReader
8+
alias AdventOfCode.Helpers.{InputReader, Transformers}
99

1010
def input, do: InputReader.read_from_file(2022, 10)
1111

1212
def run(input \\ input()) do
13-
:day_22_10.solve(input)
13+
cycles = simulate(parse(input))
14+
15+
part1 =
16+
[20, 60, 100, 140, 180, 220]
17+
|> Enum.map(fn c -> c * cycles[c] end)
18+
|> Enum.sum()
19+
20+
part2 = draw(cycles)
21+
22+
{part1, part2}
23+
end
24+
25+
defp parse(input) do
26+
input
27+
|> Transformers.lines()
28+
|> Enum.map(fn
29+
"noop" -> :noop
30+
"addx " <> val -> {:addx, String.to_integer(val)}
31+
end)
32+
end
33+
34+
defp simulate(instructions) do
35+
{cycles, _, _} =
36+
Enum.reduce(instructions, {%{}, 1, 1}, fn
37+
:noop, {acc, cycle, x} ->
38+
{Map.put(acc, cycle, x), cycle + 1, x}
39+
40+
{:addx, v}, {acc, cycle, x} ->
41+
acc = acc |> Map.put(cycle, x) |> Map.put(cycle + 1, x)
42+
{acc, cycle + 2, x + v}
43+
end)
44+
45+
cycles
46+
end
47+
48+
defp draw(cycles) do
49+
for r <- 0..5 do
50+
for c <- 0..39 do
51+
cycle = r * 40 + c + 1
52+
x = cycles[cycle]
53+
54+
if c in (x - 1)..(x + 1) do
55+
IO.write("█")
56+
else
57+
IO.write("▒")
58+
end
59+
end
60+
61+
IO.puts("")
62+
end
63+
64+
:ok
1465
end
1566
end

lib/2022/day_11.ex

Lines changed: 110 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,120 @@ defmodule AdventOfCode.Y2022.Day11 do
33
--- Day 11: Monkey in the Middle ---
44
Problem Link: https://adventofcode.com/2022/day/11
55
Difficulty: l
6-
Tags: erlang parse-heavy arithmetic
6+
Tags: parse-heavy arithmetic
77
"""
8-
alias AdventOfCode.Helpers.InputReader
8+
alias AdventOfCode.Helpers.{InputReader, Transformers}
99

1010
def input, do: InputReader.read_from_file(2022, 11)
1111

1212
def run(input \\ input()) do
13-
:day_22_11.solve(input)
13+
monkeys = parse(input)
14+
{solve1(monkeys), solve2(monkeys)}
15+
end
16+
17+
defp solve1(monkeys) do
18+
monkeys
19+
|> simulate(20, fn w -> div(w, 3) end)
20+
|> monkey_business()
21+
end
22+
23+
defp solve2(monkeys) do
24+
common_mod = monkeys |> Map.values() |> Enum.map(& &1.test) |> Enum.reduce(1, &*/2)
25+
26+
monkeys
27+
|> simulate(10_000, fn w -> rem(w, common_mod) end)
28+
|> monkey_business()
29+
end
30+
31+
defp simulate(monkeys, rounds, relax_fn) do
32+
ids = Map.keys(monkeys) |> Enum.sort()
33+
34+
Enum.reduce(1..rounds, monkeys, fn _, monkeys_acc ->
35+
Enum.reduce(ids, monkeys_acc, fn id, monkeys_round ->
36+
monkey = monkeys_round[id]
37+
38+
if monkey.items == [] do
39+
monkeys_round
40+
else
41+
throws =
42+
Enum.reduce(monkey.items, %{}, fn item, throw_acc ->
43+
new_worry = monkey.op.(item) |> relax_fn.()
44+
45+
target =
46+
if rem(new_worry, monkey.test) == 0,
47+
do: monkey.true_target,
48+
else: monkey.false_target
49+
50+
Map.update(throw_acc, target, [new_worry], fn current -> current ++ [new_worry] end)
51+
end)
52+
53+
Enum.reduce(throws, monkeys_round, fn {target_id, items}, ms ->
54+
update_in(ms, [target_id, :items], fn current -> current ++ items end)
55+
end)
56+
|> update_in([id, :inspected], &(&1 + length(monkey.items)))
57+
|> put_in([id, :items], [])
58+
end
59+
end)
60+
end)
61+
end
62+
63+
defp monkey_business(monkeys) do
64+
monkeys
65+
|> Map.values()
66+
|> Enum.map(& &1.inspected)
67+
|> Enum.sort(:desc)
68+
|> Enum.take(2)
69+
|> Enum.product()
70+
end
71+
72+
defp parse(input) do
73+
input
74+
|> Transformers.sections()
75+
|> Enum.with_index()
76+
|> Enum.reduce(%{}, fn {section, idx}, acc ->
77+
lines = Transformers.lines(section)
78+
[_, items_l, op_l, test_l, t_l, f_l] = Enum.map(lines, &String.trim/1)
79+
80+
monkey = %{
81+
items: parse_items(items_l),
82+
op: parse_op(op_l),
83+
test: parse_last_int(test_l),
84+
true_target: parse_last_int(t_l),
85+
false_target: parse_last_int(f_l),
86+
inspected: 0
87+
}
88+
89+
Map.put(acc, idx, monkey)
90+
end)
91+
end
92+
93+
defp parse_items(line) do
94+
line
95+
|> String.split(": ")
96+
|> List.last()
97+
|> String.split(", ")
98+
|> Enum.map(&String.to_integer/1)
99+
end
100+
101+
defp parse_last_int(line) do
102+
line
103+
|> String.split(" ")
104+
|> List.last()
105+
|> String.to_integer()
106+
end
107+
108+
defp parse_op(line) do
109+
[_, expr] = String.split(line, "new = ")
110+
[left_s, op_s, right_s] = String.split(expr, " ")
111+
112+
fn old ->
113+
l = if left_s == "old", do: old, else: String.to_integer(left_s)
114+
r = if right_s == "old", do: old, else: String.to_integer(right_s)
115+
116+
case op_s do
117+
"+" -> l + r
118+
"*" -> l * r
119+
end
120+
end
14121
end
15122
end

0 commit comments

Comments
 (0)