Beispiel #1
0
        private bool IsInTractorBeam(int x, int y, IntCodeVM2 vm)
        {
            vm.Reset();
            vm.AddInput(x);
            vm.AddInput(y);
            vm.ExecuteProgram();

            return(vm.GetLastOutput() == 1);
        }
Beispiel #2
0
        /// <inheritdoc />
        public string Part2()
        {
            IntCodeVM2 vm = new IntCodeVM2(intCode.Select(i => (long)i).ToList());

            vm.AddInput(5);
            vm.ExecuteProgram();

            return($"{vm.GetLastOutput()}");
        }
Beispiel #3
0
        /// <inheritdoc />
        public string Part1()
        {
            IntCodeVM2 vm = new IntCodeVM2(intCode.Select(i => (long)i).ToList());

            vm.AddInput(1);
            vm.ExecuteProgram();

            //return $"{vm.GetMemory(4)}"; // test
            return($"{vm.GetLastOutput()}");
        }
Beispiel #4
0
        /// <inheritdoc />
        public string Part1()
        {
            IntCodeVM2 vm = new IntCodeVM2(program);

            vm.ExecuteProgram();

            List <List <char> > area = new List <List <char> >();

            int total = 0;

            for (int i = 0; i < 50; i++)
            {
                area.Add(new List <char>());

                for (int j = 0; j < 50; j++)
                {
                    vm.Reset();
                    vm.AddInput(j); // x
                    vm.AddInput(i); // y

                    vm.ResumeProgram();

                    if (vm.GetLastOutput() == 0)
                    {
                        area[i].Add('.');
                        Console.Write('.');
                    }
                    else
                    {
                        area[i].Add('#');
                        Console.Write('#');
                        total++;
                    }
                }

                Console.WriteLine();
            }

            return($"{total} points are affected");
        }
Beispiel #5
0
        /// <inheritdoc />
        public string Part2()
        {
            IntCodeVM2 vm = new IntCodeVM2(program);

            // show prompt
            vm.ExecuteProgram();
            DrawASCIIOutput(vm.GetOutputs());
            vm.ClearOutput();

            // input program
            //
            //  @
            // ##ABCDEFGHI###
            //
            // if D is ground and any of A,B,C aren't then jump (p1)
            // invert T (now equal to C)
            // if ((I OR F) AND E) OR H are ground, then jump
            ASCIIHelper helper = new ASCIIHelper();

            helper.AddLine("NOT A T");
            helper.AddLine("NOT B J");
            helper.AddLine("OR T J");
            helper.AddLine("NOT C T");
            helper.AddLine("OR T J");
            helper.AddLine("AND D J");

            helper.AddLine("AND T T");

            helper.AddLine("OR I T");
            helper.AddLine("OR F T");
            helper.AddLine("AND E T");
            helper.AddLine("OR H T");
            helper.AddLine("AND T J");

            helper.AddLine("RUN");

            vm.AddInput(helper.Convert());

            // output what it showed
            vm.ResumeProgram();

            if (vm.GetLastOutput() > 255)
            {
                Console.WriteLine($"\nhull damage taken: {vm.GetLastOutput()}");
            }
            else
            {
                DrawASCIIOutput(vm.GetOutputs());
            }

            return("");
        }
Beispiel #6
0
        public void TestInputAddresses(long answer)
        {
            List <long> program = new List <long>()
            {
                3, 0,
                99,
                4, 5, 6
            };

            IntCodeVM2 vm = new IntCodeVM2(program);

            vm.AddInput(answer);
            vm.ExecuteProgram();
            Assert.That(vm.GetMemory(0), Is.EqualTo(answer));
        }
Beispiel #7
0
        public void TestInputDirect(long answer)
        {
            List <long> program = new List <long>()
            {
                103, 5,
                99,
                3, 4, 5
            };

            IntCodeVM2 vm = new IntCodeVM2(program);

            vm.AddInput(answer);
            vm.ExecuteProgram();
            Assert.That(vm.GetMemory(1), Is.EqualTo(answer));
        }
Beispiel #8
0
        /// <inheritdoc />
        public string Part1()
        {
            //IntCodeVM intCodeVM = new IntCodeVM(program);
            IntCodeVM2 intCodeVM = new IntCodeVM2(program);

            //intCodeVM.ResizeMemory(int.MaxValue >> 4);
            intCodeVM.AddInput(1);

            intCodeVM.ExecuteProgram();

            return($"{intCodeVM.GetLastOutput()}");

            // 2158221668 too low
            // 1187721666102244 is too high
        }
