78 lines
1.7 KiB
Elixir
78 lines
1.7 KiB
Elixir
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()
|