/**
* // This is the robot's control interface.
* // You should not implement it, or speculate about its implementation
* interface Robot {
* // Returns true if the cell in front is open and robot moves into the cell.
* // Returns false if the cell in front is blocked and robot stays in the current cell.
* public boolean move();
*
* // Robot will stay in the same cell after calling turnLeft/turnRight.
* // Each turn will be 90 degrees.
* public void turnLeft();
* public void turnRight();
*
* // Clean the current cell.
* public void clean();
* }
*/
class Solution {
public void cleanRoom(Robot robot) {
DFS(robot, new HashSet<>(), 0, 0, 0);
}
private void DFS(Robot robot, Set<String> visited, int i, int j, int degrees) {
String path = i + "->" + j;
if(!visited.add(path)) return;
robot.clean();
for(int k = 0; k < 4; k++) {
if(robot.move()) {
int x = i, y = j;
switch(degrees) {
case 0:
x = i - 1;
break;
case 90:
y = j + 1;
break;
case 180:
x = i + 1;
break;
case 270:
y = j - 1;
break;
default:
break;
}
DFS(robot, visited, x, y, degrees);
goBack(robot);
}
robot.turnRight();
degrees = (degrees + 90) % 360;
}
}
private void goBack(Robot robot) {
robot.turnLeft();
robot.turnLeft();
robot.move();
robot.turnLeft();
robot.turnLeft();
}
}
/*
int[][] dirs = {{-1,0},{0,-1},{1,0},{0,1}};
more simple
*/
class Solution {
int[][] dirs = {{-1,0},{0,-1},{1,0},{0,1}};
public void cleanRoom(Robot robot) {
DFS(robot, new HashSet<>(), 0, 0, 0);
}
private void DFS(Robot robot, Set<String> visited, int i, int j, int curDir) {
String path = i + "->" + j;
if(!visited.add(path)) return;
robot.clean();
// curDir => 0: up, 1: left, 2: down, 3: right
for(int k = 0; k < 4; k++) {
if(robot.move()) {
int x = i + dirs[curDir][0];
int y = i + dirs[curDir][1];
DFS(robot, visited, x, y, curDir);
goBack(robot);
}
robot.turnRight();
//turn 90 degrees
curDir = (curDir + 1) % 4;
}
}
private void goBack(Robot robot) {
robot.turnLeft();
robot.turnLeft();
robot.move();
robot.turnLeft();
robot.turnLeft();
}
}