class SeatSelector::Finder

Attributes

seats[R]

Public Class Methods

new(venue) click to toggle source
# File lib/seat_selector/finder.rb, line 5
def initialize(venue)
  @seats = venue.available_seats
  set_distance!(venue.total_columns)
end

Public Instance Methods

get_best_seats(seats_needed = 1) click to toggle source
# File lib/seat_selector/finder.rb, line 10
def get_best_seats(seats_needed = 1)
  return [] if seats_needed < 1
  best_seat = nil
  best_distance = nil
  @seats.each do |r, seats_in_row| # skip rows with no open seats
    # search the current row
    seats_in_row.each do |c, seat|
      if seats_needed == 1
        if best_seat.nil? || best_seat.distance > seat.distance
          best_seat = seat
          best_distance = seat.distance
        end
      else
        # check rightward from current seat
        valid_group = (c + 1).upto(c + seats_needed - 1).all?{|i| seats_in_row.key?(i) }
        if valid_group
          distance = (c).upto(c + seats_needed - 1).inject(0) do |sum, i| 
            sum + seats_in_row[i].distance
          end
          if best_seat.nil? || best_distance > distance
            best_seat = seat
            best_distance = distance
          end
        end
      end
    end      
  end
  
  return [] if best_seat.nil?

  if seats_needed > 1
    seats_needed.times.map {|i| @seats[best_seat.row][best_seat.column + i] }
  else
    [best_seat]
  end
end

Private Instance Methods

median(max) click to toggle source

get median of contiguous integer range 1 to max

# File lib/seat_selector/finder.rb, line 58
def median(max)
  if max.even?
    max / 2
  else
    (max + 1) / 2
  end
end
set_distance!(total_columns) click to toggle source
# File lib/seat_selector/finder.rb, line 49
def set_distance!(total_columns)
  median_column = median(total_columns)

  @seats.each_value do |seats_in_row|
    seats_in_row.each_value {|seat| seat.set_distance!(median_column) }
  end
end