Skip to content

Instantly share code, notes, and snippets.

@adityashedge
Created January 20, 2017 10:14
Show Gist options
  • Save adityashedge/931a1148a2fe12da5a646a279d7ad611 to your computer and use it in GitHub Desktop.
Save adityashedge/931a1148a2fe12da5a646a279d7ad611 to your computer and use it in GitHub Desktop.
Mars rover πŸš€ problem
DIRECTIONS = ['N', 'E', 'S', 'W']
CONTROLS = ['L', 'R', 'M']
MOVES = {
'N' => {'L' => 'W', 'R' => 'E'},
'E' => {'L' => 'N', 'R' => 'S'},
'S' => {'L' => 'E', 'R' => 'W'},
'W' => {'L' => 'S', 'R' => 'N'}
}
class GridError < StandardError; end
class RoverError < StandardError; end
class Grid
attr_reader :pos_x, :pos_y
def initialize(pos_x, pos_y)
@pos_x = pos_x
@pos_y = pos_y
end
def valid?
pos_x > 0 && pos_y > 0
end
def valid!
raise GridError, "Grid is invalid" unless valid?
end
end
class Rover
attr_reader :grid, :start_position
attr_accessor :pos_x, :pos_y, :direction, :controls
def initialize(grid)
@grid = grid
end
def move!
for control in controls do
if control == 'M'
puts "Cannot move #{control} ahead." and next unless can_move?
move
else
turn(control)
end
end
end
def land!(pos_x, pos_y, direction)
unless pos_x > 0 && pos_x < grid.pos_x && pos_y > 0 && pos_y < grid.pos_y && DIRECTIONS.include?(direction)
raise("RoverError", "Landed out of the grid!")
end
self.start_position = [pos_x, pos_y, direction]
end
private
def start_position=(position)
@start_position = position
@pos_x, @pos_y, @direction = position
end
def can_move?
case direction
when 'N'
(pos_y + 1) < grid.pos_y
when 'E'
(pos_x + 1) < grid.pos_x
when 'S'
(pos_y - 1) >= 0
when 'W'
(pos_x - 1) >= 0
else
false
end
end
def move
case direction
when 'N'
@pos_y += 1
when 'E'
@pos_x += 1
when 'S'
@pos_y -= 1
when 'W'
@pos_x -= 1
end
end
def turn(control)
@direction = MOVES[direction][control]
end
end
begin
puts "Enter the co-ordinates of grid: "
co_ords = gets.chomp.split.map(&:to_i)
grid = Grid.new(*co_ords)
grid.valid!
rescue StandardError
puts "Grid is is invalid."
retry
end
while true do
rover = Rover.new(grid)
begin
puts "Enter the landing position of the rover"
postion = gets.chomp.split
pos_x = postion[0].to_i
pos_y = postion[1].to_i
direction = postion[2]
rover.land!(pos_x, pos_y, direction)
rescue StandardError => e
puts "Invalid landing position."
retry
end
puts "Enter the controls to move the rover (invalid controls will be rejected): "
rover.controls = gets.chomp.each_char.select{|ch| CONTROLS.include?(ch.upcase)}.map(&:upcase)
rover.move!
puts "Rover reached #{rover.pos_x} #{rover.pos_y} #{rover.direction}."
puts "Do you want to send another rover? (y to continue, press any other key to exit)"
break unless gets.chomp == "y"
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment