public override async Task <string> Part2Async(string input) { var memory = IntMachineBase.ParseProgram(input); memory[0] = 2; // Wake up var intMachine = new SynchronousIntMachine(memory); var map = await GetMap(intMachine); await UpdateProgressAsync(.5, 1); var(robotPos, robotChar) = map.First(x => RobotDirections.Contains(x.Value)); var robotDirection = Directions[Array.IndexOf(RobotDirections, robotChar)]; map[robotPos] = Scaffolding; myGarbageCounter = char.MaxValue; var path = await FollowPath(map, robotPos, robotDirection); var commandData = await FindSlicing(path.ToArray()); var commands = commandData.Select(x => ConvertCommand(x.Command)).ToArray(); var movementRoutine = CreateMovementRoutine(commandData); movementRoutine.ForEach(x => intMachine.InputQueue.Enqueue(x)); commands.SelectMany(x => x).ForEach(x => intMachine.InputQueue.Enqueue(x)); "n\n".ForEach(x => intMachine.InputQueue.Enqueue(x)); while (intMachine.RunUntilBlockOrComplete() != ReturnCode.Completed) { } return(intMachine.OutputQueue.Last().ToString()); }
/// <summary> /// Check if moving is available for selected direction /// </summary> /// <param name="currentX"></param> /// <param name="currentY"></param> /// <param name="direction"></param> /// <returns>false - if robot will be lost</returns> public bool IsMovementAvailable(int currentX, int currentY, RobotDirections direction) { var result = false; // check further path switch (direction) { case RobotDirections.N: result = currentY < MaximumY; break; case RobotDirections.S: result = currentY > 0; break; case RobotDirections.W: result = currentX > 0; break; case RobotDirections.E: result = currentX < MaximumX; break; } // save bad coordinate if (result == false) { badCoordinates.Add(new FieldCoordinate(currentX, currentY, direction)); } return(result); }
// main constructor public Robot(IField field, int currentX, int currentY, string currentDirection, string actions) { actionsQueue = new Queue <char>(); currentField = field; CurrentX = currentX < 0 ? 0 : currentX; CurrentY = currentY < 0 ? 0 : currentY; // assume North is direction by default or bad input value if (Enum.TryParse <RobotDirections>(currentDirection.ToUpperInvariant(), out var currDirection)) { CurrentDirection = currDirection; } else { CurrentDirection = RobotDirections.N; } if (!string.IsNullOrWhiteSpace(actions)) { actions = actions.ToUpper(); for (var i = 0; i < actions.Length; i++) { actionsQueue.Enqueue(actions[i]); } } }
/// <summary> /// Check if moving is forbidden based on previous robots data (marked squares) /// </summary> /// <param name="currentX"></param> /// <param name="currentY"></param> /// <param name="direction"></param> /// <returns></returns> public bool IsMovementForbidden(int currentX, int currentY, RobotDirections direction) { // check stored bad coordinates data if (badCoordinates.Contains(new FieldCoordinate(currentX, currentY, direction))) { // some robot already lost return(true); } return(false); }
public FieldCoordinate(int x, int y, RobotDirections direction) { X = x; Y = y; Direction = direction; }