diff --git a/Day7/Day7.cs b/Day7/Day7.cs index a380701..ee84a30 100644 --- a/Day7/Day7.cs +++ b/Day7/Day7.cs @@ -9,23 +9,34 @@ namespace Advent public static void Execute() { var program = "3,8,1001,8,10,8,105,1,0,0,21,34,43,64,85,98,179,260,341,422,99999,3,9,1001,9,3,9,102,3,9,9,4,9,99,3,9,102,5,9,9,4,9,99,3,9,1001,9,2,9,1002,9,4,9,1001,9,3,9,1002,9,4,9,4,9,99,3,9,1001,9,3,9,102,3,9,9,101,4,9,9,102,3,9,9,4,9,99,3,9,101,2,9,9,1002,9,3,9,4,9,99,3,9,101,1,9,9,4,9,3,9,1002,9,2,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,102,2,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,1001,9,1,9,4,9,3,9,101,2,9,9,4,9,3,9,1001,9,2,9,4,9,99,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,1001,9,1,9,4,9,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,1002,9,2,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,99,3,9,101,1,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,1001,9,1,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,101,1,9,9,4,9,99,3,9,101,1,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,102,2,9,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,99,3,9,101,2,9,9,4,9,3,9,101,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,101,2,9,9,4,9,3,9,102,2,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,102,2,9,9,4,9,99"; - var phaseList = GetPhaseList(); + //var program = "3,52,1001,52,-5,52,3,53,1,52,56,54,1007,54,5,55,1005,55,26,1001,54,-5,54,1105,1,12,1,53,54,53,1008,54,0,55,1001,55,1,55,2,53,55,53,4,53,1001,56,-1,56,1005,56,6,99,0,0,0,0,10"; + //var phaseList = new List { "9,7,8,5,6".Split(',').Select(c => int.Parse(c.ToString())).ToArray() }; + int? max = 0; - var amp = new IntcodeComputer(); - foreach (var phases in phaseList) { - var output = amp.Execute(new[] { phases[0], 0 }, program); - output = amp.Execute(new[] { phases[1], output.GetValueOrDefault(0) }, program); - output = amp.Execute(new[] { phases[2], output.GetValueOrDefault(0) }, program); - output = amp.Execute(new[] { phases[3], output.GetValueOrDefault(0) }, program); - output = amp.Execute(new[] { phases[4], output.GetValueOrDefault(0) }, program); + var value = 0; - if (output > max) - max = output; + var amp1 = new IntcodeComputer(program, phases[0]); + var amp2 = new IntcodeComputer(program, phases[1]); + var amp3 = new IntcodeComputer(program, phases[2]); + var amp4 = new IntcodeComputer(program, phases[3]); + var amp5 = new IntcodeComputer(program, phases[4]); + + while (!amp5.Halted) + { + value = amp1.Execute(value); + value = amp2.Execute(value); + value = amp3.Execute(value); + value = amp4.Execute(value); + value = amp5.Execute(value); + + if (value > max) + max = value; + } } Console.WriteLine(max); @@ -41,7 +52,7 @@ namespace Advent { var phases = i.ToString("00000").ToCharArray().Select(c => int.Parse(c.ToString())).ToArray(); - if (phases.All(p => p <= 4) && phases.Distinct().Count() == 5) + if (phases.All(p => p >= 5) && phases.Distinct().Count() == 5) phaseList.Add(phases); } diff --git a/IntcodeComputer.cs b/IntcodeComputer.cs index df2f8f8..8292cf3 100644 --- a/IntcodeComputer.cs +++ b/IntcodeComputer.cs @@ -12,116 +12,128 @@ namespace Advent Immediate } + private readonly int[] _memory; + private readonly int _phase; + + private bool _setPhase; + private int _instructionPointer; + private int _output; + + public bool Halted { get; private set; } + + public IntcodeComputer(string memoryString, int phase) + { + _memory = memoryString.Split(',').Select(int.Parse).ToArray(); + _phase = phase; + } + private static int GetValue(IReadOnlyList codes, int parameter, ParameterMode mode) { return mode == ParameterMode.Immediate ? parameter : codes[parameter]; } - public int? Execute(int[] inputs, string commands) + public int Execute(int input) { - var codes = commands.Split(',').Select(int.Parse).ToArray(); - - var position = 0; - var done = false; - var inputIndex = 0; - int? output = null; - - while (!done) + while (!Halted) { - var (mode1, mode2, mode3, opCode) = ParseOpCode(codes[position]); + var (mode1, mode2, mode3, opCode) = ParseOpCode(_memory[_instructionPointer]); switch (opCode) { case 1: - codes[codes[position + 3]] = GetValue(codes, codes[position + 1], mode1) + GetValue(codes, codes[position + 2], mode2); + _memory[_memory[_instructionPointer + 3]] = GetValue(_memory, _memory[_instructionPointer + 1], mode1) + GetValue(_memory, _memory[_instructionPointer + 2], mode2); - position += 4; + _instructionPointer += 4; break; case 2: - codes[codes[position + 3]] = GetValue(codes, codes[position + 1], mode1) * GetValue(codes, codes[position + 2], mode2); + _memory[_memory[_instructionPointer + 3]] = GetValue(_memory, _memory[_instructionPointer + 1], mode1) * GetValue(_memory, _memory[_instructionPointer + 2], mode2); - position += 4; + _instructionPointer += 4; break; case 3: - codes[codes[position + 1]] = inputs[inputIndex++]; + var inputValue = _setPhase ? input : _phase; - position += 2; + _setPhase = true; + + _memory[_memory[_instructionPointer + 1]] = inputValue; + + _instructionPointer += 2; break; case 4: - output = GetValue(codes, codes[position + 1], ParameterMode.Position); + _output = GetValue(_memory, _memory[_instructionPointer + 1], ParameterMode.Position); - position += 2; + _instructionPointer += 2; - break; + return _output; case 5: { - var value = GetValue(codes, codes[position + 1], mode1); + var value = GetValue(_memory, _memory[_instructionPointer + 1], mode1); if (value != 0) - position = GetValue(codes, codes[position + 2], mode2); + _instructionPointer = GetValue(_memory, _memory[_instructionPointer + 2], mode2); else - position += 3; + _instructionPointer += 3; } break; case 6: { - var value = GetValue(codes, codes[position + 1], mode1); + var value = GetValue(_memory, _memory[_instructionPointer + 1], mode1); if (value == 0) - position = GetValue(codes, codes[position + 2], mode2); + _instructionPointer = GetValue(_memory, _memory[_instructionPointer + 2], mode2); else - position += 3; + _instructionPointer += 3; } break; case 7: { - var value1 = GetValue(codes, codes[position + 1], mode1); - var value2 = GetValue(codes, codes[position + 2], mode2); + var value1 = GetValue(_memory, _memory[_instructionPointer + 1], mode1); + var value2 = GetValue(_memory, _memory[_instructionPointer + 2], mode2); if (value1 < value2) - codes[codes[position + 3]] = 1; + _memory[_memory[_instructionPointer + 3]] = 1; else - codes[codes[position + 3]] = 0; + _memory[_memory[_instructionPointer + 3]] = 0; - position += 4; + _instructionPointer += 4; } break; case 8: { - var value1 = GetValue(codes, codes[position + 1], mode1); - var value2 = GetValue(codes, codes[position + 2], mode2); + var value1 = GetValue(_memory, _memory[_instructionPointer + 1], mode1); + var value2 = GetValue(_memory, _memory[_instructionPointer + 2], mode2); if (value1 == value2) - codes[codes[position + 3]] = 1; + _memory[_memory[_instructionPointer + 3]] = 1; else - codes[codes[position + 3]] = 0; + _memory[_memory[_instructionPointer + 3]] = 0; - position += 4; + _instructionPointer += 4; } break; case 99: - done = true; + Halted = true; - break; + return _output; } } - return output; + return _output; } private static (ParameterMode mode1, ParameterMode mode2, ParameterMode mode3, int opCode) ParseOpCode(int fullOpCode)