public static void Main(string[] args) { Console.WriteLine("Running Main"); /* * var test1FbAmplifierInput = new long[] {3,26,1001,26,-4,26,3,27,1002,27,2,27,1,27,26,27,4,27,1001,28,-1,28,1005,28,6,99,0,0,5}; * Console.WriteLine("Feedback Test 1 Result {0} from {2} - Expected {1}", * RunFeedbackAmplifier(test1FbAmplifierInput, out var maxOutputCombinationFbTest1), 139629729, string.Join(",", maxOutputCombinationFbTest1)); * * var test2FbAmplifierInput = new long[] {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}; * Console.WriteLine("Feedback Test 2 Result {0} from {2} - Expected {1}", * RunFeedbackAmplifier(test2FbAmplifierInput, out var maxOutputCombinationFbTest2), 18216, string.Join(",", maxOutputCombinationFbTest2)); * * var part2Output = RunFeedbackAmplifier((long[])Day7Input.Clone(), out var part2OutputCombination); * Console.WriteLine("Maximum feedback amplifier output achieved at {0} using combination {1}", * part2Output, string.Join(",",part2OutputCombination.ToArray())); */ //Day 9 var computer = new IntComputer((long[])Day9Program.Clone()); var input = new IntComputerInput(1); computer.Connector = new OutputPrinter(); computer.Run(input); Console.WriteLine($"Day 9 part 1 final output: {computer.GetOutput()}"); var computer2 = new IntComputer((long[])Day9Program.Clone()); var input2 = new IntComputerInput(2); computer2.Connector = new OutputPrinter(); computer2.Run(input2); Console.WriteLine($"Day 9 part 2 final output: {computer2.GetOutput()}"); }
private static long RunFeedbackAmplifier(long[] computerInput, out List <long> maxOutputCombination) { var phaseCombinations = GenerateLists(new List <long>(), new List <long>() { 5, 6, 7, 8, 9 }); var maxOutput = long.MinValue; maxOutputCombination = new List <long>(); var combinationCounter = 0; foreach (var phaseCombination in phaseCombinations) { Console.WriteLine("Trying combination {0}", combinationCounter++); var lastAmplifier = new IntComputer(new long[] { 99 }); var firstInput = new IntComputerInput(); var amplifierThreads = new List <Thread>(); foreach (var phase in phaseCombination) { var amplifier = new IntComputer((long[])computerInput.Clone()); var input = new IntComputerInput(phase); if (amplifierThreads.Count == 0) { input.AddValue(0); firstInput = input; } else if (amplifierThreads.Count == 4) { lastAmplifier.Connector = input; amplifier.Connector = firstInput; } else { lastAmplifier.Connector = input; } var newRunThread = new Thread(() => amplifier.Run(input)); amplifierThreads.Add(newRunThread); newRunThread.Start(); lastAmplifier = amplifier; } foreach (var thread in amplifierThreads) { thread.Join(); } if (lastAmplifier.GetOutput() > maxOutput) { maxOutput = lastAmplifier.GetOutput(); maxOutputCombination = phaseCombination; } } return(maxOutput); }
public long Run(IntComputerInput input, bool debug = false) { long position = 0; if (debug) { Console.WriteLine("Position: " + position + " Computer: " + string.Join(",", _intComputer)); } while (true) { var instruction = _intComputer[position++]; // opcode is the right two digits of the instruction // modes are leftmost digits once the instruction code is taken away var modes = ValidateModes(instruction / 100); instruction %= 100; long result; switch (instruction) { case 1: if (debug) { Console.WriteLine("instruction is addition"); } result = GetOperand(modes[0], position++) + GetOperand(modes[1], position++); SetOperand(modes[2], position++, result, debug); break; case 2: if (debug) { Console.WriteLine("instruction is multiplication"); } result = GetOperand(modes[0], position++) * GetOperand(modes[1], position++); SetOperand(modes[2], position++, result, debug); break; case 3: if (debug) { Console.WriteLine("instruction is input"); } SetOperand(modes[0], position++, input.GetNextInput(), debug); break; case 4: _outputValue = GetOperand(modes[0], position++); if (debug) { Console.WriteLine("instruction is output, value now: " + _outputValue); } Connector?.AddValue(_outputValue); break; case 5: if (debug) { Console.WriteLine("instruction is jump-if-true (non-zero)"); } if (GetOperand(modes[0], position++) != 0) { position = GetOperand(modes[1], position); } else { position++; //skip the second parameter } break; case 6: if (debug) { Console.WriteLine("instruction is jump-if-false (zero)"); } if (GetOperand(modes[0], position++) == 0) { position = GetOperand(modes[1], position); } else { position++; //skip the second parameter } break; case 7: if (debug) { Console.WriteLine("instruction is less-than"); } result = GetOperand(modes[0], position++) < GetOperand(modes[1], position++) ? 1 : 0; SetOperand(modes[2], position++, result, debug); break; case 8: if (debug) { Console.WriteLine("instruction is equals"); } result = GetOperand(modes[0], position++) == GetOperand(modes[1], position++) ? 1 : 0; SetOperand(modes[2], position++, result, debug); break; case 9: if (debug) { Console.WriteLine("instruction is adjust-relative-base"); } _relativeBase += GetOperand(modes[0], position++); break; case 99: if (debug) { Console.WriteLine("instruction is exit"); } return(_outputValue); default: throw new InvalidOperationException("Unexpected instruction in intComputer at position " + // position has already been incremented, so -1 to show original position $"{position-1} value {instruction } with modes " + string.Join(',', modes)); } if (debug) { Console.WriteLine($"Position: {position}, Relative Base {_relativeBase}, Computer: " + string.Join(",", _intComputer)); } } }