-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathday_18.ex
60 lines (45 loc) · 2.03 KB
/
day_18.ex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
defmodule AdventOfCode.Y2023.Day18 do
@moduledoc """
--- Day 18: Lavaduct Lagoon ---
Problem Link: https://adventofcode.com/2023/day/18
Difficulty: l
Tags: geometry
"""
alias AdventOfCode.Helpers.{InputReader, Transformers}
import AdventOfCode.Algorithms.Geometry, only: [polygon_area: 1]
@dir_map_1 %{"R" => :right, "D" => :down, "L" => :left, "U" => :up}
@dir_map_2 %{"0" => :right, "1" => :down, "2" => :left, "3" => :up}
def input, do: InputReader.read_from_file(2023, 18)
def run(input \\ input()) do
input = parse(input)
{input |> skip_colour() |> lava_capacity(), input |> rectify() |> lava_capacity()}
end
def parse(data \\ input()) do
for line <- Transformers.lines(data) do
[_, dir, steps, colours] = Regex.run(~r{(.) (\d+) \((.+)\)}, line)
{@dir_map_1[dir], String.to_integer(steps), colours}
end
end
defp lava_capacity(input) do
{perimeter, polygon} = get_geometry(input)
trunc(polygon_area(polygon) + div(perimeter, 2) + 1)
end
defp move(rules), do: move(rules, {0, 0}, [{0, 0}])
defp move([], _, points), do: Enum.reverse(points)
defp move([{:up, steps} | rules], {x, y}, points),
do: move(rules, {x - steps, y}, [{x - steps, y} | points])
defp move([{:down, steps} | rules], {x, y}, points),
do: move(rules, {x + steps, y}, [{x + steps, y} | points])
defp move([{:left, steps} | rules], {x, y}, points),
do: move(rules, {x, y - steps}, [{x, y - steps} | points])
defp move([{:right, steps} | rules], {x, y}, points),
do: move(rules, {x, y + steps}, [{x, y + steps} | points])
defp get_geometry(instructions) do
perimeter = Enum.reduce(instructions, 0, fn x, acc -> acc + elem(x, 1) end)
{perimeter, move(instructions)}
end
defp process_colour(<<"#", steps::binary-size(5), dir::binary-1>>),
do: {@dir_map_2[dir], elem(Integer.parse(steps, 16), 0)}
defp skip_colour(instructions), do: Enum.map(instructions, fn {a, b, _} -> {a, b} end)
defp rectify(instructions), do: Enum.map(instructions, &process_colour(elem(&1, 2)))
end