diff options
author | William Carroll <wpcarro@gmail.com> | 2020-01-15T14·21+0000 |
---|---|---|
committer | William Carroll <wpcarro@gmail.com> | 2020-01-15T14·21+0000 |
commit | 456d358cd7b0701b0ca2b8571d61f255d3da1488 (patch) | |
tree | cb4aac65aa1c6600f6ef773ffd58cd8579bb5084 /advent-of-code/day_5.ex | |
parent | d480b6f08b8a6b32c58e5bbdf2f193432c50fb97 (diff) |
Upload my 2019 Advent of Code attempts
Well, unexpectedly (perhaps naively so), I only made it to Day 7. I created these before I stumbled upon the idea of the mono-repository; otherwise, I like to think I would have more granular commits introducing this work.
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 |