diff --git a/Day7.cs b/Day7.cs new file mode 100644 index 0000000..63f5855 --- /dev/null +++ b/Day7.cs @@ -0,0 +1,73 @@ +using aoc2019.lib; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace aoc2019 +{ + internal class Day7 : Day + { + public override int DayNumber => 7; + + private readonly List input; + private readonly IntCodeVM[] Amplifiers = new IntCodeVM[5]; + public Day7() + { + input = Input.First().Split(',').Select(int.Parse).ToList(); + for (var i = 0; i < 5; i++) Amplifiers[i] = new IntCodeVM(input); + } + + + + public override string Part1() + { + int i, largest = 0; + + foreach (var phaseSeq in Enumerable.Range(0, 5).Permute()) + { + i = 0; + foreach (var (vm, phase) in Amplifiers.Zip(phaseSeq)) + { + vm.Reset(); + vm.Run(phase, i); + i = vm.Result; + } + + if (i > largest) + largest = i; + } + + return $"{largest}"; + } + + public override string Part2() + { + int i, largest = 0; + + foreach (var phaseSeq in Enumerable.Range(5, 5).Permute()) + { + i = 0; + foreach (var (vm, phase) in Amplifiers.Zip(phaseSeq)) + { + vm.Reset(); + vm.input.Enqueue(phase); + } + + var vms = new Queue(Amplifiers); + while (vms.Count > 0) + { + var vm = vms.Dequeue(); + var haltType = vm.Run(i); + if (haltType == IntCodeVM.HaltType.Waiting) + vms.Enqueue(vm); + i = vm.Result; + } + + if (i > largest) + largest = i; + } + + return $"{largest}"; + } + } +} diff --git a/aoc2019.csproj b/aoc2019.csproj index b777405..d98bb99 100644 --- a/aoc2019.csproj +++ b/aoc2019.csproj @@ -24,6 +24,9 @@ Always + + Always + diff --git a/input/day7.in b/input/day7.in new file mode 100644 index 0000000..0128ef0 --- /dev/null +++ b/input/day7.in @@ -0,0 +1 @@ +3,8,1001,8,10,8,105,1,0,0,21,46,59,84,93,110,191,272,353,434,99999,3,9,101,2,9,9,102,3,9,9,1001,9,5,9,102,4,9,9,1001,9,4,9,4,9,99,3,9,101,3,9,9,102,5,9,9,4,9,99,3,9,1001,9,4,9,1002,9,2,9,101,2,9,9,102,2,9,9,1001,9,3,9,4,9,99,3,9,1002,9,2,9,4,9,99,3,9,102,2,9,9,1001,9,5,9,1002,9,3,9,4,9,99,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,3,9,101,2,9,9,4,9,3,9,101,2,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,101,2,9,9,4,9,99,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,1,9,4,9,3,9,1001,9,2,9,4,9,3,9,101,1,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,1,9,4,9,3,9,1001,9,2,9,4,9,99,3,9,101,1,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,101,1,9,9,4,9,3,9,101,1,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,1,9,4,9,3,9,102,2,9,9,4,9,3,9,101,1,9,9,4,9,99,3,9,1001,9,1,9,4,9,3,9,102,2,9,9,4,9,3,9,101,1,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,2,9,4,9,3,9,101,1,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,1,9,4,9,3,9,102,2,9,9,4,9,99,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,1,9,4,9,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,101,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,2,9,4,9,99 \ No newline at end of file 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> Permute(this IEnumerable 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 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; + } + } +}