A robot on an infinite XY-plane starts at point (0, 0)
facing north. The robot receives an array of integers commands
, which represents a sequence of moves that it needs to execute. There are only three possible types of instructions the robot can receive:
-2
: Turn left 90
degrees.-1
: Turn right 90
degrees.1 <= k <= 9
: Move forward k
units, one unit at a time.Some of the grid squares are obstacles
. The ith
obstacle is at grid point obstacles[i] = (xi, yi)
. If the robot runs into an obstacle, it will stay in its current location (on the block adjacent to the obstacle) and move onto the next command.
Return the maximum squared Euclidean distance that the robot reaches at any point in its path (i.e. if the distance is 5
, return 25
).
Note:
(0, 0)
. If this happens, the robot will ignore the obstacle until it has moved off the origin. However, it will be unable to return to (0, 0)
due to the obstacle.Example 1:
Input: commands = [4,-1,3], obstacles = []
Output: 25
Explanation:
The robot starts at (0, 0)
:
(0, 4)
.(3, 4)
.The furthest point the robot ever gets from the origin is (3, 4)
, which squared is 32 + 42 = 25
units away.
Example 2:
Input: commands = [4,-1,4,-2,4], obstacles = [[2,4]]
Output: 65
Explanation:
The robot starts at (0, 0)
:
(0, 4)
.(2, 4)
, robot is at (1, 4)
.(1, 8)
.The furthest point the robot ever gets from the origin is (1, 8)
, which squared is 12 + 82 = 65
units away.
Example 3:
Input: commands = [6,-1,-1,6], obstacles = [[0,0]]
Output: 36
Explanation:
The robot starts at (0, 0)
:
(0, 6)
.(0,0)
, robot is at (0, 1)
.The furthest point the robot ever gets from the origin is (0, 6)
, which squared is 62 = 36
units away.
Constraints:
1 <= commands.length <= 104
commands[i]
is either -2
, -1
, or an integer in the range [1, 9]
.0 <= obstacles.length <= 104
-3 * 104 <= xi, yi <= 3 * 104
231
.When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The robot starts at a point and tries to move according to a series of commands. A brute force approach means we directly simulate every single movement, step-by-step, following the commands and checking for obstacles at each position.
Here's how the algorithm would work step-by-step:
def walking_robot_simulation_brute_force(commands, obstacles):
x_coordinate = 0
y_coordinate = 0
facing_direction = 0 # 0: North, 1: East, 2: South, 3: West
directions = [(0, 1), (1, 0), (0, -1), (-1, 0)]
for command in commands:
if command == -1:
# Turn right
facing_direction = (facing_direction + 1) % 4
elif command == -2:
# Turn left
facing_direction = (facing_direction - 1) % 4
else:
# Move forward
for _ in range(command):
next_x = x_coordinate + directions[facing_direction][0]
next_y = y_coordinate + directions[facing_direction][1]
# Check if the next position is an obstacle
if (next_x, next_y) in set(map(tuple, obstacles)):
break
# Update the position
x_coordinate = next_x
y_coordinate = next_y
# Calculate the squared Euclidean distance from the origin.
distance = x_coordinate**2 + y_coordinate**2
return distance
The robot walks around a grid, following commands and avoiding obstacles. We need to keep track of its position and direction as it moves, while also efficiently checking if a potential move would lead to a collision with an obstacle.
Here's how the algorithm would work step-by-step:
def walking_robot_simulation(commands, obstacles):
x_coordinate = 0
y_coordinate = 0
direction = 0 # 0: North, 1: East, 2: South, 3: West
max_distance_squared = 0
# Store obstacles as a set of tuples for efficient lookup
obstacle_set = set((x, y) for x, y in obstacles)
# Define movement offsets for each direction
direction_offsets = [(0, 1), (1, 0), (0, -1), (-1, 0)]
for command in commands:
if command == -2:
direction = (direction - 1) % 4
elif command == -1:
direction = (direction + 1) % 4
else:
# Move forward, checking for obstacles at each step
for _ in range(command):
new_x = x_coordinate + direction_offsets[direction][0]
new_y = y_coordinate + direction_offsets[direction][1]
# If next step has an obstacle, stop moving
if (new_x, new_y) in obstacle_set:
break
x_coordinate = new_x
y_coordinate = new_y
# Update the maximum squared distance
max_distance_squared = max(max_distance_squared, x_coordinate * x_coordinate + y_coordinate * y_coordinate)
return max_distance_squared
Case | How to Handle |
---|---|
Empty commands array. | Initialize robot's position to (0,0) and return the list containing only (0,0). |
Empty obstacles array. | Robot moves according to the commands without any collision detection. |
Obstacles at origin (0,0). | Robot cannot start at an obstacle, and any move towards it from adjacent squares should be prevented. |
Commands array contains only -1 or -2 (turns). | The robot rotates but does not move forward, so it stays at (0,0) and the returned path contains only (0,0). |
Commands array contains large positive numbers, potentially leading to large coordinates and integer overflow. | Use long type to store coordinates, or use modulo arithmetic if the problem allows coordinates within a certain range. |
Obstacles are very close to each other. | Ensure the robot doesn't pass between them in a single forward move command. |
Maximum number of commands and/or obstacles leading to potential memory constraints. | Confirm coordinate ranges are within reasonable memory limits. |
Robot encounters the same obstacle multiple times from different directions. | The obstacle set allows for efficient collision detection regardless of the approach angle. |