Skip to content

Instantly share code, notes, and snippets.

@aashish
Last active August 18, 2020 15:50
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 aashish/591c524dfa33e137006ca5e5a3e83670 to your computer and use it in GitHub Desktop.
Save aashish/591c524dfa33e137006ca5e5a3e83670 to your computer and use it in GitHub Desktop.
Mars Rover Problem with proxy pattern
class Plateau
attr_accessor :max_x, :max_y, :direction
def initialize(x, y, direction = :n)
@max_x = x.to_i
@max_y = y.to_i
@direction = direction.downcase.to_sym
end
end
class Rover
def location
raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'"
end
end
class RealRover < Rover
attr_accessor :location, :directions, :plateau
def initialize
end
end
class ProxyRover < Rover
def initialize(real_rover)
@real_rover = real_rover
end
def check_plateau
puts 'Proxy: Checking if plateau exists'
puts "Location: #{@real_rover.location.inspect}"
puts "Plateau: #{@real_rover.plateau.inspect}"
raise 'Rover is out of region' if !@real_rover.plateau || (@real_rover.plateau && (@real_rover.plateau.max_x < @real_rover.location.x) || (@real_rover.plateau.max_y < @real_rover.location.y))
end
def move_possible?
puts 'Proxy: Checking if move is with in plateau'
end
def location
@real_rover.location
end
def start
check_plateau
@real_rover.directions.each do |d|
move_possible? if d == 'M'
location.send(location.mapper[d.to_sym])
end
end
end
class Location
LEFT = {
n: :w,
e: :n,
s: :e,
w: :s
}
RIGHT = {
n: :e,
e: :s,
s: :w,
w: :n
}
attr_accessor :x, :y, :direction
def initialize(x = 0, y = 0, direction = :n)
@x = x.to_i
@y = y.to_i
@direction = direction.downcase.to_sym
end
def turn_left
@direction = LEFT[@direction]
end
def turn_right
@direction = RIGHT[@direction]
end
def move
case @direction
when :n
@y += 1
when :e
@x += 1
when :s
@y -= 1
when :w
@x -= 1
end
end
def mapper
{
L: 'turn_left',
R: 'turn_right',
M: 'move'
}
end
end
#----- input ----------------
input = gets("\n\n").chomp
input = input.split("\n").reject(&:empty?)
area = input.shift
area = area.split
plateau = Plateau.new(area[0], area[1])
inputs = input.each_slice(2).to_a
rovers = []
inputs.each do |input|
position = input[0].split
directions = input[1].split(//).reject(&:empty?)
real_rover = RealRover.new
real_rover.location = Location.new(position[0], position[1], position[2])
real_rover.directions = directions
real_rover.plateau = plateau
proxy_rover = ProxyRover.new(real_rover)
rovers << proxy_rover
end
rovers.each do |r|
r.start
r = r.location
puts "#{r.x} #{r.y} #{r.direction.to_s}"
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment