diff options
author | William Carroll <wpcarro@gmail.com> | 2020-01-29T14·43+0000 |
---|---|---|
committer | William Carroll <wpcarro@gmail.com> | 2020-01-29T14·43+0000 |
commit | 5c9079a41059e077f2b71b68eb83ff9fcb2e38d1 (patch) | |
tree | dce7e3566b04213228fb3c92fc593ca18841d972 /advent-of-code/day_5.ex | |
parent | fb9380ba268b3cd27372acadb87b14cc96163374 (diff) |
Splice ./universe directory into ./
Manually merging: - README.md: I added the description from universe/README.md into the heading of dotfiles/README.md. - .envrc: dotfiles/.envrc was a superset of universe/.envrc - .gitignore: Adding some of the ignored patterns from universe/.gitignore to dotfiles/.gitignore Everything else here should be a simple rename.
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 |