Microsoft Interview Question
Country: United States
it depends on our code that in which direction the rower should go and assume that left is in the same direction for both the rovers.
dont really understand the question, how one rover knows the other rover's position?
whenever a rover reaches a parachute , it will know that the other rover is ahead of it.
why?
the question here is ambiguous but the original question where this is taken from specifies that both the rovers are on same straight line so they cant move in parallel.
the question here is ambiguous but the original question where this is taken from specifies that both the rovers are on same straight line so they cant move in parallel.
the only condition under which this may not work is when both land at the exact same time (because then they'll execute the exact same thing at the exact same time and hence will never meet)
#define NOT_MET_YET 1
int i, steps;
steps=0;
while(1) {
If on parachute go to LABEL_START;
NO OPERATION;
}
LABEL_START:
while(NOT_MET_YET) { // whats the check to see if they've met ??
for(i=0; i<steps; i++) { go left; /* go left 'i' steps */ }
for(i=0; i<steps; i++) { go right; /* go right 'i' steps */ }
for(i=0; i<steps; i++) { go right; /* go right 'i' steps */ }
for(i=0; i<steps; i++) { go left; /* go left 'i' steps */ }
i++;
}
You cant use for loops or any other variables. Only allowed commands are listed in my question. I got the logic right on this one, but i could not code it. Here is the logic
" Both rovers land. Then move both to left. Eventually one of them will land on the parachute of other. Then make the one on parachute stop (no operation) and move just the other to right."
This is the logic he asked me to code, but i couldnt using just commands above.
Dee, can you help me understand the ques.?
3. If on parachute go to lablel.
What do you mean by "if on parachute".
Are parachutes (say P1 and P2) as landing spots that can be used as references?
Also, I don't understand "Then move both to left. Eventually one of them will land on the parachute of other. "
why would that be? If two points have some distance between them and you move then equally in equal direction, they will never meet.
I am perhaps missing your point here. Can you clarify please?
fizzybuzzer Here is what I mean:
1. Yes one they land they drop their parachutes at the location. Parachutes dont move with the rovers. So yes, these parachutes can be used as a reference to find landing location
2. Let me explain my logic again:
Say there are 2 rovers, A and B
i. Both the rovers are dropped on different points on Mars. Say x and y points respectively (y is on the left of x). That means rover B is on the left of rover A.
ii. Now start moving both the rovers to left (A and B both start moving to left, their parachutes are at landing position). After a while of moving, the rover A will come in contact of parachute of rover B.
iii At this point we need to make use of command 'ON PARACHUTE then NO OPERATION' and we need to stop rover A from moving.
iv. And now we need to start moving JUST the rover B to right. After a while rover B will meet rover A.
Does that make sense?
This will only work if the x and y are in same line,
what if x and y are on parallel line and distance between them is > r ; Radius of the parachute
then even if you move both to left they will go into infinite distance since Mars is straight infinite plane .
Few questions:
1. Do both rovers land at the same time?
2. If i choose a command will both both rovers follow it simultaneously or is there turn pattern? Like if i choose to 'Go Left' then both will move to left at the same time?
With no loops or counters, go back to your basic finite state machine coding:
Let the phrase LEFT expand to: go left; @label if on_parachute goto @label; go right;
(that is: step left, stop if parachute, else go back)
and LEFT(n) expand to: {go left; @label if on_parachute goto @label;} ^n {go right;} ^n
(that is: step and test 'n' times to the left, then return)
Define RIGHT(n) similarly.
since we cannot loop or keep state: program each rover as:
LEFT(1); RIGHT(2); LEFT(4); RIGHT(8); ... up to diameter of Mars
(right, that was give as infinite, so impress your interviewer by reminding them that a finite state machine cannot search an infinite space; we do not have a turing machine or even a stack machine...)
What it does:
Each rover take increasingly longer excursions to left and then to right,
but will stop when it find the parachute of the other rover (and wait there)
eventually, the other rover will come back to its own parachute and meet the one waiting there.
Note: the numbers 1,2,4 can be scaled to any arbitrarily large/ascending values.
@MJ: if the rovers collide on landing, then the post-condition is immediately satisfied: the rovers meet.
If we have goto label then it'll be like this (r1:=rover1, r2:=rover2):
r1.goLeft
r2.goLeft
:loop
if r1.onParachute goto r1p
if r2.onParachute goto r2p
r1.goLeft
r2.goLeft
goto loop
:r1p
r1.noOp
r2.goRight
if r2.onParachute goto end
goto r1p
:r2p
r2.noOp
r1.goRight
if r1.onParachute goto end
goto r2p
:end
but if I can't use goto without if onParachute then it's problematic
if(onParachute)
goto label execute_code
execute_code :
static int count;
count++;
if(count<3) // on landing each rover visit the label therefore count =2
{
while(1)
{
go left;
no operation; //to make the rover slow
}
}
else if(count ==3) // one rover has reached others parachute
{
while(1)
go left;
}
else ; //count can never be 4
package test.command.test;
import test.command.ControlStation;
import test.command.Planet;
import test.command.model.Cell
public class TestKlass {
public static void main(String[] args) {
ControlStation station = new ControlStation();
String firstLine ="5 5";
String secLine ="1 2 N";
String command = "LMLMLMLMM";
Planet planet = station.getData(firstLine, secLine);
Cell cell =station.processCommand(planet, command);
System.out.println("["+cell.getX()+", "+ cell.getY()+", "+cell.getDir()+"]");
String secLine1 ="3 3 E";
String command1 = "MMRMMRMRRM";
Planet planet1 = station.getData(firstLine, secLine1);
cell =station.processCommand(planet1, command1);
System.out.println("["+cell.getX()+", "+ cell.getY()+", "+cell.getDir()+"]");
}
}
package test.command.model;
public class Grid {
private int[][] layout = null;
private int xMax;
private int yMax;
public Grid(int xMax, int yMax) {
this.layout = new int[xMax][yMax];
this.xMax = xMax;
this.yMax = yMax;
}
public int[][] getLayout() {
return layout;
}
public int getXMax() {
return xMax;
}
public int getYMax() {
return yMax;
}
public boolean xbound(int xx){
if(xx >=0 && xx <= xMax){
return true;
}
return false;
}
public boolean ybound(int yy){
if(yy >=0 && yy <= yMax){
return true;
}
return false;
}
}
package test.command.model;
public class Cell {
private int x;
private int y;
private String dir;
public Cell() {}
public Cell(int x, int y,String dir) {
this.x=x;this.y=y;this.dir =dir;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public String getDir() {
return dir;
}
public void setDir(String dir) {
this.dir = dir;
}
}
package test.command;
import test.command.model.Cell;
import test.command.model.Grid;
public interface RoverSignal {
public Cell getPosition();
public void setPosition(Cell position);
public Remote getRemote();
public void setRemote(Remote remote);
public Grid getGrid();
public void setGrid(Grid grid);
}
package test.command;
import test.command.model.Cell;
import test.command.model.Grid;
public class Rover implements RoverSignal{
private Cell position;
private Remote remote = null;
private Grid grid = null;
public Rover(){
this.remote = new RemoteImpl();
}
public Rover(Grid grid ){
this.grid = grid;
this.remote = new RemoteImpl();
}
private class RemoteImpl extends RemoteConfig implements Remote {
public RemoteImpl() {
super();
}
@Override
public void leftRotate(Cell cell) {
String dir = cell.getDir();
cell.setDir(leftRotateMap.get(dir));
setPosition(cell);
}
@Override
public void move(Cell cell) {
String dir = cell.getDir();
if(dir.equals("N")){
if(grid.ybound(cell.getY()+1))
cell.setY(cell.getY()+1);
}else if(dir.equals("S")){
if(grid.ybound(cell.getY()-1))
cell.setY(cell.getY()-1);
}else if(dir.equals("E")){
if(grid.xbound(cell.getX()+1))
cell.setX(cell.getX()+1);
}else if(dir.equals("W")){
if(grid.xbound(cell.getX()-1))
cell.setX(cell.getX()-1);
}
setPosition(cell);return;
}
@Override
public void rightRotate(Cell cell) {
String dir = cell.getDir();
cell.setDir(rightRotateMap.get(dir));
setPosition(cell);
}
}
public Cell getPosition() {
return position;
}
public void setPosition(Cell position) {
this.position = position;
}
public Remote getRemote() {
return remote;
}
public void setRemote(Remote remote) {
this.remote = remote;
}
public Grid getGrid() {
return grid;
}
public void setGrid(Grid grid) {
this.grid = grid;
}
}
package test.command;
import java.util.HashMap;
import java.util.Map;
public class RemoteConfig {
protected Map<String, String> leftRotateMap = null;
{
leftRotateMap = new HashMap<String, String>();
leftRotateMap.put("N", "W");
leftRotateMap.put("W", "S");
leftRotateMap.put("S", "E");
leftRotateMap.put("E", "N");
}
protected Map<String, String> rightRotateMap = null;
{
rightRotateMap = new HashMap<String, String>();
rightRotateMap.put("N", "E");
rightRotateMap.put("E", "S");
rightRotateMap.put("S", "W");
rightRotateMap.put("W", "N");
}
public RemoteConfig() {
// TODO Auto-generated constructor stub
}
}
package test.command;
import test.command.model.Cell;
public interface Remote {
public void move(Cell cell);
public void leftRotate(Cell cell);
public void rightRotate(Cell cell);
}
package test.command;
import test.command.model.Grid;
public class Planet {
private Grid grid;
private Rover rover;
private Grid[] grids;
private Rover[] rovers;
public Planet() {
}
public Planet(Grid[] grids, Rover[] rovers) {
this.grids = grids;
this.rovers = rovers;
}
public Planet(Grid grid, Rover rover) {
this.grid = grid;
this.rover = rover;
}
public Grid getGrid() {
return grid;
}
public void setGrid(Grid grid) {
this.grid = grid;
}
public Rover getRover() {
return rover;
}
public void setRover(Rover rover) {
this.rover = rover;
}
public Grid[] getGrids() {
return grids;
}
public void setGrids(Grid[] grids) {
this.grids = grids;
}
public Rover[] getRovers() {
return rovers;
}
public void setRovers(Rover[] rovers) {
this.rovers = rovers;
}
}
package test.command;
import test.command.model.Cell;
import test.command.model.Grid;
public class ControlStation {
private Planet planet;
private String[] commands;
private Grid grid;
public Cell processCommand(Planet planet, String command){
if(null == command || null == planet)return null;
Cell cell = null;
RoverSignal roverSignal = planet.getRover();
Remote remote = roverSignal.getRemote();
cell = roverSignal.getPosition();
char[] comArray = command.toCharArray();
for (char c : comArray) {
if('L' == c){
remote.leftRotate(cell);
}else if('R' == c){
remote.rightRotate(cell);
}else if('M'==c){
remote.move(cell);
}
}
return cell;
}
public Planet getData(String firstLine, String secLine){
Cell cell = getCell(secLine);
Grid grid = getGrid(firstLine);
Rover rover = new Rover();
rover.setGrid(grid);
rover.setPosition(cell);
return new Planet(grid,rover);
}
private Cell getCell(String secLine){
String[] arr = secLine.split("\\s+");
int xx= Integer.parseInt(arr[0]);
int yy= Integer.parseInt(arr[1]);
return new Cell(xx, yy, arr[2]);
}
private Grid getGrid(String firstLine){
String[] arr = firstLine.split("\\s+");
int xMax= Integer.parseInt(arr[0]);
int yMax= Integer.parseInt(arr[1]);
return new Grid(xMax, yMax);
}
}
The logic is that make the both the rover go in the same direction either left or right .
Make its speed slow by putting a NOP after every left command.
And whenever a rover reaches a parachute , it will know that the other rover is ahead of it.So in this rover dont execute the NOP making its speed faster .Hence the rover behind will get fast and meet up with the other rover.
}
- dineshbansal007 November 03, 2012