/// <summary> /// Runs the specified Intcode program. /// </summary> /// <param name="program">The Intcode program to run.</param> /// <param name="adjust">Whether to adjust the state for <c>1202 program alarm</c> before running.</param> /// <param name="cancellationToken">The optional cancellation token to use.</param> /// <returns> /// The memory values of the program once run. /// </returns> public static async Task <IReadOnlyList <long> > RunProgramAsync( string program, bool adjust = false, CancellationToken cancellationToken = default) { long[] instructions = IntcodeVM.ParseProgram(program); if (adjust) { instructions[1] = 12; instructions[2] = 2; } var vm = new IntcodeVM(instructions) { Input = await ChannelHelpers.CreateReaderAsync(new[] { 0L }, cancellationToken), }; if (!await vm.RunAsync(cancellationToken)) { throw new PuzzleException("Failed to run program."); } return(vm.Memory().ToArray()); }
protected override object SolvePart1() { var vm = new IntcodeVM(Input[0]); var result = vm.Execute(); return(vm.Output.Where((t, i) => i % 3 == 2).Count(x => x == 2)); }
/// <summary> /// Runs the specified Intcode program. /// </summary> /// <param name="program">The Intcode program to run.</param> /// <param name="input">The input to the program.</param> /// <param name="cancellationToken">The optional cancellation token to use.</param> /// <returns> /// The keycode output by the program. /// </returns> public static async Task <IReadOnlyList <long> > RunProgramAsync( string program, long?input = null, CancellationToken cancellationToken = default) { long[] instructions = IntcodeVM.ParseProgram(program); var channel = Channel.CreateUnbounded <long>(); if (input.HasValue) { await channel.Writer.WriteAsync(input.Value, cancellationToken); } channel.Writer.Complete(); var vm = new IntcodeVM(instructions, 2_000) { Input = channel.Reader, }; if (!await vm.RunAsync(cancellationToken)) { throw new PuzzleException("Failed to run program."); } return(await vm.Output.ToListAsync(cancellationToken)); }
protected override object SolvePart1() { var position = (0, 0); var direction = RobotDirection.Up; var panels = new Dictionary <(int, int), long>(); var vm = new IntcodeVM(Input[0]); var status = IntcodeVM.HaltMode.Unknown; while (status != IntcodeVM.HaltMode.Terminated) { var currentPanelColor = panels.ContainsKey(position) ? panels[position] : 0L; status = vm.Execute(new long[] { currentPanelColor }); var panelColor = vm.Output.Dequeue(); var turn = (int)vm.Output.Dequeue(); if (panels.ContainsKey(position)) { panels[position] = panelColor; } else { panels.Add(position, panelColor); } direction = TurnRobot(direction, turn); position = MoveRobot(direction, position); } return(panels.Count); }
protected override object SolvePart2() { var vm = new IntcodeVM(Input[0]); for (var noun = 0; noun < 100; noun++) { for (var verb = 0; verb < 100; verb++) { vm.Write(1, noun); vm.Write(2, verb); vm.Execute(); if (vm.Read(0) != 19690720) { vm.ResetVM(); continue; } return(100 * noun + verb); } } return(null); }
/// <summary> /// Gets the number of block tiles on the screen after the game is run. /// </summary> /// <param name="program">The Intcode program to run.</param> /// <param name="cancellationToken">The cancellation token to use.</param> /// <returns> /// The number of block tiles on the screen. /// </returns> public static async Task <(long BlockTileCount, long Score)> PlayGameAsync( string program, CancellationToken cancellationToken) { long[] instructions = IntcodeVM.ParseProgram(program); var vm = new IntcodeVM(instructions, 10_000) { Input = await ChannelHelpers.CreateReaderAsync(new[] { 2L }, cancellationToken), }; if (!await vm.RunAsync(cancellationToken)) { throw new PuzzleException("Failed to run program."); } var outputs = await vm.Output.ToListAsync(cancellationToken); var grid = new Dictionary <Point, int>(outputs.Count); long score = 0; for (int i = 0; i < outputs.Count; i += 3) { long x = outputs[i]; long y = outputs[i + 1]; long tileId = outputs[i + 2]; if (x == 1 && y == 0) { score = tileId; } else { grid[new((int)x, (int)y)] = (int)tileId;
protected override object SolvePart1() { var vm = new IntcodeVM(Input[0]); vm.Execute(new long[] { 1 }); return(vm.Output.First()); }
public Droid(long x, long y, long steps, IntcodeVM vm, bool finished = false) { X = x; Y = y; Steps = steps; VM = vm ?? throw new ArgumentNullException(nameof(vm)); Finsihed = finished; }
protected override object SolvePart1() { var vm = new IntcodeVM(Input[0]); vm.Write(1, 12); vm.Write(2, 2); vm.Execute(); return(vm.Read(0)); }
/// <summary> /// Runs the specified Intcode program as an asynchronous operation. /// </summary> /// <param name="program">The Intcode program to run.</param> /// <param name="input">The input to the program.</param> /// <param name="cancellationToken">The cancellation token to use.</param> /// <returns> /// The output of the program once run. /// </returns> internal static async Task <IReadOnlyList <long> > RunAsync( IEnumerable <long> program, long[] input, CancellationToken cancellationToken) { var vm = new IntcodeVM(program) { Input = await ChannelHelpers.CreateReaderAsync(input, cancellationToken), }; if (!await vm.RunAsync(cancellationToken)) { throw new PuzzleException("Failed to run program."); } return(await vm.Output.ToListAsync(cancellationToken)); }
protected override object SolvePart1() { var maxOutput = 0L; var phaseSettings = new long[] { 0, 1, 2, 3, 4 }; var vm = new IntcodeVM(Input[0]); do { // Amp A vm.ResetVM(); var input = new[] { phaseSettings[0], 0 }; vm.Execute(input); var output = vm.Output.ToArray(); // Amp B vm.ResetVM(); input = new[] { phaseSettings[1], output[0] }; vm.Execute(input); output = vm.Output.ToArray(); // Amp C vm.ResetVM(); input = new[] { phaseSettings[2], output[0] }; vm.Execute(input); output = vm.Output.ToArray(); // Amp D vm.ResetVM(); input = new[] { phaseSettings[3], output[0] }; vm.Execute(input); output = vm.Output.ToArray(); // Amp E vm.ResetVM(); input = new[] { phaseSettings[4], output[0] }; vm.Execute(input); output = vm.Output.ToArray(); if (output[0] > maxOutput) { maxOutput = output[0]; } } while (phaseSettings.NextPermutation()); return(maxOutput); }
/// <summary> /// Runs the specified Intcode program. /// </summary> /// <param name="program">The Intcode program to run.</param> /// <param name="input">The input to the program.</param> /// <param name="cancellationToken">The cancellation token to use.</param> /// <returns> /// The diagnostic code output by the program. /// </returns> public static async Task <long> RunProgramAsync( string program, long input, CancellationToken cancellationToken) { long[] instructions = IntcodeVM.ParseProgram(program); var vm = new IntcodeVM(instructions) { Input = await ChannelHelpers.CreateReaderAsync(new[] { input }, cancellationToken), }; if (!await vm.RunAsync(cancellationToken)) { throw new PuzzleException("Failed to run program."); } var outputs = await vm.Output.ToListAsync(cancellationToken); return(outputs.Count == 0 ? 0 : outputs[^ 1]);
protected override object SolvePart1() { var map = new Dictionary <(int X, int Y), char>(); var vm = new IntcodeVM(Input[0]); var(x, y) = (0, 0); var vmStatus = vm.Execute(); while (vm.Output.Count > 0) { var o = vm.Output.Dequeue(); var c = (char)o; Console.Write(c); if (o == 10) { (x, y) = (0, y + 1); } else { map[(x++, y)] = c;
protected override object SolvePart2() { var vm = new IntcodeVM(Input[0]); vm.Write(0, 2); var paddle = (X : -1L, Y : -1L); var ball = (X : -1L, Y : -1L); while (vm.Execute() != IntcodeVM.HaltMode.Terminated) { var(Paddle, Ball, _) = ProcessOutput(vm); if (Paddle.X != -1 && Paddle.Y != -1) { paddle = Paddle; } if (Ball.X != -1 && Ball.Y != -1) { ball = Ball; } if (ball.X < paddle.X) { vm.Input.Enqueue(-1); } else if (ball.X > paddle.X) { vm.Input.Enqueue(1); } else { vm.Input.Enqueue(0); } } var finalState = ProcessOutput(vm); return(finalState.Score); }
/// <summary> /// Creates new VM data from the given IntcodeVM /// </summary> /// <param name="vm">VM to create the data for</param> public VMData(IntcodeVM vm) { this.memory = vm.memory; this.getInput = vm.GetNextInput; this.setOutput = vm.AddOutput; }
protected override object SolvePart2() { var position = (0, 0); var direction = RobotDirection.Up; var panels = new Dictionary <(int, int), long>(); var vm = new IntcodeVM(Input[0]); panels.Add((0, 0), 1L); var status = IntcodeVM.HaltMode.Unknown; while (status != IntcodeVM.HaltMode.Terminated) { var currentPanelColor = panels.ContainsKey(position) ? panels[position] : 0L; status = vm.Execute(new long[] { currentPanelColor }); var panelColor = vm.Output.Dequeue(); var turn = (int)vm.Output.Dequeue(); if (panels.ContainsKey(position)) { panels[position] = panelColor; } else { panels.Add(position, panelColor); } direction = TurnRobot(direction, turn); position = MoveRobot(direction, position); } var minX = panels.Keys.Min(x => x.Item1); var minY = panels.Keys.Min(y => y.Item2); var maxX = panels.Keys.Max(x => x.Item1); var maxY = panels.Keys.Max(y => y.Item2); var imgWidth = maxX - minX + 20; var imgHeight = maxY - minY + 20; using var image = new Bitmap(imgWidth, imgHeight); for (var y = 0; y < imgHeight; y++) { for (var x = 0; x < imgWidth; x++) { image.SetPixel(x, y, Color.Black); } } foreach (var panel in panels) { if (panel.Value == 1) { image.SetPixel(panel.Key.Item1 - minX + 10, panel.Key.Item2 - minY + 10, Color.White); } } image.RotateFlip(RotateFlipType.Rotate270FlipNone); using var bigImage = new Bitmap(image, new Size(image.Width * 4, image.Height * 4)); bigImage.Save(@".\2019\AdventOfCode2019112.png"); using var engine = new TesseractEngine(@".\_ExternalDependencies\tessdata_legacy", "eng", EngineMode.TesseractOnly); using Pix pix = PixConverter.ToPix(bigImage); using var page = engine.Process(pix); return(page.GetText().Trim('\n')); }
private static ((long X, long Y) Paddle, (long X, long Y) Ball, long Score) ProcessOutput(IntcodeVM vm) { var score = 0L; var paddle = (X : -1L, Y : -1L); var ball = (X : -1L, Y : -1L); while (vm.Output.Count > 0) { var(x, y, value) = (vm.Output.Dequeue(), vm.Output.Dequeue(), vm.Output.Dequeue()); if (x == -1 && y == 0) // Score { score = value; } else { switch (value) { case 0: // Empty break; case 1: // Wall break; case 2: // Block break; case 3: // Paddle paddle = (x, y); break; case 4: // Ball ball = (x, y); break; } } } return(paddle, ball, score); }
/// <summary> /// Creates a new Droid with the specified program /// </summary> /// <param name="program">Program on which the droid runs</param> public Droid(IntcodeVM program) => this.program = program;
/// <summary> /// Runs the specified Intcode program. /// </summary> /// <param name="program">The Intcode program to run.</param> /// <param name="useFeedback">Whether to arrange the amplifiers in a feedback loop.</param> /// <param name="cancellationToken">The optional cancellation to oken to use.</param> /// <returns> /// The diagnostic code output by the program. /// </returns> public static async Task <long> RunProgramAsync( string program, bool useFeedback = false, CancellationToken cancellationToken = default) { long[] instructions = IntcodeVM.ParseProgram(program); int[] seed = useFeedback ? new[] { 5, 6, 7, 8, 9 } : new[] { 0, 1, 2, 3, 4 }; var signals = new List <long>(); foreach (var permutation in Maths.GetPermutations(seed)) { long signal = 0; long[] phases = permutation.Select((p) => (long)p).ToArray(); if (!useFeedback) { for (int i = 0; i < phases.Length; i++) { signal = (await IntcodeVM.RunAsync(instructions, new[] { phases[i], signal }, cancellationToken))[0]; } } else { var amplifiers = new IntcodeVM[phases.Length]; var inputs = new Channel <long> [phases.Length]; for (int i = 0; i < phases.Length; i++) { amplifiers[i] = new(instructions); var input = Channel.CreateUnbounded <long>(); await input.Writer.WriteAsync(phases[i], cancellationToken); inputs[i] = input; } await inputs[0].Writer.WriteAsync(0, cancellationToken); for (int i = 0; i < phases.Length; i++) { int nextAmp = i == phases.Length - 1 ? 0 : i + 1; var thisAmp = amplifiers[i]; var nextInput = inputs[nextAmp]; thisAmp.Input = inputs[i].Reader; thisAmp.OnOutput += async(_, value) => { await nextInput.Writer.WriteAsync(value, cancellationToken); }; } bool completed = false; while (!completed) { foreach (var amp in amplifiers) { completed = await amp.RunAsync(cancellationToken); } } signal = (await amplifiers[^ 1].Output.ToListAsync(cancellationToken))[^ 1];
/// <summary> /// Creates and setups a new Arcade from the given software /// </summary> /// <param name="width">Width of the view</param> /// <param name="height">Height of the view</param> /// <param name="software">Software to run the arcade on</param> public Arcade(int width, int height, IntcodeVM software) : base(width, height, b => toChar[b], Anchor.TOP_LEFT) { this.software = software; }
/// <summary> /// Creates a new painter robot on the specified hull /// </summary> /// <param name="hullWidth">Hull width</param> /// <param name="hullHeight">Hull height</param> /// <param name="brain">Robot brain</param> public PainterRobot(int hullWidth, int hullHeight, IntcodeVM brain) { this.brain = brain; this.hull = new(hullWidth, hullHeight, i => i is Colour.WHITE ? "#" : "."); this.position = new(hullWidth / 2, hullHeight / 2); }
public override void Solve() { vm = new IntcodeVM(Input[0]); base.Solve(); }