private Point GetLookAheadLocation(Point currentLocation, Direction direction) { return(direction.Id switch { 'U' => PointUtilities.MoveUp(currentLocation), 'R' => PointUtilities.MoveRight(currentLocation), 'D' => PointUtilities.MoveDown(currentLocation), 'L' => PointUtilities.MoveLeft(currentLocation), _ => throw new ArgumentOutOfRangeException(nameof(direction), direction, "Unexpected direction") });
private IReadOnlyList <string> GetRoute(IReadOnlyDictionary <Point, char> view) { const char scaffold = '#'; var route = new List <string>(); var currentDirection = Direction.Up; var currentLocation = view.Single(pixel => pixel.Value == '^').Key; var keepGoing = true; var length = 0; while (keepGoing) { var lookAheadLocation = GetLookAheadLocation(currentLocation, currentDirection); view.TryGetValue(lookAheadLocation, out var lookAheadPixel); if (lookAheadPixel == scaffold) { // Keep going in same direction length++; currentLocation = currentDirection.Id switch { 'U' => PointUtilities.MoveUp(currentLocation), 'R' => PointUtilities.MoveRight(currentLocation), 'D' => PointUtilities.MoveDown(currentLocation), 'L' => PointUtilities.MoveLeft(currentLocation), _ => throw new ArgumentOutOfRangeException() }; } else { lookAheadLocation = GetLookAheadLocation(currentLocation, currentDirection.TurnRight); view.TryGetValue(lookAheadLocation, out lookAheadPixel); if (lookAheadPixel == scaffold) { // Scaffold on the right if (length > 0) { route.Add(length.ToString()); } route.Add(Direction.Right.Id.ToString()); currentDirection = currentDirection.TurnRight; length = 0; } else { lookAheadLocation = GetLookAheadLocation(currentLocation, currentDirection.TurnLeft); view.TryGetValue(lookAheadLocation, out lookAheadPixel); if (lookAheadPixel == scaffold) { // Scaffold on the left if (length > 0) { route.Add(length.ToString()); } route.Add(Direction.Left.Id.ToString()); currentDirection = currentDirection.TurnLeft; length = 0; } else { // Scaffold only behind so must have reached the end if (length > 0) { route.Add(length.ToString()); } keepGoing = false; } } } } return(route); }