class Map::Tube::Graph

Attributes

lines[RW]
stations[RW]

Public Class Methods

new() click to toggle source
# File lib/map/tube/graph.rb, line 6
def initialize
  @stations = []
  @lines = []
end

Public Instance Methods

add_line(line) click to toggle source
# File lib/map/tube/graph.rb, line 15
def add_line(line)
  @lines << line
end
add_station(station) click to toggle source
# File lib/map/tube/graph.rb, line 11
def add_station(station)
  @stations << station
end
get_line_by_id(line_id) click to toggle source
# File lib/map/tube/graph.rb, line 33
def get_line_by_id(line_id)
  find_by(:line, :id, line_id)
end
get_line_by_name(line_name) click to toggle source
# File lib/map/tube/graph.rb, line 37
def get_line_by_name(line_name)
  find_by(:line, :name, line_name)
end
get_shortest_route(from_station_name, to_station_name) click to toggle source
# File lib/map/tube/graph.rb, line 19
def get_shortest_route(from_station_name, to_station_name)
  from_station = get_station_by_name(from_station_name)
  to_station = get_station_by_name(to_station_name)
  compute_shortest_path(from_station, to_station)
end
get_station_by_id(station_id) click to toggle source
# File lib/map/tube/graph.rb, line 25
def get_station_by_id(station_id)
  find_by(:station, :id, station_id)
end
get_station_by_name(station_name) click to toggle source
# File lib/map/tube/graph.rb, line 29
def get_station_by_name(station_name)
  find_by(:station, :name, station_name)
end
graphviz() click to toggle source
# File lib/map/tube/graph.rb, line 53
def graphviz
  Graphviz.new(self)
end
to_h() click to toggle source
# File lib/map/tube/graph.rb, line 41
def to_h
  {}.tap do |hash|
    @stations.each do |station|
      hash[station.name] = []
      station.links.each do |link|
        curr_link = self.get_station_by_id(link)
        hash[station.name] << curr_link.name unless curr_link.name == station.name
      end
    end
  end
end

Private Instance Methods

compute_shortest_path(from_station, to_station) click to toggle source
# File lib/map/tube/graph.rb, line 67
def compute_shortest_path(from_station, to_station)
  raise_error_for_model(:route) if from_station.id == to_station.id

  route = Route.new(from_station, to_station)
  visited, queue = [], []
  edge = {}

  queue << from_station
  visited << from_station

  while queue.any?
    curr_station = queue.shift
    break if curr_station.id == to_station.id

    curr_station.links.each do |link|
      next_station = get_station_by_id(link)
      next if visited.include?(next_station)
      queue << next_station
      visited << next_station
      edge[link] = curr_station
    end
  end

  loop do
    to_station = edge[to_station.id]
    break if to_station.id == from_station.id
    route.intermediate_stations.unshift(to_station)
  end

  route
end
find_by(model, attribute, value) click to toggle source
# File lib/map/tube/graph.rb, line 59
def find_by(model, attribute, value)
  get_instance_for_model(model).each do |obj|
    return obj if obj.send(attribute) == value
  end

  raise_error_for_model(model, attribute, value)
end
get_instance_for_model(model) click to toggle source
# File lib/map/tube/graph.rb, line 99
def get_instance_for_model(model)
  {
    :station => @stations,
    :line => @lines
  }[model]
end
raise_error_for_model(model, attribute=nil, value=nil) click to toggle source
# File lib/map/tube/graph.rb, line 106
def raise_error_for_model(model, attribute=nil, value=nil)
  case model
  when :station
    raise(Map::Tube::Exceptions::StationException, "Station with #{attribute}='#{value}' does not exist")
  when :line
    raise(Map::Tube::Exceptions::LineException, "Line with #{attribute}='#{value}' does not exist")
  when :route
    raise(Map::Tube::Exceptions::RouteException, "Stations must be different")
  end
end