Day 18: Lavaduct Lagoon – Advent of Code 2023
Mix.install([{:topo, "~> 1.0"}])
input =
File.stream!("/Users/pw/src/weiland/adventofcode/2023/input/18.txt")
|> Stream.map(&String.trim/1)
test_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)" |> String.split("\n")
Parsing
delta_map = %{"D" => [1, 0], "U" => [-1, 0], "L" => [0, -1], "R" => [0, 1]}
parse_one = fn input ->
input
|> Enum.map(&String.split(&1, " "))
|> Enum.map(fn [dir, steps, _color] -> [delta_map[dir], String.to_integer(steps)] end)
end
dir_map = %{"0" => "R", "1" => "D", "2" => "L", "3" => "U"}
parse_two = fn input ->
input
|> Enum.map(&String.split(&1, " "))
|> Enum.map(fn [_, _, "(#" <> string] ->
[
delta_map[dir_map[String.slice(string, -2, 1)]],
Integer.parse(String.slice(string, 0, 5), 16) |> elem(0)
]
end)
end
parse_two.(test_input)
Part One
dig = fn input ->
{_, perimeter, coords} =
input
|> Enum.reduce({{0, 0}, 0, []}, fn [[row_delta, col_delta], steps],
{{prev_row, prev_col}, perimeter, coords} ->
pos = {prev_row + row_delta * steps, prev_col + col_delta * steps}
{pos, perimeter + steps, [pos | coords]}
end)
area =
coords
|> Enum.reverse()
|> Enum.chunk_every(2, 1, :discard)
|> Enum.reduce(0, fn [{row, col}, {next_row, next_col}], acc ->
(row + next_row) * (col - next_col) / 2 + acc
end)
trunc(area + perimeter / 2 + 1)
end
IO.inspect(dig.(test_input |> parse_one.()) == 62, label: "Test part one")
dig.(input |> parse_one.())
Part Two
IO.inspect(dig.(test_input |> parse_two.()) == 952_408_144_115, label: "Test part two")
dig.(input |> parse_two.())