Пример #1
0
        public Dictionary <Point, long> GetCameraFeed(VacuumRobot vr)
        {
            int x = 0;
            int y = 0;

            Dictionary <Point, long> cameraFeed = new Dictionary <Point, long>();

            do
            {
                vr.Run();
                long output = vr.Output;

                cameraFeed.Add(new Point(x, y), vr.Output);

                if (vr.Output == 10)
                {
                    x = 0;
                    y++;
                }
                else
                {
                    x++;
                }
            } while (vr.CurrentState != IntcodeComputer.State.Halted);

            return(cameraFeed);
        }
Пример #2
0
        static void Main(string[] args)
        {
            string inputProgram = File.ReadAllText(@".\Day17\input.txt");

            long[]      instructionSet  = inputProgram.Trim('\n').Split(',').Select((instr) => Int64.Parse(instr)).ToArray();
            LargeMemSet memSet          = new LargeMemSet(instructionSet);
            var         vBot            = new VacuumRobot();
            Task        intCodeComputer = ComputeIntCode(memSet, vBot);
            int         result          = vBot.SumAlignmentParams();

            vBot.findThreeSegments();
            intCodeComputer.Wait();
            Console.WriteLine("\nDust collected:" + vBot.LastOutput);
        }
Пример #3
0
        public void EnterInput(VacuumRobot vr, string inputs)
        {
            Console.WriteLine(inputs);
            List <long> ascii = inputs.Select(x => Convert.ToInt64(x)).ToList();

            foreach (long input in ascii)
            {
                vr.Input = input;
                vr.Run();
            }

            vr.Input = 10;
            vr.Run();
        }
Пример #4
0
        public string SolvePartOne(string[] input)
        {
            long[] program = string.Join(",", input)
                             .Split(",")
                             .Select(x => Int64.Parse(x))
                             .ToArray();

            VacuumRobot vr = new VacuumRobot(program, false, true);
            Dictionary <Point, long> cameraFeed = GetCameraFeed(vr);

            cameraFeed.OrderBy(x => x.Key.Y)
            .ThenBy(x => x.Key.X)
            .Select(x => Convert.ToChar(x.Value))
            .ToList()
            .ForEach(x => Console.Write(x));

            return(GetAlignmentParametersSum(cameraFeed).ToString());
        }
Пример #5
0
        public string SolvePartTwo(string[] input)
        {
            long[] cameraFeedProgram = string.Join(",", input)
                                       .Split(",").Select(x => Int64.Parse(x)).ToArray();
            long[] wakeupProgram = string.Join(",", input)
                                   .Split(",").Select(x => Int64.Parse(x)).ToArray();

            VacuumRobot vr = new VacuumRobot(cameraFeedProgram, false, true);
            Dictionary <Point, long> scaffolding = GetCameraFeed(vr)
                                                   .Where(x => x.Value != 46 && x.Value != 10)
                                                   .ToDictionary(x => x.Key, x => x.Value);

            ScaffoldPathBuilder spb = new ScaffoldPathBuilder();

            StringBuilder sb = new StringBuilder();

            spb.GetScaffoldInstructions(scaffolding)
            .Select(x => Convert.ToChar(x))
            .ToList().ForEach(c => sb.Append(c));

            string mainMovRoutine = sb.ToString();
            string movFunctionA   = ReduceInstructions(ref mainMovRoutine, "A", 18, "ABC");
            string movFunctionB   = ReduceInstructions(ref mainMovRoutine, "B", 20, "ABC");
            string movFunctionC   = ReduceInstructions(ref mainMovRoutine, "C", 6, "ABC");

            wakeupProgram[0] = 2;
            vr = new VacuumRobot(wakeupProgram, true, false);
            vr.Run();
            EnterInput(vr, mainMovRoutine);
            EnterInput(vr, movFunctionA);
            EnterInput(vr, movFunctionB);
            EnterInput(vr, movFunctionC);
            EnterInput(vr, "n");

            while (vr.CurrentState != IntcodeComputer.State.Halted)
            {
                vr.Run();
            }

            Console.WriteLine();

            return(vr.Output.ToString());
        }
Пример #6
0
        private static async Task ComputeIntCode(LargeMemSet instructionSet, VacuumRobot vBot)
        {
            long        activeInstruction = 0;
            long        relativeBase      = 0;
            Queue <int> outputQueue       = new Queue <int>();

            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] = await vBot.GetNextDirectionInput();

                    activeInstruction += 2;
                    break;

                case 4:
                    vBot.SetCameraOutput((int)firstParamValue);
                    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]}");
                }
            }
        }