From a9519aebbf3ad9c23f7f37cdc0a75fe449e748d6 Mon Sep 17 00:00:00 2001 From: bluepython508 Date: Mon, 18 Dec 2023 09:19:27 +0000 Subject: [PATCH] Day 18 --- lib/common.ex | 4 +++ lib/day10.ex | 6 ++--- lib/day16.ex | 4 --- lib/day18.ex | 67 ++++++++++++++++++++++++++++++++++++++++++++++++ lib/mix_tasks.ex | 1 + tests/day18/1 | 14 ++++++++++ tests/day18/1.1 | 1 + tests/day18/1.2 | 1 + 8 files changed, 90 insertions(+), 8 deletions(-) create mode 100644 lib/day18.ex create mode 100644 tests/day18/1 create mode 100644 tests/day18/1.1 create mode 100644 tests/day18/1.2 diff --git a/lib/common.ex b/lib/common.ex index 1de2d69..d7bea39 100644 --- a/lib/common.ex +++ b/lib/common.ex @@ -59,4 +59,8 @@ defmodule Aoc2023.Common do def repeat(_, 0), do: [] def repeat(lst, n), do: Enum.concat(lst, repeat(lst, n - 1)) + + def add_vec({y, x}, {y_, x_}) do + {y + y_, x + x_} + end end diff --git a/lib/day10.ex b/lib/day10.ex index 75ffa9d..5ec14e0 100644 --- a/lib/day10.ex +++ b/lib/day10.ex @@ -13,8 +13,6 @@ defmodule Aoc2023.Day10 do ?S => [] } - defp add_coords({y, x}, {y_, x_}), do: {y + y_, x + x_} - defp path(s_conns, conns) do loop = fn recur, checked, checking -> checked_ = MapSet.union(checked, checking) @@ -53,7 +51,7 @@ defmodule Aoc2023.Day10 do |> Enum.map(fn {c, x} -> { {y, x}, - Map.get(@connections, c) |> Enum.map(pipe(add_coords({y, x}))) + Map.get(@connections, c) |> Enum.map(pipe(add_vec({y, x}))) } end) end) @@ -71,7 +69,7 @@ defmodule Aoc2023.Day10 do end def part2({{sy, sx}, s_conns, grid, path}) do - s_dirs = s_conns |> Enum.map(pipe(add_coords({-sy, -sx}))) |> Enum.sort() + s_dirs = s_conns |> Enum.map(pipe(add_vec({-sy, -sx}))) |> Enum.sort() s_char = @connections |> Enum.find(fn {_, conns} -> Enum.sort(conns) == s_dirs end) |> elem(0) grid_ = grid |> list_map_at(sy, pipe(map_nth(0, pipe(List.replace_at(sx, s_char))))) diff --git a/lib/day16.ex b/lib/day16.ex index c141220..1a73fda 100644 --- a/lib/day16.ex +++ b/lib/day16.ex @@ -15,10 +15,6 @@ defmodule Aoc2023.Day16 do end end - defp add_vec({y, x}, {y_, x_}) do - {y + y_, x + x_} - end - def parse(input) do input |> lines diff --git a/lib/day18.ex b/lib/day18.ex new file mode 100644 index 0000000..fab738e --- /dev/null +++ b/lib/day18.ex @@ -0,0 +1,67 @@ +defmodule Aoc2023.Day18 do + require Integer + use Aoc2023 + + def parse(input) do + input + |> lines + |> Enum.map(fn line -> + [dir, n, color] = + Regex.run(~r/^([RDLU]) (\d+) \(#([0-9a-f]{6})\)$/, line, capture: :all_but_first) + + { + dir |> String.to_charlist() |> head, + n |> String.to_integer(), + color + } + end) + end + + defp simulate({pos, dist, points}, {dir, n}) do + p = + case dir do + :u -> {-n, 0} + :d -> {n, 0} + :r -> {0, n} + :l -> {0, -n} + end + |> add_vec(pos) + + {p, dist + n, [p | points]} + end + + defp area(perim, points), + # Shoelace formula + do: + Stream.zip(points, points |> Stream.cycle() |> Stream.drop(1)) + |> Stream.map(fn {{y, x}, {y1, x1}} -> x * y1 - x1 * y end) + |> Enum.sum() + |> abs + |> then(&((&1 + perim) / 2)) + |> trunc + + defp run(instrs) do + {_, dist, points} = instrs |> Enum.reduce({{0, 0}, 2, [{0, 0}]}, &simulate(&2, &1)) + area(dist, points) + end + + def part1(input) do + run(for {dir, n, _} <- input, do: {case dir do + ?U -> :u + ?D -> :d + ?L -> :l + ?R -> :r + end, n}) + end + + def part2(input) do + run(for {_, _, <>} <- input do + {case dir do + ?0 -> :r + ?1 -> :d + ?2 -> :l + ?3 -> :u + end, String.to_integer(len, 16)} + end) + end +end diff --git a/lib/mix_tasks.ex b/lib/mix_tasks.ex index 6b2299d..eb6837b 100644 --- a/lib/mix_tasks.ex +++ b/lib/mix_tasks.ex @@ -18,6 +18,7 @@ defmodule Mix.Tasks.Aoc do defp module(14), do: Aoc2023.Day14 defp module(15), do: Aoc2023.Day15 defp module(16), do: Aoc2023.Day16 + defp module(18), do: Aoc2023.Day18 # [MODULE INSERTION POINT] defp base_dir(), do: System.get_env("AOC_BASE") diff --git a/tests/day18/1 b/tests/day18/1 new file mode 100644 index 0000000..fc7612e --- /dev/null +++ b/tests/day18/1 @@ -0,0 +1,14 @@ +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) diff --git a/tests/day18/1.1 b/tests/day18/1.1 new file mode 100644 index 0000000..b2412e3 --- /dev/null +++ b/tests/day18/1.1 @@ -0,0 +1 @@ +62 \ No newline at end of file diff --git a/tests/day18/1.2 b/tests/day18/1.2 new file mode 100644 index 0000000..c4d07b7 --- /dev/null +++ b/tests/day18/1.2 @@ -0,0 +1 @@ +952408144115 \ No newline at end of file