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);
        }