From 9dcee6f61d0c856fd9c334445db6ca030a5a6403 Mon Sep 17 00:00:00 2001 From: Ben Harris Date: Sat, 7 Dec 2019 03:57:17 -0500 Subject: day 7 --- lib/IntCodeVM.cs | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 lib/IntCodeVM.cs (limited to 'lib/IntCodeVM.cs') diff --git a/lib/IntCodeVM.cs b/lib/IntCodeVM.cs new file mode 100644 index 0000000..de2b98a --- /dev/null +++ b/lib/IntCodeVM.cs @@ -0,0 +1,94 @@ +using System.Collections.Generic; +using System.Linq; + +namespace aoc2019.lib +{ + public class IntCodeVM + { + private int i; + public List v; + public Queue input, output; + private readonly List program; + + public IntCodeVM(List tape) + { + i = 0; + program = tape; + v = tape; + input = new Queue(); + output = new Queue(); + } + + public enum HaltType + { + Terminate, + Waiting + } + + enum Op : int + { + ADD = 1, MUL = 2, INPUT = 3, OUTPUT = 4, JMP = 5, JNE = 6, LT = 7, EQ = 8, HALT = 99 + } + + public void Reset() + { + i = 0; + v = program; + input.Clear(); + output.Clear(); + } + + public int Result => output.Dequeue(); + + public HaltType Run(params int[] additionalInput) + { + foreach (var i in additionalInput) input.Enqueue(i); + return Run(); + } + public HaltType Run() + { + while (i < v.Count) + { + int Val(int mode, int val) => + mode == 0 ? v[val] : val; + + int Val1() => Val(v[i] / 100 % 10, v[i + 1]); + int Val2() => Val(v[i] / 1000, v[i + 2]); + + switch ((Op)(v[i] % 100)) + { + case Op.ADD: + v[v[i + 3]] = Val1() + Val2(); + i += 4; break; + case Op.MUL: + v[v[i + 3]] = Val1() * Val2(); + i += 4; break; + case Op.INPUT: + if (!input.Any()) + return HaltType.Waiting; + v[v[i + 1]] = input.Dequeue(); + i += 2; break; + case Op.OUTPUT: + output.Enqueue(Val1()); + i += 2; break; + case Op.JMP: + i = Val1() == 0 ? i + 3 : Val2(); + break; + case Op.JNE: + i = Val1() != 0 ? i + 3 : Val2(); + break; + case Op.LT: + v[v[i + 3]] = Val1() < Val2() ? 1 : 0; + i += 4; break; + case Op.EQ: + v[v[i + 3]] = Val1() == Val2() ? 1 : 0; + i += 4; break; + case Op.HALT: + return HaltType.Terminate; + } + } + + return HaltType.Terminate; + } + } +} -- cgit 1.4.1