Write a robot simulator.
A robot factory's test facility needs a program to verify robot movements.
The robots have three possible movements:
Robots are placed on a hypothetical infinite grid, facing a particular direction (north, east, south, or west) at a set of {x,y} coordinates, e.g., {3,8}, with coordinates increasing to the north and east.
The robot then receives a number of instructions, at which point the testing facility verifies the robot's new position, and in which direction it is pointing.
To run the tests, run the command busted
from within the exercise directory.
For more detailed information about the Lua track, including how to get help if you're having trouble, please visit the exercism.io Lua language page.
Inspired by an interview question at a famous company.
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
local Robot = require('robot-simulator')
describe('robot-simulator', function()
it('should make the current x, y, and heading available', function()
local robot = Robot{ x = 5, y = 10, heading = 'north' }
assert.equal(5, robot.x)
assert.equal(10, robot.y)
assert.equal('north', robot.heading)
end)
it('should move forward when an A command is given', function()
local robot = Robot{ x = 5, y = 10, heading = 'north' }
robot:move('A')
assert.equal(5, robot.x)
assert.equal(11, robot.y)
assert.equal('north', robot.heading)
end)
it('should change heading clockwise when an R command is given', function()
local robot = Robot{ x = 5, y = 10, heading = 'north' }
robot:move('R')
assert.equal(5, robot.x)
assert.equal(10, robot.y)
assert.equal('east', robot.heading)
end)
it('should change heading counter-clockwise when an L command is given', function()
local robot = Robot{ x = 5, y = 10, heading = 'north' }
robot:move('L')
assert.equal(5, robot.x)
assert.equal(10, robot.y)
assert.equal('west', robot.heading)
end)
it('should be able to chain commands', function()
local robot = Robot{ x = 5, y = 10, heading = 'north' }
robot:move('LAR')
assert.equal(4, robot.x)
assert.equal(10, robot.y)
assert.equal('north', robot.heading)
end)
it('should be able to turn all the way around by turning clockwise', function()
local robot = Robot{ x = 7, y = -10, heading = 'north' }
robot:move('RRRR')
assert.equal(7, robot.x)
assert.equal(-10, robot.y)
assert.equal('north', robot.heading)
end)
it('should be able to turn all the way around by turning counter-clockwise', function()
local robot = Robot{ x = 5, y = 10, heading = 'south' }
robot:move('LLLL')
assert.equal(5, robot.x)
assert.equal(10, robot.y)
assert.equal('south', robot.heading)
end)
it('should be able to advance in all directions', function()
local robot = Robot{ x = 5, y = 10, heading = 'north' }
robot:move('ARAARAARAR')
assert.equal(6, robot.x)
assert.equal(9, robot.y)
assert.equal('north', robot.heading)
end)
it('should raise an error when an invalid command is used', function()
local robot = Robot{ x = 5, y = 10, heading = 'north' }
assert.has_errors(function() robot:move('ARALZR') end)
end)
end)
local robot = {}
local brain = {
north = { L = 'west', R = 'east', y = 1 },
east = { L = 'north', R = 'south', x = 1 },
south = { L = 'east', R = 'west', y = -1 },
west = { L = 'south', R = 'north', x = -1 }
}
local function move(self, command)
for i = 1, #command do
local c = command:sub(i,i)
if c == 'R' or c == 'L' then self.heading = brain[self.heading][c]
elseif c == 'A' then
self.x = self.x + (brain[self.heading].x or 0)
self.y = self.y + (brain[self.heading].y or 0)
else
assert(false, 'unknown command')
end
end
end
return function(p)
return {
x = p.x,
y = p.y,
heading = p.heading,
move = move
}
end
A huge amount can be learned from reading other people’s code. This is why we wanted to give exercism users the option of making their solutions public.
Here are some questions to help you reflect on this solution and learn the most from it.
Level up your programming skills with 3,449 exercises across 52 languages, and insightful discussion with our volunteer team of welcoming mentors. Exercism is 100% free forever.
Sign up Learn More
Community comments
Looks good. Now you just need to remove local robot = {} :)