Last active
August 18, 2020 15:50
-
-
Save aashish/591c524dfa33e137006ca5e5a3e83670 to your computer and use it in GitHub Desktop.
Mars Rover Problem with proxy pattern
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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