Beispiel #9
0
        public void TestInputBaseOffset(long answer)
        {
            List <long> program = new List <long>()
            {
                109, 3,
                203, 4,
                99,
                5, 6, 7
            };

            IntCodeVM2 vm = new IntCodeVM2(program);

            vm.AddInput(answer);
            vm.ExecuteProgram();
            Assert.That(vm.GetMemory(7), Is.EqualTo(answer));
        }
Beispiel #10
0
        /// <inheritdoc />
        public string Part1()
        {
            IntCodeVM2 vm = new IntCodeVM2(program);

            // show prompt
            vm.ExecuteProgram();
            DrawASCIIOutput(vm.GetOutputs());
            vm.ClearOutput();

            // input program
            //J = (NOT A OR NOT B OR NOT C) AND D
            //
            //  @
            // ##ABCD###
            //
            // if D is ground and any of A,B,C aren't then jump
            ASCIIHelper helper = new ASCIIHelper();

            helper.AddLine("NOT A T");
            helper.AddLine("NOT B J");
            helper.AddLine("OR T J");
            helper.AddLine("NOT C T");
            helper.AddLine("OR T J");
            helper.AddLine("AND D J");

            helper.AddLine("WALK");

            vm.AddInput(helper.Convert());

            // output what it showed
            vm.ResumeProgram();

            if (vm.GetLastOutput() > 255)
            {
                Console.WriteLine($"\nhull damage taken: {vm.GetLastOutput()}");
            }
            else
            {
                DrawASCIIOutput(vm.GetOutputs());
            }

            return("");
        }
Beispiel #11
0
        /// <inheritdoc />
        public string Part1()
        {
            IntCodeVM2 intCodeVM = new IntCodeVM2(program);

            intCodeVM.AddInput(0);
            //intCodeVM.ResizeMemory(int.MaxValue >> 4);

            // positions and colors (1 = white, 0 = black)
            Dictionary <Vector2Int, int> paintedPanels = new Dictionary <Vector2Int, int>();

            paintedPanels.Add(Vector2Int.Zero, 0);

            // rotation
            Direction direction = Direction.Up;

            // keep running till it stops asking for input
            Vector2Int robotPos = Vector2Int.Zero;

            while (intCodeVM.ResumeProgram() == IntCodeVM2.HaltCode.WaitingForInput)
            {
                // get outputs
                int newColor        = (int)intCodeVM.GetOutputs()[0];
                int directionChange = (int)intCodeVM.GetOutputs()[1];

                // paint
                if (paintedPanels.TryGetValue(robotPos, out int color))
                {
                    paintedPanels[robotPos] = newColor;
                }
                else
                {
                    paintedPanels.Add(robotPos, newColor);
                }

                // rotate
                if (directionChange == 0)
                {
                    direction = (direction - 1);
                    // left 90° from up is left
                    if ((int)direction < 0)
                    {
                        direction = Direction.Left;
                    }
                }
                else
                {
                    direction += 1;
                    // right 90° from left is up
                    if ((int)direction > 3)
                    {
                        direction = Direction.Up;
                    }
                }

                // move one panel forward
                switch (direction)
                {
                case Direction.Up:
                    robotPos += new Vector2Int(0, -1);
                    break;

                case Direction.Right:
                    robotPos += new Vector2Int(1, 0);
                    break;

                case Direction.Down:
                    robotPos += new Vector2Int(0, 1);
                    break;

                case Direction.Left:
                    robotPos += new Vector2Int(-1, 0);
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }

                // input into VM
                if (paintedPanels.TryGetValue(robotPos, out color))
                {
                    intCodeVM.AddInput(color);
                }
                else
                {
                    intCodeVM.AddInput(0);
                }


                // clear output
                intCodeVM.ClearOutput();

                // run again
            }

            Console.WriteLine($"Last halt reason {intCodeVM.LastHaltReason.ToString()}");

            return($"Touched {paintedPanels.Count} panels");
            // ans = 2511
        }
Beispiel #12
0
        /// <inheritdoc />
        public string Part1()
        {
            IntCodeVM2 vm = new IntCodeVM2(program);

            // used for drawing
            tiles = new Dictionary <Vector2Int, Tile>
            {
                { Vector2Int.Zero, Tile.Empty }
            };

            // all visited places
            places = new List <Place>();
            places.Add(new Place()
            {
                Position    = Vector2Int.Zero,
                PreviousDir = Direction.East,
                UnExplored  = new List <Direction>()
                {
                    Direction.East, Direction.North, Direction.West, Direction.South
                }
            });

            Vector2Int currentPos   = Vector2Int.Zero;
            Vector2Int lastValidPos = Vector2Int.Zero;

            while (places.Count(p => p.UnExplored.Count > 0) > 0)
            {
                // generate next move
                Direction dir = NextMove(currentPos, places);
                vm.AddInput((int)dir);
                currentPos = Move(currentPos, dir);


                /*
                 * // bump into every wall and pray
                 * switch (random.Next(0, 4))
                 * {
                 *  case 0:
                 *      vm.AddInput((int)Direction.North);
                 *      currentPos = Move(currentPos, Direction.North);
                 *      break;
                 *
                 *  case 1:
                 *      vm.AddInput((int)Direction.South);
                 *      currentPos = Move(currentPos, Direction.South);
                 *      break;
                 *
                 *  case 2:
                 *      vm.AddInput((int)Direction.West);
                 *      currentPos = Move(currentPos, Direction.West);
                 *      break;
                 *
                 *  case 3:
                 *      vm.AddInput((int)Direction.East);
                 *      currentPos = Move(currentPos, Direction.East);
                 *      break;
                 * }
                 */

                // get input

                /*
                 * switch (Console.ReadKey().Key)
                 * {
                 *  case ConsoleKey.UpArrow:
                 *      vm.AddInput((int)Direction.North);
                 *      currentPos = Move(currentPos, Direction.North);
                 *      break;
                 *
                 *  case ConsoleKey.DownArrow:
                 *      vm.AddInput((int)Direction.South);
                 *      currentPos = Move(currentPos, Direction.South);
                 *      break;
                 *
                 *  case ConsoleKey.LeftArrow:
                 *      vm.AddInput((int)Direction.West);
                 *      currentPos = Move(currentPos, Direction.West);
                 *      break;
                 *
                 *  case ConsoleKey.RightArrow:
                 *      vm.AddInput((int)Direction.East);
                 *      currentPos = Move(currentPos, Direction.East);
                 *      break;
                 * }
                 */


                // resume
                vm.ResumeProgram();

                // get status
                switch (vm.GetLastOutput())
                {
                case 0:
                    if (!tiles.ContainsKey(currentPos))
                    {
                        tiles.Add(currentPos, Tile.Wall);
                    }

                    currentPos = lastValidPos;
                    break;

                case 1:
                    lastValidPos = currentPos;

                    if (!tiles.ContainsKey(currentPos))
                    {
                        tiles.Add(currentPos, Tile.Empty);

                        // add surrounding tiles to explore
                        Place newPlace = new Place()
                        {
                            Position    = currentPos,
                            PreviousDir = OppositeDir(dir),
                        };

                        if (!tiles.ContainsKey(currentPos + new Vector2Int(0, -1)))
                        {
                            newPlace.UnExplored.Add(Direction.North);
                        }
                        if (!tiles.ContainsKey(currentPos + new Vector2Int(0, +1)))
                        {
                            newPlace.UnExplored.Add(Direction.South);
                        }
                        if (!tiles.ContainsKey(currentPos + new Vector2Int(-1, 0)))
                        {
                            newPlace.UnExplored.Add(Direction.West);
                        }
                        if (!tiles.ContainsKey(currentPos + new Vector2Int(+1, 0)))
                        {
                            newPlace.UnExplored.Add(Direction.East);
                        }

                        places.Add(newPlace);
                    }

                    break;

                case 2:
                    lastValidPos = currentPos;

                    if (!tiles.ContainsKey(currentPos))
                    {
                        tiles.Add(currentPos, Tile.Oxygen);

                        // add surrounding tiles to explore
                        Place newPlace = new Place()
                        {
                            Position    = currentPos,
                            PreviousDir = OppositeDir(dir),
                        };

                        if (!tiles.ContainsKey(currentPos + new Vector2Int(0, -1)))
                        {
                            newPlace.UnExplored.Add(Direction.North);
                        }
                        if (!tiles.ContainsKey(currentPos + new Vector2Int(0, +1)))
                        {
                            newPlace.UnExplored.Add(Direction.South);
                        }
                        if (!tiles.ContainsKey(currentPos + new Vector2Int(-1, 0)))
                        {
                            newPlace.UnExplored.Add(Direction.West);
                        }
                        if (!tiles.ContainsKey(currentPos + new Vector2Int(+1, 0)))
                        {
                            newPlace.UnExplored.Add(Direction.East);
                        }

                        places.Add(newPlace);
                    }
                    break;
                }

                // draw screen
                if (visualize)
                {
                    DrawScreen(tiles, currentPos);
                }
            }

            // find out where oxygen is
            Vector2Int oxygenLocation = tiles.Where(t => t.Value == Tile.Oxygen).Select(t => t.Key).First();
            Place      oxygenPlace    = places.Find(p => p.Position.Equals(oxygenLocation));

            int   distance     = 0;
            Place currentPlace = oxygenPlace;

            while (!currentPlace.Position.Equals(Vector2Int.Zero))
            {
                distance++;
                var currentPosition = Move(currentPlace.Position, currentPlace.PreviousDir);
                currentPlace = places.Find(p => p.Position.Equals(currentPosition));
            }

            // push output down a bit
            if (visualize)
            {
                Console.SetCursorPosition(0, 50);
            }

            return($"Distance to travel: {distance} tiles");
        }
