예제 #1
0
        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);
        }
예제 #2
0
        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);
                    break;

                case 2:
                    if (debug)
                    {
                        Console.WriteLine("instruction is multiplication");
                    }
                    result = GetOperand(modes[0], position++) * GetOperand(modes[1], position++);
                    SetOperand(modes[2], position++, result);
                    break;

                case 3:
                    if (debug)
                    {
                        Console.WriteLine("instruction is input");
                    }
                    SetOperand(modes[0], position++, input.GetNextInput());
                    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);
                    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);
                    break;

                case 99:
                    if (debug)
                    {
                        Console.WriteLine("instruction is exit");
                    }
                    return(_outputValue);

                default:
                    throw new InvalidOperationException("Unexpected instruction in intComputer at position " +
                                                        position + " value " +
                                                        instruction + " with opcodes " + modes);
                }
                if (debug)
                {
                    Console.WriteLine("Position: " + position + " Computer: " + string.Join(",", _intComputer));
                }
            }
        }