Пример #1
0
        static void Main11(string[] args)
        {
            string inputProgram = File.ReadAllText(@".\Day11\input.txt");

            long[]      instructionSet = inputProgram.Trim('\n').Split(',').Select((instr) => Int64.Parse(instr)).ToArray();
            LargeMemSet memSet         = new LargeMemSet(instructionSet);
            PaintBot    pb             = new PaintBot();

            ComputeIntCode(memSet, pb);

            Console.WriteLine(pb.TotalPanelsPainted);
            pb.printPainting();
        }
Пример #2
0
        private static void ComputeIntCode(LargeMemSet instructionSet, PaintBot bot)
        {
            long activeInstruction = 0;
            long relativeBase      = 0;
            bool givenPaintInstr   = false;

            while (instructionSet[activeInstruction] != 99)
            {
                long instruction = instructionSet[activeInstruction];
                // opcode is right most two digits
                long opcode     = instruction % 100;
                long firstMode  = (instruction / 100) % 10;
                long secondMode = (instruction / 1000) % 10;
                long thirdMode  = (instruction / 10000) % 10;

                long   firstParamValue           = 0;
                long   firstParamIndex           = 0;
                long   secondParamValue          = 0;
                long   thirdParamIndex           = 0;
                long[] opcodesNeedingFirstParam  = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
                long[] opcodesNeedingSecondParam = { 1, 2, 5, 6, 7, 8 };
                long[] opcodesNeedingThirdParam  = { 1, 2, 7, 8 };

                if (opcodesNeedingFirstParam.Contains(opcode))
                {
                    switch (firstMode)
                    {
                    // Position
                    case 0:
                        firstParamIndex = instructionSet[activeInstruction + 1];
                        break;

                    // Immediate
                    case 1:
                        firstParamIndex = activeInstruction + 1;
                        break;

                    // Relative
                    case 2:
                        firstParamIndex = instructionSet[activeInstruction + 1] + relativeBase;
                        break;
                    }
                    firstParamValue = instructionSet[firstParamIndex];
                }
                if (opcodesNeedingSecondParam.Contains(opcode))
                {
                    switch (secondMode)
                    {
                    case 0:
                        secondParamValue = instructionSet[instructionSet[activeInstruction + 2]];
                        break;

                    case 1:
                        secondParamValue = instructionSet[activeInstruction + 2];
                        break;

                    case 2:
                        secondParamValue = instructionSet[instructionSet[activeInstruction + 2] + relativeBase];
                        break;
                    }
                }
                if (opcodesNeedingThirdParam.Contains(opcode))
                {
                    switch (thirdMode)
                    {
                    case 0:
                        thirdParamIndex = instructionSet[activeInstruction + 3];
                        break;

                    case 1:
                        throw new Exception("Cannot store at immediate position");

                    case 2:
                        thirdParamIndex = instructionSet[activeInstruction + 3] + relativeBase;
                        break;
                    }
                }

                switch (opcode)
                {
                // add
                case 1:
                    instructionSet[thirdParamIndex] =
                        firstParamValue + secondParamValue;
                    activeInstruction += 4;
                    break;

                case 2:
                    instructionSet[thirdParamIndex] =
                        firstParamValue * secondParamValue;
                    activeInstruction += 4;
                    break;

                case 3:
                    instructionSet[firstParamIndex] = bot.getCameraReading();
                    activeInstruction += 2;
                    break;

                case 4:
                    if (!givenPaintInstr)
                    {
                        bot.paint((int)firstParamValue);
                        givenPaintInstr = true;
                    }
                    else
                    {
                        bot.changeDirectionAndMove((int)firstParamValue);
                        givenPaintInstr = false;
                    }
                    activeInstruction += 2;
                    break;

                case 5:
                    if (firstParamValue != 0)
                    {
                        activeInstruction = secondParamValue;
                    }
                    else
                    {
                        activeInstruction += 3;
                    }
                    break;

                case 6:
                    if (firstParamValue == 0)
                    {
                        activeInstruction = secondParamValue;
                    }
                    else
                    {
                        activeInstruction += 3;
                    }
                    break;

                case 7:
                    if (firstParamValue < secondParamValue)
                    {
                        instructionSet[thirdParamIndex] = 1;
                    }
                    else
                    {
                        instructionSet[thirdParamIndex] = 0;
                    }
                    activeInstruction += 4;
                    break;

                case 8:
                    if (firstParamValue == secondParamValue)
                    {
                        instructionSet[thirdParamIndex] = 1;
                    }
                    else
                    {
                        instructionSet[thirdParamIndex] = 0;
                    }
                    activeInstruction += 4;
                    break;

                case 9:
                    relativeBase      += firstParamValue;
                    activeInstruction += 2;
                    break;

                default:
                    throw new Exception($"Unexpected opcode {instructionSet[activeInstruction]}");
                }
            }
        }