Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- > store = IntervalStore.new
- []
- > store.add(1, 2)
- [[1, 2]]
- > store.add(5, 6)
- [[1, 2], [5, 6]]
- > store.add(1, 4)
- [[1, 4], [5, 6]]
- > store.add(1, 2)
- [[1, 4], [5, 6]]
- > store.add(3, 5)
- [[1, 6]]
- > store.add(0, 7)
- [[0, 7]]
- class IntervalStore(object):
- def __init__(self):
- self.store = []
- def filter_result(self, flatten_store, low_index, upp_index):
- useless_values = filter(lambda value: low_index < flatten_store.index(value) < upp_index, flatten_store)
- flatten_store = filter(lambda value: value not in useless_values, flatten_store)
- self.store = []
- for i, k in zip(flatten_store[0::2], flatten_store[1::2]):
- self.store.append([i, k])
- def add(self, low, upp):
- flatten_store = [number for pair in self.store for number in pair]
- low_index, upp_index = self.index_of(low, flatten_store), self.index_of(upp, flatten_store)
- if low_index >= 0 and upp_index >= 0:
- if low_index % 2 != 0:
- low_index -= 1
- if upp_index % 2 == 0:
- upp_index += 1
- elif low_index >= 0 > upp_index:
- if low_index % 2 != 0:
- low_index -= 1
- flatten_store.append(upp)
- flatten_store = sorted(flatten_store)
- upp_index = self.index_of(upp, flatten_store)
- if upp_index % 2 != 0:
- upp_index += 1
- elif low_index < 0 <= upp_index:
- if upp_index % 2 == 0:
- upp_index += 1
- flatten_store.append(low)
- flatten_store = sorted(flatten_store)
- low_index = self.index_of(low, flatten_store)
- if low_index % 2 != 0:
- low_index -= 1
- upp_index += 1
- else:
- flatten_store.append(low)
- flatten_store.append(upp)
- flatten_store = sorted(flatten_store)
- low_index, upp_index = self.index_of(low, flatten_store), self.index_of(upp, flatten_store)
- if low_index % 2 != 0:
- low_index -= 1
- if upp_index % 2 == 0:
- upp_index += 1
- self.filter_result(flatten_store, low_index, upp_index)
- def index_of(self, value, list):
- try:
- return list.index(value)
- except ValueError:
- return -1
- class IntervalStore
- def initialize
- @store = []
- end
- def to_s
- "[#{@store.map{ |i| "[#{i.first}, #{i.last}]" }.join(', ')}]"
- end
- # TODO - implement this method
- def add(low, upp)
- flatten_store = @store.flatten
- low_index, upp_index = flatten_store.index(low), flatten_store.index(upp)
- if low_index and upp_index
- low_index -=1 if low_index.odd?
- upp_index +=1 if upp_index.even?
- elsif low_index and !upp_index
- low_index -= 1 if low_index.odd?
- (flatten_store << upp).sort!
- upp_index = flatten_store.index(upp)
- upp_index += 1 if upp_index.odd?
- elsif !low_index and upp_index
- upp_index += 1 if upp_index.even?
- (flatten_store << low).sort!
- low_index = flatten_store.index(low)
- low_index -= 1 if low_index.odd?
- upp_index += 1
- else
- (flatten_store << low << upp).sort!
- low_index, upp_index = flatten_store.index(low), flatten_store.index(upp)
- low_index -= 1 if low_index.odd?
- upp_index += 1 if upp_index.even?
- end
- filter_result = filter_store(flatten_store, low_index, upp_index)
- format_result(filter_result)
- end
- def format_result(rest)
- @store = []
- rest.each_slice(2) { |pair_values| @store << pair_values }
- @store
- end
- def filter_store(flatten_store, low_index, upp_index)
- flatten_store.clone.delete_if do |value|
- flatten_store_index = flatten_store.index(value)
- low_index < flatten_store_index and flatten_store_index < upp_index
- end
- end
- end
- def format_result(rest)
- @store = rest.each_slice(2).to_a
- end
- def filter_store(flatten_store, low_index, upp_index)
- flatten_store[0..low_index] + flatten_store[high_index..-1]
- end
- b < c - undershoot
- a < c, b >= c, b <= d - left overlap
- a <= c, b >= d - total overlap
- a >= c, b <= d - subsection
- a > c, b > d - right overlap
- a > d - overshoot
- class IntervalStore(object):
- def __init__(self):
- self.range_list = []
- def __str__(self):
- return str(self.range_list)
- def __repr__(self):
- return str(self)
- def add(self, low, high):
- for interval in self.range_list:
- if interval[0] <= low and interval[1] >= high:
- return
- if interval[0] > high or interval[1] < low:
- continue
- else:
- self.range_list.remove(interval)
- self.add(min([interval[0], low]), max([interval[1], high]))
- return
- if len(self.range_list) == 0:
- self.range_list.append( [low, high])
- else:
- insert_index = 0
- while insert_index < len(self.range_list) and high > self.range_list[insert_index][0]:
- insert_index += 1
- self.range_list.insert(insert_index, [low, high])
- class Interval < Range
- # Check if another interval overlaps this one
- def overlap?(other)
- cover?(other.min) || cover?(other.max)
- end
- # Return a new Interval by merging this one with another
- def merge(other)
- Interval.new([min, other.min].min, [max, other.max].max)
- end
- # Simplified array representation
- def to_a
- [min, max]
- end
- end
- class IntervalStore
- def initialize
- @intervals = []
- end
- def add(min, max)
- @intervals.push(Interval.new(min, max))
- @intervals.sort_by!(&:min)
- @intervals = @intervals.inject([]) do |merged, interval|
- if merged.any? && merged.last.overlap?(interval)
- merged << merged.pop.merge(interval)
- else
- merged << interval
- end
- end
- end
- # Returns an array representation
- def to_a
- @intervals.map(&:to_a)
- end
- end
- class IntervalStore < Array
- def initialize
- super
- end
- def add(low, high)
- push([low, high])
- sort_by!(&:first)
- collapse
- end
- private
- def collapse
- collapsed = inject([]) do |merged, interval|
- can_merge = merged.any? && overlap?(merged.last, interval)
- merged << (can_merge ? merge(merged.pop, interval) : interval)
- end
- clear.concat(collapsed)
- end
- def overlap?(a, b)
- a = Range.new(*a) # just for the `cover?` method
- a.cover?(b.first) || a.cover?(b.last)
- end
- def merge(a, b)
- [ [a.first, b.first].min , [a.last, b.last].max ]
- end
- end
- store = IntervalStore.new # => []
- store.add(1, 2) # => [[1, 2]]
- store.add(5, 6) # => [[1, 2], [5, 6]]
- store.add(1, 4) # => [[1, 4], [5, 6]]
- store.add(1, 2) # => [[1, 4], [5, 6]]
- store.add(3, 5) # => [[1, 6]]
- store.add(0, 7) # => [[0, 7]]
- class Interval
- attr_reader :left, :right
- def initialize(left,right)
- @left = left
- @right = right
- end
- # Is self entirely to the left of other?
- def < (other)
- self.right < other.left
- end
- # Is self entirely to the right of other?
- def > (other)
- self.left > other.right
- end
- # Return the lessor of the left end of self and the left end of other
- def left_most(other)
- [self.left, other.left].min
- end
- # Return the greater of the right end of self and the right end of other
- def right_most(other)
- [self.right, other.right].max
- end
- # How intervals are to be displayed
- def inspect
- "#{self.left}..#{self.right}"
- end
- end
- class IntervalStore
- attr_reader :intervals
- def initialize
- # Array to hold Interval objects
- @intervals = []
- end
- def add(left, right)
- # Create an Interval object
- interval_to_add = Interval.new(left,right)
- if @intervals.empty?
- @intervals = [interval_to_add]
- return
- end
- # intervals in @intervals entirely to the left of interval_to_add
- before = @intervals.find_all {|i| i < interval_to_add }
- # intervals in @intervals entirely to the right of interval_to_add
- after = @intervals.find_all {|i| i > interval_to_add }
- # We will replace all intervals between the before and after
- # intervals (if any) with an interval new_interval
- if (before.size==@intervals.size || after.size==@intervals.size)
- # Case where all intervals are to the left of interval_to_add or to the
- # right of interval_to_add
- new_interval = interval_to_add
- else
- # before.size is the offset of the left-most interval in @intervals
- # that is not in before
- # @intervals.size-after.size-1 is the offset of the right-most
- # interval in @intervals that is not in after
- new_interval = Interval.new(interval_to_add.left_most(@intervals[before.size]),
- interval_to_add.right_most(@intervals[@intervals.size-after.size-1]))
- end
- @intervals = before + [new_interval] + after
- end
- end
- is = IntervalStore.new
- is.add(2 , 5) #=> [2..5]
- is.add(6 , 8) #=> [2..5, 6..8]
- is.add(8 ,10) #=> [2..5, 6..10]
- is.add(0 , 1) #=> [0..1, 2..5, 6..10]
- is.add(1 , 7) #=> [0..10]
- is.add(0 , 1) #=> [0..10]
- is.add(1 ,11) #=> [0..11]
- is.add(-1,10) #=> [-1..11]
- is.add(-2,12) #=> [-2..12]
- Public Class Interval
- Private lower As Integer ' LEFT
- Private upper As Integer ' RIGHT
- Public Sub New(_lower As Integer, _upper As Integer)
- lower = _lower
- upper = _upper
- End Sub
- Public Function lessthan(other As Interval) As Boolean
- If (upper < other.lower) Then Return True
- Return False
- End Function
- Public Function morethan(other As Interval) As Boolean
- If (lower > other.upper) Then Return True
- Return False
- End Function
- Public Function leftmost(other As Interval) As Integer
- Return Math.Min(lower, other.lower)
- End Function
- Public Function rightmost(other As Interval) As Integer
- Return Math.Max(upper, other.upper)
- End Function
- Public Function inspect() As String
- If (lower = upper) Then Return lower.ToString Else Return lower.ToString & ".." & upper.ToString
- End Function
- End Class
- Public Class IntervalStore
- Private intervals As List(Of Interval)
- Public Sub New()
- intervals = New List(Of Interval)
- End Sub
- Public Sub addInterval(lower As Integer, upper As Integer)
- Dim interval_to_add As Interval
- interval_to_add = New Interval(lower, upper)
- If (intervals Is Nothing) Then
- intervals.Add(interval_to_add)
- Return
- End If
- Dim after As List(Of Interval) = intervals.FindAll(Function(i) interval_to_add.lessthan(i))
- Dim before As List(Of Interval) = intervals.FindAll(Function(i) interval_to_add.morethan(i))
- Dim new_interval As Interval
- If ((before.Count = intervals.Count) Or (after.Count = intervals.Count)) Then
- new_interval = interval_to_add
- Else
- new_interval = New Interval(interval_to_add.leftmost(intervals(before.Count)), interval_to_add.rightmost(intervals((intervals.Count - after.Count) - 1)))
- End If
- intervals = before
- intervals.Add(new_interval)
- intervals.AddRange(after)
- End Sub
- Public Function returnValues() As String
- Dim sReturn As String = vbNullString
- For Each int As Interval In intervals
- sReturn = sReturn & (int.inspect) & ","
- Next
- If (sReturn IsNot Nothing) Then Return sReturn.Trim(","c).Replace(",", ", ") Else Return Nothing
- End Function
- End Class
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement