Skip to content

Commit 811b680

Browse files
committed
2069. Walking Robot Simulation II: AC
1 parent 194eb4a commit 811b680

File tree

2 files changed

+170
-0
lines changed

2 files changed

+170
-0
lines changed

src/solution/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1560,3 +1560,4 @@ mod s2063_vowels_of_all_substrings;
15601560
mod s2064_minimized_maximum_of_products_distributed_to_any_store;
15611561
mod s2065_maximum_path_quality_of_a_graph;
15621562
mod s2068_check_whether_two_strings_are_almost_equivalent;
1563+
mod s2069_walking_robot_simulation_ii;
Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
/**
2+
* [2069] Walking Robot Simulation II
3+
*
4+
* 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".
5+
* The robot can be instructed to move for a specific number of steps. For each step, it does the following.
6+
* <ol>
7+
* Attempts to move forward one cell in the direction it is facing.
8+
* If the cell the robot is moving to is out of bounds, the robot instead turns 90 degrees counterclockwise and retries the step.
9+
* </ol>
10+
* After the robot finishes moving the number of steps required, it stops and awaits the next instruction.
11+
* Implement the Robot class:
12+
*
13+
* Robot(int width, int height) Initializes the width x height grid with the robot at (0, 0) facing "East".
14+
* void step(int num) Instructs the robot to move forward num steps.
15+
* int[] getPos() Returns the current cell the robot is at, as an array of length 2, [x, y].
16+
* String getDir() Returns the current direction of the robot, "North", "East", "South", or "West".
17+
*
18+
*
19+
* Example 1:
20+
* <img alt="example-1" src="https://assets.leetcode.com/uploads/2021/10/09/example-1.png" style="width: 498px; height: 268px;" />
21+
* Input
22+
* ["Robot", "step", "step", "getPos", "getDir", "step", "step", "step", "getPos", "getDir"]
23+
* [[6, 3], [2], [2], [], [], [2], [1], [4], [], []]
24+
* Output
25+
* [null, null, null, [4, 0], "East", null, null, null, [1, 2], "West"]
26+
* Explanation
27+
* Robot robot = new Robot(6, 3); // Initialize the grid and the robot at (0, 0) facing East.
28+
* robot.step(2); // It moves two steps East to (2, 0), and faces East.
29+
* robot.step(2); // It moves two steps East to (4, 0), and faces East.
30+
* robot.getPos(); // return [4, 0]
31+
* robot.getDir(); // return "East"
32+
* robot.step(2); // It moves one step East to (5, 0), and faces East.
33+
* // Moving the next step East would be out of bounds, so it turns and faces North.
34+
* // Then, it moves one step North to (5, 1), and faces North.
35+
* robot.step(1); // It moves one step North to (5, 2), and faces North (not West).
36+
* robot.step(4); // Moving the next step North would be out of bounds, so it turns and faces West.
37+
* // Then, it moves four steps West to (1, 2), and faces West.
38+
* robot.getPos(); // return [1, 2]
39+
* robot.getDir(); // return "West"
40+
*
41+
*
42+
* Constraints:
43+
*
44+
* 2 <= width, height <= 100
45+
* 1 <= num <= 10^5
46+
* At most 10^4 calls in total will be made to step, getPos, and getDir.
47+
*
48+
*/
49+
pub struct Solution {}
50+
51+
// problem: https://leetcode.com/problems/walking-robot-simulation-ii/
52+
// discuss: https://leetcode.com/problems/walking-robot-simulation-ii/discuss/?currentPage=1&orderBy=most_votes&query=
53+
54+
// submission codes start here
55+
56+
enum Direction {
57+
North,
58+
East,
59+
South,
60+
West,
61+
}
62+
63+
struct Robot {
64+
max_x: i32,
65+
max_y: i32,
66+
current_route_num: i32,
67+
position_cache: (i32, i32, Direction),
68+
}
69+
70+
/**
71+
* `&self` means the method takes an immutable reference.
72+
* If you need a mutable reference, change it to `&mut self` instead.
73+
*/
74+
impl Robot {
75+
fn new(width: i32, height: i32) -> Self {
76+
Self {
77+
max_x: width - 1,
78+
max_y: height - 1,
79+
current_route_num: -1,
80+
position_cache: (0, 0, Direction::East),
81+
}
82+
}
83+
84+
fn step(&mut self, num: i32) {
85+
if self.current_route_num < 0 {
86+
self.current_route_num = 0;
87+
}
88+
89+
let perim = (self.max_x + 1) * 2 + (self.max_y - 1) * 2;
90+
91+
self.current_route_num += num;
92+
self.current_route_num %= perim;
93+
self.set_position_data();
94+
}
95+
96+
fn get_pos(&self) -> Vec<i32> {
97+
vec![self.position_cache.0.clone(), self.position_cache.1.clone()]
98+
}
99+
100+
fn get_dir(&self) -> String {
101+
match self.position_cache.2 {
102+
Direction::North => "North",
103+
Direction::East => "East",
104+
Direction::South => "South",
105+
Direction::West => "West",
106+
}
107+
.to_string()
108+
}
109+
110+
fn set_position_data(&mut self) {
111+
self.position_cache = if self.current_route_num < 0 {
112+
(0, 0, Direction::East)
113+
} else if self.current_route_num == 0 {
114+
(self.current_route_num, 0, Direction::South)
115+
} else if self.current_route_num <= self.max_x {
116+
(self.current_route_num, 0, Direction::East)
117+
} else if self.current_route_num <= self.max_x + self.max_y {
118+
(
119+
self.max_x,
120+
self.current_route_num - self.max_x,
121+
Direction::North,
122+
)
123+
} else if self.current_route_num <= 2 * self.max_x + self.max_y {
124+
(
125+
self.max_x - (self.current_route_num - self.max_x - self.max_y),
126+
self.max_y,
127+
Direction::West,
128+
)
129+
} else {
130+
(
131+
0,
132+
self.max_y - (self.current_route_num - 2 * self.max_x - self.max_y),
133+
Direction::South,
134+
)
135+
}
136+
}
137+
}
138+
139+
/**
140+
* Your Robot object will be instantiated and called as such:
141+
* let obj = Robot::new(width, height);
142+
* obj.step(num);
143+
* let ret_2: Vec<i32> = obj.get_pos();
144+
* let ret_3: String = obj.get_dir();
145+
*/
146+
147+
// submission codes end
148+
149+
#[cfg(test)]
150+
mod tests {
151+
use super::*;
152+
153+
#[test]
154+
fn test_2069_example_1() {
155+
let mut robot = Robot::new(6, 3); // Initialize the grid and the robot at (0, 0) facing East.
156+
robot.step(2); // It moves two steps East to (2, 0), and faces East.
157+
robot.step(2); // It moves two steps East to (4, 0), and faces East.
158+
assert_eq!(robot.get_pos(), vec![4, 0]); // return [4, 0]
159+
assert_eq!(robot.get_dir(), "East".to_string()); // return "East"
160+
robot.step(2); // It moves one step East to (5, 0), and faces East.
161+
// Moving the next step East would be out of bounds, so it turns and faces North.
162+
// Then, it moves one step North to (5, 1), and faces North.
163+
robot.step(1); // It moves one step North to (5, 2), and faces North (not West).
164+
robot.step(4); // Moving the next step North would be out of bounds, so it turns and faces West.
165+
// Then, it moves four steps West to (1, 2), and faces West.
166+
assert_eq!(robot.get_pos(), vec![1, 2]); // return [1, 2]
167+
assert_eq!(robot.get_dir(), "West".to_string()); // return "West"
168+
}
169+
}

0 commit comments

Comments
 (0)