Skip to content

Instantly share code, notes, and snippets.

@xavdid
Last active January 4, 2016 08:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xavdid/8593272 to your computer and use it in GitHub Desktop.
Save xavdid/8593272 to your computer and use it in GitHub Desktop.
Mars Rover
=begin
### PROMPT ###
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 line of 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.
OUTPUT:
The output for each rover should be its final co-ordinates and heading.
Sample IO
Test Input:
5 5
1 2 N
LMLMLMLMM
3 3 E
MMRMMRMRRM
Expected Output:
1 3 N
5 1 E
### NOTES ###
To run:
Run `ruby rover.rb` with input.txt in the same directory
Assumptions:
Input file is formatted correctly and is present
The units are measure in kilomters, even if rovers occupy the same grid
space, they won't collide.
Notes:
If the rover drives off the side of the plateau, the program will notify
you so (and report drop location in the interest of salvaging the rover).
This wasn't mentioned in the spec, but it's the only reason I could think
of to keep track of the dimensions of the plateau.
=end
class Rover
def initialize(height, width)
@height = height
@width = width
@x = 0
@y = 0
@cur_dir = 0
@directions = ['N','E','S','W']
end
def act(i)
if i == 'R' or i == 'L'
rotate(i)
else
step
end
end
def step
if @cur_dir == 0
@y += 1
elsif @cur_dir == 1
@x += 1
elsif @cur_dir == 2
@y -= 1
elsif @cur_dir == 3
@x -= 1
end
if @x < 0 or @x > @width or @y < 0 or @y > @height
throw :side_error
end
end
def rotate(d)
# decides which direction to turn and adjusts the int accordingly
c = d == 'L' ? -1 : 1
@cur_dir = (@cur_dir + c) % 4
end
def get_location
return "#{@x} #{@y} #{@directions[@cur_dir]}"
end
def set_location(x, y, d)
@x = x
@y = y
@cur_dir = @directions.index(d)
end
end
# file input
f = open('input.txt')
a = f.first.split(' ')
height = a[0].to_i
width = a[1].to_i
# initialize variables
r = Rover.new(height,width)
instructions = false
good = true
f.each do |line|
# location line
if !instructions
l = line.chomp.split(' ')
r.set_location(l[0].to_i,l[1].to_i,l[2])
# action line
else
l = line.chomp.split("")
l.each do |action|
begin
r.act(action)
rescue Exception => e
puts "Rover fell off at #{r.get_location}!"
good = false
break
end
end
# prints if the rover never fell off
puts r.get_location if good
end
# the next line is the other option
instructions = !instructions
good = true
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment