public RecursiveProgram(IIntCodeValidator validator, IIntcodeProgramFactory intcodeProgramFactory) { _validator = validator; _intcodeProgramFactory = intcodeProgramFactory; _adder = new AdderProgram(_validator); _multiplier = new MultiplierProgram(_validator); }
public int ComputeSignal(IList <IntCodeValue> phaseSettings, int[] data) { var amplifiers = new IIntCodeProgram[phaseSettings.Count]; var firstInput = new BlockingCollection <IntCodeValue>(); for (var i = 0; i < amplifiers.Length; i++) { var input = i == 0 ? firstInput : amplifiers[i - 1].Output; input.Add(phaseSettings[i]); if (_feedbackLoop && i == amplifiers.Length - 1) { amplifiers[i] = IntCodeProgram.New(input, firstInput); } else { amplifiers[i] = IntCodeProgram.New(input); } } var tasks = amplifiers.Select(program => Task.Factory.StartNew(() => program.Compute(data.ToArray()), TaskCreationOptions.LongRunning)); firstInput.Add(IntCodeValue.FromInt(0)); Task.WhenAll(tasks).Wait(TimeoutMs); var took = amplifiers.Last().Output.TryTake(out var signal); if (!took) { throw new InvalidOperationException("No output found."); } if (amplifiers.Last().Output.Count != 0) { throw new InvalidOperationException("There's still output in the last amplifier."); } return((int)signal); }