diff options
Diffstat (limited to 'advent-of-code/day_5.ex')
-rw-r--r-- | advent-of-code/day_5.ex | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/advent-of-code/day_5.ex b/advent-of-code/day_5.ex new file mode 100644 index 000000000000..807e3c9177be --- /dev/null +++ b/advent-of-code/day_5.ex @@ -0,0 +1,50 @@ +defmodule Interpretter do + def interpret_param({mode, x}, xs) do + case mode do + :positional -> Enum.at(xs, x) + :immediate -> x + end + end + + # Perhaps I can model the intepretter after Forth and make it a stack-based + # interpretter with an emphasis on debugability, introspection. + def interpret(i, xs) do + stack = [] + op = Enum.at(xs, i) + + # map instructions into an intermediate representation (i.e. IR) where the + # opcodes are mapped into atoms and the arguments are mapped into references + # or literals. + + instructions = + %{'01' => :add, + '02' => :multiply, + '03' => :input, + '04' => :output, + '05' => :jump_if_true, + '06' => :jump_if_false, + '07' => :less_than, + '08' => :equal_to, + '99' => :return} + + case xs do + [:add, a, b, {:positional, out} | rest] -> + a = interpret_param(a, xs) + b = interpret_param(b, xs) + Interpretter.interpret(i + 3, List.insert_at(xs, out, a + b)) + + [:multiply, a, b, {:positional, out} | rest] -> + a = interpret_param(a, xs) + b = interpret_param(b, xs) + Interpretter.interpret(i + 3, List.insert_at(xs, out, a * b)) + + [:input, a | rest] -> nil + [:output, a | rest] -> nil + [:jump_if_true, a, b | rest] -> nil + [:jump_if_false, a, b | rest] -> nil + [:less_than, a, b, out | rest] -> nil + [:equal_to, a, b, out | rest] -> nil + [:return | _rest] -> nil + end + end +end |