Beispiel #13
0
        /// <inheritdoc />
        public string Part1()
        {
            // set to true to play the text adventure
            bool userPlay = false;


            IntCodeVM2 vm = new IntCodeVM2(program);

            vm.ExecuteProgram();

            if (userPlay)
            {
                while (true)
                {
                    // output
                    foreach (long l in vm.GetOutputs())
                    {
                        if (l < 255)
                        {
                            Console.Write((char)l);
                        }
                        else
                        {
                            Console.Write(l);
                        }
                    }

                    vm.ClearOutput();

                    // input
                    string inputLine = Console.ReadLine();

                    ASCIIHelper helper = new ASCIIHelper();
                    helper.AddLine(inputLine);

                    vm.AddInput(helper.Convert());
                    vm.ResumeProgram();
                }
            }
            else
            {
                // list of inputs to get to the end
                List <string> inputs = new List <string>()
                {
                    "south",
                    "take food ration",
                    "west",
                    "north",
                    "north",
                    "east",
                    "take astrolabe",
                    "west",
                    "south",
                    "south",
                    "east",
                    "north",
                    "east",
                    "south",
                    "take weather machine",
                    "west",
                    "take ornament",
                    "east",
                    "north",
                    "east",
                    "east",
                    "east",
                    "south"
                };

                ASCIIHelper helper = new ASCIIHelper();
                foreach (string input in inputs)
                {
                    helper.AddLine(input);
                }

                vm.AddInput(helper.Convert());
                vm.ResumeProgram();

                List <long> output = vm.GetOutputs();
                output.RemoveAt(output.Count - 1);          // remove last \n
                int lastLineStart = output.LastIndexOf(10); // get last sentence

                // convert characters to a string
                StringBuilder lastLine = new StringBuilder();
                for (int i = lastLineStart + 1; i < output.Count; i++)
                {
                    if (output[i] < 255)
                    {
                        lastLine.Append((char)output[i]);
                    }
                    else
                    {
                        lastLine.Append(output[i]);
                    }
                }

                // get the number from the last line
                return(Regex.Match(lastLine.ToString(), @"\d+").Value);
            }

            return($"");
        }
