public (ImmutableIntCodeMachine iicm, long[] output) Run(params long[] input) { var immutableIntCodeMachine = new ImmutableIntCodeMachine(this.icm.Clone()); return(immutableIntCodeMachine, immutableIntCodeMachine.icm.Run(input)); }
static void Main(string[] args) { System.Console.WriteLine("Day 17"); string filename = "input"; IntCodeMachine icm; using (StreamReader sr = new StreamReader(filename)) { int[] data = sr.ReadLine().Trim().Split(",").Select(s => Int32.Parse(s)).ToArray(); icm = new IntCodeMachine("ASCII", data); } // Read the grid (and print it) int output; StringBuilder sb = new StringBuilder(); icm.Reset(); while (icm.active) { if (!icm.Next(new int[] {}, out output)) { break; } sb.Append((char)output); } string view = sb.ToString().Trim(); char[][] grid = view.Split().Select(s => s.ToCharArray()).ToArray(); // System.Console.WriteLine(view); // Part 1 int sum = 0; for (int y = 1; y < grid.Length - 1; y++) { for (int x = 1; x < grid[y].Length - 1; x++) { if (grid[y][x] == '#' && grid[y - 1][x] == '#' && grid[y + 1][x] == '#' && grid[y][x - 1] == '#' && grid[y][x + 1] == '#') { sum += x * y; } } } System.Console.WriteLine($"1. {sum}"); // Part 2 // I mostly did this by eye & hand, from the grid drawn by the code above // A B A B C B A C B C // // A L12L08R10R10 // B L06L04L12 // C R10L08L04R10 // => // 76,44,49,50,44,76,44,56,44,82,44,49,48,44,82,44,49,48 // 76,44,54,44,76,44,52,44,76,44,49,50 // 82,44,49,48,44,76,44,56,44,76,44,52,44,82,44,49,48 // // A 65 // B 66 // C 67 // L 76 // R 82 // , 44 // \n 10 // n 110 // y 121 int[] main = new int[] { 65, 44, 66, 44, 65, 44, 66, 44, 67, 44, 66, 44, 65, 44, 67, 44, 66, 44, 67, 10 }; int[] A = new int[] { 76, 44, 49, 50, 44, 76, 44, 56, 44, 82, 44, 49, 48, 44, 82, 44, 49, 48, 10 }; int[] B = new int[] { 76, 44, 54, 44, 76, 44, 52, 44, 76, 44, 49, 50, 10 }; int[] C = new int[] { 82, 44, 49, 48, 44, 76, 44, 56, 44, 76, 44, 52, 44, 82, 44, 49, 48, 10 }; int[] video = new int[] { 110, 10 }; inputData = new List <int>() .Concat(main) .Concat(A) .Concat(B) .Concat(C) .Concat(video) .ToArray(); icm.Reset(); icm.SetRegister(0, 2); icm.InputReader += new IcmInputReader(InputWriter); icm.OutputWriter += new IcmOutputWriter(OutputReader); icm.Run(); // Read output sb.Clear(); foreach (int item in outputData) { sb.Append((char)item); } System.Console.WriteLine(sb.ToString()); System.Console.WriteLine(outputData.Last()); }
static void Main(string[] args) { const int N_AMP = 5; // Number of amplifiers // Read input and create IntCode instances string filename = @"input"; IntCodeMachine amp; IntCodeMachine[] amplifier; using (StreamReader sr = new StreamReader(filename)) { // All data is on the first line int[] data = sr.ReadLine().Trim().Split(",").Select(s => Int32.Parse(s)).ToArray(); // Only 1 IntCode is needed, as they all use the same instructions, and they reset // their state between runs anyway. Therefor we can reuse the amplifier. amp = new IntCodeMachine("Part1-test", data); // For part 2, we do need distinct amplifiers amplifier = new IntCodeMachine[N_AMP]; for (int i = 0; i < N_AMP; i++) { amplifier[i] = new IntCodeMachine(i.ToString(), data); } } System.Console.WriteLine("Day 07"); int[] output = new int[N_AMP]; int thrusterOutput = 0; for (int a = 0; a < N_AMP; a++) { output[0] = amp.Run(new int[] { a, 0 }, true); for (int b = 0; b < N_AMP; b++) { if (b == a) { continue; } output[1] = amp.Run(new int[] { b, output[0] }, true); for (int c = 0; c < N_AMP; c++) { if (c == a || c == b) { continue; } output[2] = amp.Run(new int[] { c, output[1] }, true); for (int d = 0; d < N_AMP; d++) { if (d == a || d == b || d == c) { continue; } output[3] = amp.Run(new int[] { d, output[2] }, true); int e = 10 - a - b - c - d; // No loop needed! output[4] = amp.Run(new int[] { e, output[3] }, true); if (output[4] > thrusterOutput) { thrusterOutput = output[4]; } } } } } System.Console.WriteLine($"1. {thrusterOutput}"); // Part 2 thrusterOutput = 0; int intermediateResult = 0; int[] phase, bestPhase = null; for (int a = 5; a < 10; a++) { for (int b = 5; b < 10; b++) { if (b == a) { continue; } for (int c = 5; c < 10; c++) { if (c == a || c == b) { continue; } for (int d = 5; d < 10; d++) { if (d == a || d == b || d == c) { continue; } int e = 35 - a - b - c - d; // No loop needed! // Starting the machines also resets their state phase = new int[] { a, b, c, d, e }; amplifier[0].Start(new int[] { phase[0], 0 }, out output[0]); amplifier[1].Start(new int[] { phase[1], output[0] }, out output[1]); amplifier[2].Start(new int[] { phase[2], output[1] }, out output[2]); amplifier[3].Start(new int[] { phase[3], output[2] }, out output[3]); if (amplifier[4].Start(new int[] { phase[4], output[3] }, out output[4])) { intermediateResult = output[4]; } while (amplifier[0].active) { amplifier[0].Next(new int[] { output[4] }, out output[0]); amplifier[1].Next(new int[] { output[0] }, out output[1]); amplifier[2].Next(new int[] { output[1] }, out output[2]); amplifier[3].Next(new int[] { output[2] }, out output[3]); // output is always overwritten, even if the machine has no output // Next() return true iff the machine actually has output (and the // value is meaningful) if (amplifier[4].Next(new int[] { output[3] }, out output[4])) { intermediateResult = output[4]; } } if (intermediateResult > thrusterOutput) { thrusterOutput = intermediateResult; bestPhase = phase; } } } } } System.Console.WriteLine($"2. {thrusterOutput} [{bestPhase[0]},{bestPhase[1]},{bestPhase[2]},{bestPhase[3]},{bestPhase[4]}]"); }