How to find a range contained in an array of ranges?

Example

business_hours['monday'] = [800..1200, 1300..1700]
business_hours['tuesday'] = [900..1100, 1300..1700]

...

Then I have a bunch of events that occupy some of these intervals, for example

event = { start_at: somedatetime, end_at: somedatetime }

Iterating over events from a specific date to a specific date, I create another array

busy_hours['monday'] = [800..830, 1400..1415]

...

Now my problems are:

  • Creating an available_hours array that contains business_hours minus busy_hours

available_hours = business_hours - busy_hours

  • Given a specific duration, say 30 minutes, find what time intervals are available in available_hours. In the above examples, such a method returns

available_slots['monday'] = [830..900, 845..915, 900..930, and so on]

Not that he checked available_hours in 15-minute increments for intervals of a given duration.

Thanks for the help!

+3
source share
3

, . , , , . .

:

. 15- ( , ). .

:

  • 0xF = 0x1111 = > .
  • 0xC = 0x1100 = > .

24 . , , . 24 .

, 00:00 23:59 business_hours['monday'] = 0x0000 0000 FFFF 0FFF F000 0000

_, .

:

event_a = 0x0000 0000 00F0 0000 0000 0000 # 10:00 - 11:00 
event_b = 0x0000 0000 0000 07F8 0000 0000 # 13:15 - 15:15

busy_hours = event_a & event_b 

busy_hours business_hours :

available_hours = business_hours (busy_hours ^ 0xFFFF FFFF FFFF FFFF FFFF FFFF)

xor (^) essentialy busy_hours not_busy_hours. Anding (&) not_busy_hours business_hours .

.

all_available_hours = person_a_available_hours & person_b_available_hours & person_c_available_hours

, . - : , , . , 0.

, : 0x1 = > 15 , 0x3 = > , 0x7 = > 45 , 0xF = > ,... 0xFF = > 2 ..

, :

acceptable_times =[]
(0 .. 24 * 4 - (#of time chunks time slot)).each do |i|
  acceptable_times.unshift(time_slot_in_hex) if available_hours & (time_slot_in_hex << i) == time_slot_in_hex << i
end

. . , .

24 * 4 24 , 4 . - (#of time chunks in time slot) 1 15 , . (Math.log(time_slot_in_hex)/Math.log(2)).floor + 1

, , (15 ) . , . , , _ .

, , , , , , .

, (..: [800..1200, 1300..1700]) . - . , , , .. , , - , .

+7

, :

ary = [800..1200, 1300..1700]

test = 800..830
p ary.any? {|rng| rng.include?(test.first) and rng.include?(test.last)}
# => true

test = 1245..1330
p ary.any? {|rng| rng.include?(test.first) and rng.include?(test.last)}
# => false

class Range
  def include_range?(r)
    self.include?(r.first) and self.include?(r.last)
  end
end
+1

, , , . , , ( Range, , ):

class Range
  def contains(range)
    first <= range.first || last >= range.last
  end

  def -(range)
    out = []
    unless range.first <= first && range.last >= last
      out << Range.new(first, range.first) if range.first > first
      out << Range.new(range.last, last) if range.last < last
    end
    out
  end
end

, :

event_range = event.start_time..event.end_time
matching_range = business_hours.find{|r| r.contains(event_range)}    

, (, ):

available_hours = business_hours.dup
available_hours.delete(matching_range)
available_hours += matching_range - event_range

. , - , , :)

+1

Source: https://habr.com/ru/post/1720819/


All Articles