Beispiel #14
0
        /// <inheritdoc />
        public string Part1()
        {
            // create vms and inputs
            List <IntCodeVM2> vms = new List <IntCodeVM2>();

            for (int i = 0; i < 50; i++)
            {
                vms.Add(new IntCodeVM2(program));
                vms[i].AddInput(i);
            }

            while (true)
            {
                // run all of them till they stop waiting for input
                List <Task> tasks = new List <Task>();
                foreach (IntCodeVM2 vm in vms)
                {
                    tasks.Add(Task.Run(() => { vm.ResumeProgram(); }));
                }
                Task.WaitAll(tasks.ToArray());

                // add input to all of them
                bool[] addedInput = new bool[50];
                for (int i = 0; i < vms.Count; i++)
                {
                    IntCodeVM2  vm     = vms[i];
                    List <long> packet = vm.GetOutputs();

                    if (packet.Count > 0)
                    {
                        // go through multiple packets
                        for (int j = 0; j < packet.Count; j += 3)
                        {
                            // actually crashes the program
                            if (packet[j] == 255)
                            {
                                return($"Y value of first packet which was went to 255: {packet[2]}");
                            }

                            IntCodeVM2 receiver = vms[(int)packet[j]];
                            receiver.AddInput(packet[j + 1]);
                            receiver.AddInput(packet[j + 2]); // crash showed 22074

                            addedInput[i] = true;
                        }

                        // clear output for next time
                        vm.ClearOutput();
                    }
                }

                // all of those which didn't receive input get -1
                for (int i = 0; i < addedInput.Length; i++)
                {
                    if (!addedInput[i])
                    {
                        vms[i].AddInput(-1);
                    }
                }
            }
        }
Beispiel #15
0
        /// <inheritdoc />
        public string Part2()
        {
            // create vms and inputs
            List <IntCodeVM2> vms = new List <IntCodeVM2>();

            for (int i = 0; i < 50; i++)
            {
                vms.Add(new IntCodeVM2(program));
                vms[i].AddInput(i);
            }

            List <long> lastNatPacket = new List <long>()
            {
                0, 0, 0
            };
            List <long> previousYValuesUsed = new List <long>();
            bool        updatedY            = false;

            while (true)
            {
                // run all of them till they stop waiting for input
                List <Task> tasks = new List <Task>();
                foreach (IntCodeVM2 vm in vms)
                {
                    tasks.Add(Task.Run(() => { vm.ResumeProgram(); }));
                }
                Task.WaitAll(tasks.ToArray());

                // add input to all of them
                bool[] addedInput = new bool[50];
                for (int i = 0; i < vms.Count; i++)
                {
                    IntCodeVM2  vm     = vms[i];
                    List <long> packet = vm.GetOutputs();

                    if (packet.Count > 0)
                    {
                        // go through multiple packets
                        for (int j = 0; j < packet.Count; j += 3)
                        {
                            // actually crashes the program
                            if (packet[j] == 255)
                            {
                                //return $"Y value of first packet which was went to 255: {packet[2]}";
                                lastNatPacket[1] = packet[j + 1];
                                lastNatPacket[2] = packet[j + 2];

                                updatedY = true;
                            }
                            else
                            {
                                IntCodeVM2 receiver = vms[(int)packet[j]];
                                receiver.AddInput(packet[j + 1]);
                                receiver.AddInput(packet[j + 2]); // crash showed 22074

                                addedInput[i] = true;
                            }
                        }

                        // clear output for next time
                        vm.ClearOutput();
                    }
                }

                // check if all inputs are empty
                if (addedInput.All(i => i == false))
                {
                    // send last NAT packet to vm 0
                    vms[0].AddInput(lastNatPacket);

                    // only add used Y after updating Y
                    if (updatedY)
                    {
                        previousYValuesUsed.Add(lastNatPacket[2]);
                        updatedY = false;
                    }

                    // check if this one was sent before
                    if (previousYValuesUsed.Count > 1 && previousYValuesUsed[previousYValuesUsed.Count - 2] == previousYValuesUsed[previousYValuesUsed.Count - 1])
                    {
                        return($"sent {previousYValuesUsed[previousYValuesUsed.Count - 2]} twice in a row");
                    }

                    // send -1 to the rest
                    for (int i = 1; i < addedInput.Length; i++)
                    {
                        if (!addedInput[i])
                        {
                            vms[i].AddInput(-1);
                        }
                    }
                }
                // just another round
                else
                {
                    // all of those which didn't receive input get -1
                    for (int i = 0; i < addedInput.Length; i++)
                    {
                        if (!addedInput[i])
                        {
                            vms[i].AddInput(-1);
                        }
                    }
                }
            }
        }
