From d60e640e466cfb83d930d9cdcbedcf4a96bee56e Mon Sep 17 00:00:00 2001 From: Caleb Webber Date: Fri, 18 Apr 2025 12:32:22 -0400 Subject: [PATCH] add 2021 day 2 --- elixir/lib/Y2021/day2.exs | 78 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 elixir/lib/Y2021/day2.exs diff --git a/elixir/lib/Y2021/day2.exs b/elixir/lib/Y2021/day2.exs new file mode 100644 index 0000000..aa0da25 --- /dev/null +++ b/elixir/lib/Y2021/day2.exs @@ -0,0 +1,78 @@ +defmodule Submarine1 do + import AoC.Util.Tuple + + @sub_key :sub + @default {0,0} + + def reset(), do: Process.delete(@sub_key) + defp update(key, f, default), do: Process.put(key, f.(Process.get(key, default))) + def forward(n), do: update(@sub_key, &pairwise_sum(&1, {n, 0}), @default) + def down(n), do: update(@sub_key, &pairwise_sum(&1, {0, n}), @default) + def up(n), do: update(@sub_key, &pairwise_sum(&1, {0, -n}), @default) + + def checksum() do + {x, y} = Process.get(@sub_key, @default) + x * y + end +end + +defmodule Submarine2 do + import AoC.Util.Tuple + + @sub_key :sub + @default {0, 0, 0} + + def reset(), do: Process.delete(@sub_key) + defp update(key, f, default), do: Process.put(key, f.(Process.get(key, default))) + def forward(n), do: update(@sub_key, fn {_,_,a} = p -> pairwise_sum(p, {n, a*n, 0}) end, @default) + def down(n), do: update(@sub_key, &pairwise_sum(&1, {0, 0, n}), @default) + def up(n), do: update(@sub_key, &pairwise_sum(&1, {0, 0, -n}), @default) + + def checksum() do + {x, y, _} = Process.get(@sub_key, @default) + x * y + end +end + +gen_code = fn instructions, part -> + instructions = Code.string_to_quoted(instructions) + + quote do + unquote( + case part do + :part1 -> quote do: import Submarine1 + :part2 -> quote do: import Submarine2 + end + ) + + reset() + + unquote(instructions) + + checksum() + end +end + +solve = fn instructions, part -> + {soln, _} = Code.eval_quoted(gen_code.(instructions, part)) + + soln +end + +test_input = """ +forward 5 +down 5 +forward 8 +up 3 +down 8 +forward 2 +""" + +if solve.(test_input, :part1) != 150 or solve.(test_input, :part2) != 900 do + raise "unable to solve example input" +end + +input = File.read!("./lib/Y2021/day2.txt") + +solve.(input, :part2) +|> IO.puts()