diff options
author | Ben Harris <ben@tilde.team> | 2019-12-07 03:57:17 -0500 |
---|---|---|
committer | Ben Harris <ben@tilde.team> | 2019-12-07 03:57:17 -0500 |
commit | 9dcee6f61d0c856fd9c334445db6ca030a5a6403 (patch) | |
tree | 9a7ac3bd7fdb2ddab8244eefd41828ba65c27657 /lib | |
parent | 5759cac12d42e92d7f07aa54d4bf376f2e63995b (diff) |
day 7
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Extensions.cs | 15 | ||||
-rw-r--r-- | lib/IntCodeVM.cs | 94 |
2 files changed, 109 insertions, 0 deletions
diff --git a/lib/Extensions.cs b/lib/Extensions.cs new file mode 100644 index 0000000..52863d0 --- /dev/null +++ b/lib/Extensions.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace aoc2019.lib +{ + public static class Extensions + { + public static IEnumerable<IEnumerable<T>> Permute<T>(this IEnumerable<T> list) + { + if (list.Count() == 1) return new[] { list }; + return list.SelectMany(t => Permute(list.Where(x => !x.Equals(t))), (v, p) => p.Prepend(v)); + } + } +} 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<int> v; + public Queue<int> input, output; + private readonly List<int> program; + + public IntCodeVM(List<int> tape) + { + i = 0; + program = tape; + v = tape; + input = new Queue<int>(); + output = new Queue<int>(); + } + + 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; + } + } +} |