Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save aashish/739ccc7100af55dc81d61f668dc9d7eb to your computer and use it in GitHub Desktop.
Save aashish/739ccc7100af55dc81d61f668dc9d7eb to your computer and use it in GitHub Desktop.
Mars Rover Problem with Flyweight 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
def land(position)
puts 'Rover landed'
end
end
class Rover
attr_accessor :name, :location, :directions, :plateau
def initialize(name)
@name = name
end
def start
check_plateau
directions.each do |d|
move_possible? if d == 'M'
location.send(location.mapper[d.to_sym])
end
end
def check_plateau
puts 'Checking if plateau exists'
puts "Location: #{location.inspect}"
puts "Plateau: #{plateau.inspect}"
raise 'Rover is out of region' if !plateau || (plateau && (plateau.max_x < location.x) || (plateau.max_y < location.y))
end
def move_possible?
puts 'Checking if move is with in plateau'
end
end
class RoverFactory
attr_accessor :rovers
def initialize
@rovers = {}
end
def find_rover(name)
if [email protected]_key?(name)
@rovers[name] = Rover.new(name)
end
@rovers[name]
end
def total_number_of_rovers
@rovers.size
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
class Operation
def initialize
@rover_factory = RoverFactory.new
end
def deploy(plateau, name, input)
position = input[0].split
directions = input[1].split(//).reject(&:empty?)
rover = @rover_factory.find_rover(name)
rover.location = Location.new(position[0], position[1], position[2])
rover.directions = directions
rover.plateau = plateau
rover.start
end
def execute
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
inputs.each_with_index { |input, index| deploy(plateau, "Rover #{index}", input) }
end
def status
@rover_factory.rovers.each do |key, value|
puts "#{value.name}, location: #{value.location.inspect}"
end
end
end
opt = Operation.new
opt.execute
opt.status
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment