Пример #1
0
    /// <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());
    }
Пример #2
0
        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));
        }
Пример #3
0
    /// <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));
    }
Пример #4
0
        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);
        }
Пример #5
0
        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);
        }
Пример #6
0
    /// <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;
Пример #7
0
        protected override object SolvePart1()
        {
            var vm = new IntcodeVM(Input[0]);

            vm.Execute(new long[] { 1 });

            return(vm.Output.First());
        }
Пример #8
0
 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;
 }
Пример #9
0
        protected override object SolvePart1()
        {
            var vm = new IntcodeVM(Input[0]);

            vm.Write(1, 12);
            vm.Write(2, 2);
            vm.Execute();

            return(vm.Read(0));
        }
Пример #10
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));
    }
Пример #11
0
        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);
        }
Пример #12
0
    /// <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]);
Пример #13
0
        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;
Пример #14
0
        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);
        }
Пример #15
0
 /// <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;
 }
Пример #16
0
        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'));
        }
Пример #17
0
        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);
        }
Пример #18
0
 /// <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;
Пример #19
0
    /// <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];
Пример #20
0
 /// <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;
 }
Пример #21
0
 /// <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);
 }
Пример #22
0
        public override void Solve()
        {
            vm = new IntcodeVM(Input[0]);

            base.Solve();
        }