private static async ValueTask <int> CalculateOutputSignalWithFeedbackAsync(IEnumerable <int> phaseSettingInputs, int[] program) { var channel = await Task.WhenAll(phaseSettingInputs.Select(CreateAmplifierInputChannel)); var count = channel.Length; var amp = new Task[count]; for (int i = 0; i < count; ++i) { // get this amplifier's input var input = channel[i]; // connect the output to the next amplifier's input var output = channel[(i + 1) % channel.Length]; // run the program amp[i] = IntcodeMachine.RunProgramAsync(program, input.Reader, output.Writer); } // send initial input to the first amp await channel.First().Writer.WriteAsync(0); // wait for all of the programs to finish await Task.WhenAll(amp); // retrieve the final output from the input of the first amp return(await channel.First().Reader.ReadAsync()); }
public static async Task RunProgramAsync( int[] program, ChannelReader <int> input, ChannelWriter <int> output, CancellationToken cancellationToken = default, bool complete = true) { try { var vm = new IntcodeMachine(program, input, output); await vm.StepUntilHalted(cancellationToken); } catch (Exception ex) { if (complete) { output.TryComplete(ex); } } finally { if (complete) { output.TryComplete(); } } }
private static int CalculateOutputSignal(IEnumerable <int> phaseSettingInputs, int[] program) => phaseSettingInputs.Aggregate(0, (prev, phase) => IntcodeMachine.RunProgram(program, new[] { phase, prev }).Single());