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