Beispiel #16
0
        /// <inheritdoc />
        public string Part2()
        {
            IntCodeVM2 vm = new IntCodeVM2(program);

            vm.SetMemory(0, 2); // put into different mode

            // input
            // L,12, L,12, R,12,
            // L,12, L,12, R,12
            // L,8, L,8, R,12, L,8, L,8,
            // L,10, R,8, R,12,
            // L,10, R,8, R,12,
            // L,12, L,12, R,12
            // L,8, L,8, R,12, L,8, L,8,
            // L,10, R,8, R,12,
            // L,12, L,12, R,12,
            // L,8, L,8, R,12, L,8, L,8
            //
            // A, A, B, C, C, A, B, C, A, B
            // A L,12, L,12, R,12
            // B L,8, L,8, R,12, L,8, L,8
            // C L,10, R,8, R,12,

            List <long> inputs = new List <long>()
            {
                65, 44, 65, 44, 66, 44, 67, 44, 67, 44, 65, 44, 66, 44, 67, 44, 65, 44, 66, 10,
                76, 44, 49, 50, 44, 76, 44, 49, 50, 44, 82, 44, 49, 50, 10,
                76, 44, 56, 44, 76, 44, 56, 44, 82, 44, 49, 50, 44, 76, 44, 56, 44, 76, 44, 56, 10,
                76, 44, 49, 48, 44, 82, 44, 56, 44, 82, 44, 49, 50, 10,
                110, 10
            };

            foreach (long l in inputs)
            {
                vm.AddInput(l);
            }

            vm.ExecuteProgram();

            List <long> outputs = vm.GetOutputs();

            int line      = 0;
            int posInLine = 0;

            List <Vector2Int> scaffold = new List <Vector2Int>();
            long total = 0;


            foreach (long c in outputs)
            {
                switch (c)
                {
                // new line
                case 10:
                    Console.WriteLine();
                    line++;
                    posInLine = 0;
                    continue;
                    break;

                // #
                case 35:
                    Console.Write("#");
                    scaffold.Add(new Vector2Int(posInLine, line));
                    break;

                // .
                case 46:
                    Console.Write(".");
                    break;

                // <
                case 60:
                    Console.Write("<");
                    break;

                // >
                case 62:
                    Console.Write(">");
                    break;

                // ^
                case 94:
                    Console.Write("^");
                    break;

                // v
                case 118:
                    Console.Write("v");
                    break;


                // x
                case 120:
                    Console.Write("x");
                    //Console.WriteLine("");
                    //return "It's dead Jim!";
                    break;


                default:
                    if (c < 255)
                    {
                        Console.Write((char)c);
                    }
                    else
                    {
                        Console.WriteLine($"\n{c}");
                    }
                    total += c;
                    break;
                }

                posInLine++;
            }

            // higher than 5624
            //var test = outputs.Skip(3121).ToList();

            return($"total {total}");
        }
Beispiel #17
0
        /// <inheritdoc />
        public string Part2()
        {
            IntCodeVM2 vm = new IntCodeVM2(longs);

            vm.SetMemory(0, 2);
            vm.ExecuteProgram();

            List <int> output = vm.GetOutputs().Select(l => (int)l).ToList();

            Dictionary <Vector2Int, int> tiles = new Dictionary <Vector2Int, int>();
            int finalScore = 0;

            // draw tiles
            for (int i = 0; i < output.Count; i += 3)
            {
                // get score
                if (output[i] == -1)
                {
                    finalScore = output[i + 2];
                    continue;
                }

                // create new tiles
                tiles.Add(new Vector2Int(output[i], output[i + 1]), output[i + 2]);
            }

            // as long as breakable blocks remain
            while (tiles.Values.Count(t => t == 2) > 0)
            {
                // redraw tiles
                output = vm.GetOutputs().Select(l => (int)l).ToList();
                for (int i = 0; i < output.Count; i += 3)
                {
                    // get score
                    if (output[i] == -1)
                    {
                        finalScore = output[i + 2];
                        Console.WriteLine($"Current score {finalScore}");
                        continue;
                    }

                    Vector2Int pos = new Vector2Int(output[i], output[i + 1]);
                    if (tiles.ContainsKey(pos))
                    {
                        tiles[pos] = output[i + 2];
                    }
                    else
                    {
                        tiles.Add(pos, output[i + 2]);
                    }
                }

                // show screen
                if (humanInput)
                {
                    DrawScreen(tiles);

                    // do a move
                    switch (Console.ReadKey().Key)
                    {
                    case ConsoleKey.DownArrow:
                        vm.AddInput(0);
                        break;

                    case ConsoleKey.LeftArrow:
                        vm.AddInput(-1);
                        break;

                    case ConsoleKey.RightArrow:
                        vm.AddInput(+1);
                        break;
                    }
                }
                else
                {
                    // get paddle pos
                    Vector2Int paddle = tiles.Keys.ToList()[tiles.Values.ToList().FindIndex(i => i == 3)];

                    // get ball pos
                    Vector2Int ball = tiles.Keys.ToList()[tiles.Values.ToList().FindIndex(i => i == 4)];

                    // determine next move
                    if (ball.X > paddle.X)
                    {
                        vm.AddInput(1);
                    }
                    else if (ball.X < paddle.X)
                    {
                        vm.AddInput(-1);
                    }
                    else
                    {
                        vm.AddInput(0);
                    }
                }

                // run again
                vm.ClearOutput();
                vm.ResumeProgram();
            }



            return($"final score {finalScore}");
        }
