Skip to content

Commit d6da29b

Browse files
author
Joshua Goller
committed
489 attempt 2
1 parent 59436ea commit d6da29b

File tree

1 file changed

+149
-0
lines changed

1 file changed

+149
-0
lines changed
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
"""
2+
Given a robot cleaner in a room modeled as a grid. Each cell in the grid can be empty or blocked.
3+
The robot cleaner with 4 given APIs can move forward, turn left or turn right. Each turn it made
4+
is 90 degrees. When it tries to move into a blocked cell, its bumper sensor detects the obstacle
5+
and it stays on the current cell. Design an algorithm to clean the entire room using only the 4
6+
given APIs shown below.
7+
8+
interface Robot {
9+
// returns true if next cell is open and robot moves into the cell.
10+
// returns false if next cell is obstacle and robot stays on the current cell.
11+
boolean move();
12+
13+
// Robot will stay on the same cell after calling turnLeft/turnRight.
14+
// Each turn will be 90 degrees.
15+
void turnLeft();
16+
void turnRight();
17+
18+
// Clean the current cell.
19+
void clean();
20+
}
21+
22+
Example:
23+
24+
Input:
25+
room = [
26+
[1,1,1,1,1,0,1,1],
27+
[1,1,1,1,1,0,1,1],
28+
[1,0,1,1,1,1,1,1],
29+
[0,0,0,1,0,0,0,0],
30+
[1,1,1,1,1,1,1,1]
31+
],
32+
row = 1,
33+
col = 3
34+
35+
Explanation:
36+
All grids in the room are marked by either 0 or 1.
37+
0 means the cell is blocked, while 1 means the cell is accessible.
38+
The robot initially starts at the position of row=1, col=3.
39+
From the top left corner, its position is one row below and three columns right.
40+
41+
Notes:
42+
- The input is only given to initialize the room and the robot's position internally.
43+
You must solve this problem "blindfolded". In other words, you must control the robot
44+
using only the mentioned 4 APIs, without knowing the room layout and the initial robot's position.
45+
- The robot's initial position will always be in an accessible cell.
46+
- The initial direction of the robot will be facing up.
47+
- All accessible cells are connected, which means the all cells marked as 1 will be
48+
accessible by the robot.
49+
- Assume all four edges of the grid are all surrounded by wall.
50+
---------------------------------------------------------------
51+
- In: Grid, starting position
52+
- Out: set of behaviors such that all cells are visited
53+
- Cases:
54+
- Fully explorable room
55+
- Completely unexplorable room
56+
- Variants
57+
58+
- clean() is a red herring. We just need to visit every cell.
59+
- A BFS or DFS will ensure we visit every cell; however, for a BFS,
60+
we can wind up in an invalid state - we cannot explore a cell we are not
61+
next to currently, so if we try to visit the neighbor of a cell we were
62+
in previously, we could have trouble. DFS is probably a better option.
63+
- We do not actually know what cell we are in when we start; however
64+
we can just assume we're in 0,0 and go from there; we won't worry about
65+
array index errors since move() will return false.
66+
- We don't have access to the grid, just the robot; as such, we need to
67+
program our DFS from turning and moving
68+
- Perhaps we should implement Solution methods that match
69+
the robot's methods and in each call update the internal representation
70+
as well as call the robot API?
71+
- Our overall algorithm should be something like:
72+
visit(cell, parent):
73+
clean()
74+
for each neighbor:
75+
face(neighbor) # turns robot correctly
76+
if move(): # moves robot forward
77+
visit_current_cell(neighbor, current)
78+
face(parent)
79+
move() # final move will return false, which is OK.
80+
- The best thing to do would be if we could completely abstract away direction
81+
from our high level algorithm; maybe if we implement a moveTo() that handles
82+
correctly facing?
83+
- Our overall algorithm should be something like:
84+
visit(cell, parent):
85+
clean()
86+
for each neighbor:
87+
if moveTo(): # moves robot forward
88+
visit_current_cell(neighbor, current)
89+
moveTo(parent) # final move will return false, which is OK.
90+
91+
moveTo(src, dst):
92+
# turn to face correct direction;
93+
# if move() succeeds, update position and return true
94+
# if move() fails, don't update position and return false
95+
96+
face(src, dest):
97+
# determine which direction in the list should be faced
98+
# call robot.turnLeft() or turnRight() until facing that direction
99+
"""
100+
101+
UP, RIGHT, DOWN, LEFT = (-1, 0), (0, 1), (1, 0), (0, 1)
102+
DIRECTIONS = [UP, RIGHT, DOWN, LEFT]
103+
104+
105+
class Solution(object):
106+
def __init__(self):
107+
self.visited = set()
108+
self.position = (0, 0) # assumed
109+
self.directions_i = 0
110+
111+
def cleanRoom(self, robot):
112+
self.robot = robot
113+
self.visit(robot, self.position) # what should the parent of the first cell be?
114+
115+
def visit(self, cell, parent):
116+
"""
117+
clean()
118+
for each neighbor:
119+
if moveTo(): # moves robot forward
120+
visit_current_cell(neighbor, current)
121+
moveTo(parent) # final move will return false, which is OK.
122+
"""
123+
self.visited.add((self.row, self.col))
124+
self.robot.clean()
125+
return
126+
127+
# returns true if next cell is open and robot moves into the cell.
128+
# returns false if next cell is obstacle and robot stays on the current cell.
129+
def moveTo(self, cell):
130+
self.face(cell)
131+
if self.robot.move():
132+
self.position[0] += DIRECTIONS[self.directions_i][0]
133+
self.position[1] += DIRECTIONS[self.directions_i][1]
134+
return True
135+
return False
136+
137+
# Ensure the robot is facing in the correct direction to move to
138+
# this cell; turn right until so.
139+
def face(self, cell):
140+
correct_direction = (cell[0] - self.position[0], cell[1] - self.position[1])
141+
if correct_direction not in DIRECTIONS: # diagonal or other invalid direction
142+
return
143+
while DIRECTIONS[self.directions_i] != correct_direction:
144+
self.robot.turnRight()
145+
self.directions_i = (self.directions_i + 1) % 4
146+
147+
148+
if __name__ == '__main__':
149+
s = Solution()

0 commit comments

Comments
 (0)