about summary refs log tree commit diff
path: root/advent-of-code/day_5.ex
diff options
context:
space:
mode:
Diffstat (limited to 'advent-of-code/day_5.ex')
-rw-r--r--advent-of-code/day_5.ex50
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