Beispiel #18
0
        /// <inheritdoc />
        public string Part2()
        {
            IntCodeVM2 intCodeVM = new IntCodeVM2(program);

            intCodeVM.AddInput(1);                              // starting from a white panel now

            // positions and colors (1 = white, 0 = black)
            Dictionary <Vector2Int, int> paintedPanels = new Dictionary <Vector2Int, int>();

            paintedPanels.Add(Vector2Int.Zero, 0);

            // rotation
            Direction direction = Direction.Up;

            // keep running till it stops asking for input
            Vector2Int robotPos = Vector2Int.Zero;

            while (intCodeVM.ResumeProgram() == IntCodeVM2.HaltCode.WaitingForInput)
            {
                // get outputs
                int newColor        = (int)intCodeVM.GetOutputs()[0];
                int directionChange = (int)intCodeVM.GetOutputs()[1];

                // paint
                if (paintedPanels.TryGetValue(robotPos, out int color))
                {
                    paintedPanels[robotPos] = newColor;
                }
                else
                {
                    paintedPanels.Add(robotPos, newColor);
                }

                // rotate
                if (directionChange == 0)
                {
                    direction = (direction - 1);
                    // left 90° from up is left
                    if ((int)direction < 0)
                    {
                        direction = Direction.Left;
                    }
                }
                else
                {
                    direction += 1;
                    // right 90° from left is up
                    if ((int)direction > 3)
                    {
                        direction = Direction.Up;
                    }
                }

                // move one panel forward
                switch (direction)
                {
                case Direction.Up:
                    robotPos += new Vector2Int(0, -1);
                    break;

                case Direction.Right:
                    robotPos += new Vector2Int(1, 0);
                    break;

                case Direction.Down:
                    robotPos += new Vector2Int(0, 1);
                    break;

                case Direction.Left:
                    robotPos += new Vector2Int(-1, 0);
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }

                // input into VM
                if (paintedPanels.TryGetValue(robotPos, out color))
                {
                    intCodeVM.AddInput(color);
                }
                else
                {
                    intCodeVM.AddInput(0);
                }


                // clear output
                intCodeVM.ClearOutput();

                // run again
            }

            Console.WriteLine($"Last halt reason {intCodeVM.LastHaltReason.ToString()}");
            Console.WriteLine($"Touched {paintedPanels.Count} panels");

            // find highest x and highest y
            int highestX = paintedPanels.Keys.OrderBy(vec => vec.X).Last().X;
            int highestY = paintedPanels.Keys.OrderBy(vec => vec.Y).Last().Y;

            /*
             * int lowestX = xSorted[0].X;                         // 0
             * int highestX = xSorted[xSorted.Count - 1].X;        // 42
             * int lowestY = ySorted[0].Y;                         // 0
             * int highestY = ySorted[xSorted.Count - 1].Y;        // 18
             */

            for (int i = 0; i <= highestY; i++)
            {
                for (int j = 0; j <= highestX; j++)
                {
                    int color = 0;
                    if (paintedPanels.TryGetValue(new Vector2Int(j, i), out color))
                    {
                    }

                    // color
                    if (color == 0)
                    {
                        Console.ForegroundColor = ConsoleColor.White;
                        Console.BackgroundColor = ConsoleColor.Black;
                    }
                    else
                    {
                        Console.ForegroundColor = ConsoleColor.Black;
                        Console.BackgroundColor = ConsoleColor.White;
                    }

                    Console.Write(" ");
                }

                Console.WriteLine();
            }

            return($"");
        }