Skip to content

Instantly share code, notes, and snippets.

@mskasal
Created August 8, 2017 20:23
Show Gist options
  • Save mskasal/648744d8eb933df8b714041b6e05744e to your computer and use it in GitHub Desktop.
Save mskasal/648744d8eb933df8b714041b6e05744e to your computer and use it in GitHub Desktop.
Mars Rover challenge
/* MARS ROVERS
A squad of robotic rovers are to be landed by NASA on a plateau on Mars. This plateau, which
is curiously rectangular, must be navigated by the rovers so that their on-board cameras can
get a complete view of the surrounding terrain to send back to Earth.
A rover's position and location is represented by a combination of x and y co-ordinates and
a letter representing one of the four cardinal compass points. The plateau is divided up into
a grid to simplify navigation. An example position might be 0, 0, N, which means the rover is
in the bottom left corner and facing North.
In order to control a rover, NASA sends a simple string of letters. The possible letters are
'L', 'R' and 'M'. 'L' and 'R' makes the rover spin 90 degrees left or right respectively,
without moving from its current spot. 'M' means move forward one grid point, and maintain
the same heading.
Assume that the square directly North from (x, y) is (x, y+1).
INPUT: The first input is the upper-right coordinates of the plateau, the lower-left coordinates
are assumed to be 0,0.
The rest of the input is information pertaining to the rovers that have been deployed.
Each rover has two lines of input. The first line gives the rover's position, and the
second line is a series
of instructions telling the rover how to explore the plateau.
The position is made up of two integers and a letter separated by spaces, corresponding
to the x and y co-ordinates and the rover's orientation.
Each rover will be finished sequentially, which means that the second rover won't start
to move until the first one has finished moving.
Code :
MarsRover marsRover = new MarsRover(5,5);
marsRover.addRover(1,2,'N');
marsRover.sendCommand('LMLMLMLMM');
marsRover.addRover(3,3,'E');
marsRover.sendCommand('MMRMMRMRRM');
marsRover.getFinalPositions() returns a list of two strings
1 3 N
5 1 E
*/
class Rover {
// Set default positions, direction
constructor(
xPosition = 0,
yPosition = 0,
direction = 'N') {
this.xPosition = xPosition;
this.yPosition = yPosition;
this.direction = direction;
}
proceed(command) {
if (command === 'M') {
this.move();
} else if (command === 'R' || command === 'L') {
this.turn(command);
}
}
turn(command) {
// [L]EFT as -1, [R]IGHT as 1.
// Clockwise increase, decrease for reverse.
const turnTypes = { L: -1, R: 1 };
let directionAsStr = '';
let directionAsInt = this.getDirectionAsInt(this.direction);
// When rover turns directionAsInt can define only as (0,1,2,3)
directionAsInt = (4 + ((directionAsInt + turnTypes[command]) % 4)) % 4;
// Changing direction int to re-usable string type ([N]orth, [E]ast, [S]outh, [W]est)
directionAsStr = this.getDirectionAsString(directionAsInt);
this.direction = directionAsStr;
}
move() {
switch (this.direction) {
case 'N':
this.yPosition += 1;
break;
case 'E':
this.xPosition += 1;
break;
case 'S':
this.yPosition -= 1;
break;
case 'W':
this.xPosition -= 1;
break;
default:
break;
}
this.crashTest();
}
static getDirectionAsInt(directionAsStr) {
const directionsAsInt = { N: 0, E: 1, S: 2, W: 3 };
return directionsAsInt[directionAsStr];
}
static getDirectionAsString(directionAsInt) {
let directionAsStr = '';
if (directionAsInt === 0) {
directionAsStr = 'N';
} else if (directionAsInt === 1) {
directionAsStr = 'E';
} else if (directionAsInt === 2) {
directionAsStr = 'S';
} else if (directionAsInt === 3) {
directionAsStr = 'W';
}
return directionAsStr;
}
static crashTest() {
if (this.xPosition > 5 || this.yPosition > 5 ||
this.xPosition < 0 || this.yPosition < 0) {
console.log('Crashed!');
}
}
getRoverCurrentStatus() {
return [this.xPosition, this.yPosition, this.direction];
}
}
class MarsRover {
constructor(width, height) {
this.grid = { width, height };
this.roverList = [];
}
addRover(xPosition, yPosition, direction) {
const newRover = new Rover(xPosition, yPosition, direction);
this.roverList.push(newRover);
this.landTest({ xPosition, yPosition });
}
sendCommand(commandLine) {
commandLine.split('').forEach((command) => {
// Getting always last rover, after last command squence over
this.roverList[this.roverList.length - 1].proceed(command);
});
}
getFinalPositions() {
this.roverList.forEach((rover) => {
console.log(rover.getRoverCurrentStatus().join(' '));
});
}
static landTest(newRover) {
// Rovers can not be land on out of grid
// Also NASA can not cancel the command sequence :)
if (newRover.xPosition > this.grid.width ||
newRover.yPosition > this.grid.height) {
console.log('Rover can not be place! Out of grid.');
console.log("Can not cancel 'sendCommand' command sequence, rover probably gonna crash!");
}
}
}
// COMMANDS
const marsRover = new MarsRover(5, 5);
marsRover.addRover(1, 2, 'N');
marsRover.sendCommand('LMLMLMLMM');
marsRover.addRover(3, 3, 'E');
marsRover.sendCommand('MMRMMRMRRM');
marsRover.getFinalPositions();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment