Solving Leetcode Interviews in Seconds with AI: Walking Robot Simulation II
Introduction
In this blog post, we will explore how to solve the LeetCode problem "2069" using AI. LeetCode is a popular platform for preparing for coding interviews, and with the help of AI tools like Chatmagic, we can generate solutions quickly and efficiently - helping you pass the interviews and get the job offer without having to study for months.
Problem Statement
A width x height grid is on an XY-plane with the bottom-left cell at (0, 0) and the top-right cell at (width - 1, height - 1). The grid is aligned with the four cardinal directions ("North", "East", "South", and "West"). A robot is initially at cell (0, 0) facing direction "East". The robot can be instructed to move for a specific number of steps. For each step, it does the following. Attempts to move forward one cell in the direction it is facing. If the cell the robot is moving to is out of bounds, the robot instead turns 90 degrees counterclockwise and retries the step. After the robot finishes moving the number of steps required, it stops and awaits the next instruction. Implement the Robot class: Robot(int width, int height) Initializes the width x height grid with the robot at (0, 0) facing "East". void step(int num) Instructs the robot to move forward num steps. int[] getPos() Returns the current cell the robot is at, as an array of length 2, [x, y]. String getDir() Returns the current direction of the robot, "North", "East", "South", or "West". Example 1: Input ["Robot", "step", "step", "getPos", "getDir", "step", "step", "step", "getPos", "getDir"] [[6, 3], [2], [2], [], [], [2], [1], [4], [], []] Output [null, null, null, [4, 0], "East", null, null, null, [1, 2], "West"] Explanation Robot robot = new Robot(6, 3); // Initialize the grid and the robot at (0, 0) facing East. robot.step(2); // It moves two steps East to (2, 0), and faces East. robot.step(2); // It moves two steps East to (4, 0), and faces East. robot.getPos(); // return [4, 0] robot.getDir(); // return "East" robot.step(2); // It moves one step East to (5, 0), and faces East. // Moving the next step East would be out of bounds, so it turns and faces North. // Then, it moves one step North to (5, 1), and faces North. robot.step(1); // It moves one step North to (5, 2), and faces North (not West). robot.step(4); // Moving the next step North would be out of bounds, so it turns and faces West. // Then, it moves four steps West to (1, 2), and faces West. robot.getPos(); // return [1, 2] robot.getDir(); // return "West" Constraints: 2 <= width, height <= 100 1 <= num <= 105 At most 104 calls in total will be made to step, getPos, and getDir.
Explanation
Here's a breakdown of the solution:
- Simulate Movement: The core idea is to simulate the robot's movement step by step, handling boundary checks and direction changes as required.
- Optimize Steps with Modulo: Since the robot moves in a cycle, we can use the modulo operator to efficiently determine the final position and direction after a large number of steps, without actually iterating through each step. This dramatically speeds things up for large 'num' values in the
step()function. We pre-calculate the perimeter of the grid's path. Direction Tracking: Keep track of the current direction as an index into a directions array, allowing easy switching between directions using modulo arithmetic.
Runtime Complexity: O(1) for
getPos()andgetDir(). O(1) forstep()after pre-calculation of the perimeter. Storage Complexity: O(1)
Code
class Robot:
def __init__(self, width: int, height: int):
self.width = width
self.height = height
self.x = 0
self.y = 0
self.dir_index = 0 # 0: East, 1: North, 2: West, 3: South
self.directions = ["East", "North", "West", "South"]
self.perimeter = 2 * (width + height) - 4
self.moved = False # To track if any step has been taken yet
def step(self, num: int) -> None:
num %= self.perimeter
if num == 0 and not self.moved:
pass # Special case for initial position
elif num == 0:
self.dir_index = (self.dir_index) % 4
return # Special case for when num is a multiple of the perimeter
self.moved = True
while num > 0:
if self.dir_index == 0: # East
if self.x + num < self.width:
self.x += num
num = 0
else:
num -= (self.width - 1 - self.x)
self.x = self.width - 1
self.dir_index = 1
elif self.dir_index == 1: # North
if self.y + num < self.height:
self.y += num
num = 0
else:
num -= (self.height - 1 - self.y)
self.y = self.height - 1
self.dir_index = 2
elif self.dir_index == 2: # West
if self.x - num >= 0:
self.x -= num
num = 0
else:
num -= self.x
self.x = 0
self.dir_index = 3
elif self.dir_index == 3: # South
if self.y - num >= 0:
self.y -= num
num = 0
else:
num -= self.y
self.y = 0
self.dir_index = 0
def getPos(self) -> list[int]:
return [self.x, self.y]
def getDir(self) -> str:
if not self.moved:
return "East"
return self.directions[self.dir_index % 4]