aboutsummaryrefslogtreecommitdiff
path: root/aoc-2019-elixir/lib/day02.ex
diff options
context:
space:
mode:
Diffstat (limited to 'aoc-2019-elixir/lib/day02.ex')
-rw-r--r--aoc-2019-elixir/lib/day02.ex65
1 files changed, 65 insertions, 0 deletions
diff --git a/aoc-2019-elixir/lib/day02.ex b/aoc-2019-elixir/lib/day02.ex
new file mode 100644
index 0000000..46f64bd
--- /dev/null
+++ b/aoc-2019-elixir/lib/day02.ex
@@ -0,0 +1,65 @@
+defmodule Day02 do
+ @add_opcode 1
+ @mul_opcode 2
+ @ret_opcode 99
+ @noun_address 1
+ @verb_address 2
+
+ @spec part1(binary) :: list
+ def part1(input) do
+ run(input, 12, 2)
+ end
+
+ @spec part2(binary) :: integer
+ def part2(input) do
+ for(
+ n <- 0..100,
+ v <- 0..100,
+ do: {n, v, run(input, n, v)}
+ )
+ |> Enum.find(&(elem(&1, 2) == 19_690_720))
+ |> then(fn {n, v, _} -> n * 100 + v end)
+ end
+
+ defp run(input, noun, verb) do
+ input
+ |> parse()
+ |> List.replace_at(@noun_address, noun)
+ |> List.replace_at(@verb_address, verb)
+ |> execute()
+ |> hd()
+ end
+
+ defp binary_op(program, op, a, b, out) do
+ program |> List.replace_at(out, op.(Enum.at(program, a), Enum.at(program, b)))
+ end
+
+ defp execute(program, pc \\ 0) do
+ instruction = program |> Enum.drop(pc) |> Enum.take(4)
+
+ case instruction do
+ [@add_opcode, a, b, out] ->
+ program
+ |> binary_op(&+/2, a, b, out)
+ |> execute(pc + 4)
+
+ [@mul_opcode, a, b, out] ->
+ program
+ |> binary_op(&*/2, a, b, out)
+ |> execute(pc + 4)
+
+ [@ret_opcode | _] ->
+ program
+ end
+ end
+
+ defp parse(input) do
+ input
+ |> String.split(",")
+ |> Enum.map(&Util.Integer.parse!/1)
+ end
+end
+
+input = Util.Input.read_text("day02")
+input |> Day02.part1() |> IO.inspect()
+input |> Day02.part2() |> IO.inspect()