Skip to content

Instantly share code, notes, and snippets.

@shadybotros
Last active February 1, 2019 16:20
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shadybotros/558c1f844993a534ff1674462b6ba373 to your computer and use it in GitHub Desktop.
Save shadybotros/558c1f844993a534ff1674462b6ba373 to your computer and use it in GitHub Desktop.
An attempt to solve the Mars Rover Kata (https://codurance.com/2017/11/16/katas-for-functional-calisthenics/#marsroverkata), assuming an unlimited world and without wrapping. Try it in the Ramda REPL (https://ramdajs.com/repl/).
const moveRover = curry((initialPosition, commands) => {
return commands.reduce(moveRoverOnce, initialPosition);
});
const moveRoverOnce = (position, command) => pipe(
mapToInternalFormat,
rotate(command),
move(command),
mapBack
)(position);
const mapToInternalFormat = position => ({
x: position.x,
y: position.y,
angle: getAngleFromOrientation(position.orientation)
});
const getAngleFromOrientation = (orientation) => ({
'W': 0,
'N': Math.PI / 2,
'E': Math.PI,
'S': Math.PI * 1.5
})[orientation];
const rotate = curry((command, internalPosition) => ({
...internalPosition,
angle: internalPosition.angle += getAngleFromDirection(command)
}));
const getAngleFromDirection = (direction) => ({
l: -Math.PI / 2,
r: Math.PI / 2,
f: 0,
b: 0
})[direction];
const move = curry((command, position) => ({
...position,
x: position.x + Math.cos(position.angle) * getSpeed(command),
y: position.y + Math.sin(position.angle) * getSpeed(command)
}));
const getSpeed = (command) => ({
l: 0,
r: 0,
f: 1,
b: -1
})[command];
const mapBack = internalPosition => ({
x: internalPosition.x,
y: internalPosition.y,
orientation: getOrientationFromAngle(Math.round(internalPosition.angle / Math.PI * 180))
});
const getOrientationFromAngle = (angle) => ({
0: 'E',
90: 'N',
180: 'W',
270: 'S'
})[angle];
const initialPosition = {
x: 10,
y: 3,
orientation: 'N'
};
const commands = ['f', 'f', 'b', 'l', 'f', 'r', 'r', 'f'];
const expectedEndPosition = {
x: 10,
y: 4,
orientation: 'E'
};
const moveRoverFromInitialPosition = moveRover(initialPosition);
const actualEndPosition = moveRoverFromInitialPosition(commands);
equals(actualEndPosition, expectedEndPosition);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment