Sha256: d7ea0dda41f9451eadcd2e6a33665af460016a3cb0200bbd5524ca612d1acae7

Contents?: true

Size: 1.67 KB

Versions: 33

Compression:

Stored size: 1.67 KB

Contents

class Range

  #
  # The actual last value in the range (eg: `(1...10).actual_last == 9`)
  #
  def actual_last
    exclude_end? ? last - 1 : last
  end

  #
  # Pick a random number from the range.
  #
  def rand
    Kernel.rand(self)
  end

  #
  # The number in the middle of this range.
  #
  def mid
    (min + max) / 2
  end
  alias_method :middle, :mid

  #
  # Return a new range which is the intersection of the two ranges
  #
  def &(other)
    mins, maxes = minmax.zip(other.minmax)

    (mins.max..maxes.min)
  end

  #
  # Return a new range which is the union of the two ranges (even if the two ranges don't overlap)
  #
  def |(other)
    vals = [
      first,
      other.first,
      actual_last,
      other.actual_last
    ].sort

    (vals.first..vals.last)
  end

  #
  # Merge this range with another (if the two ranges overlap, then it returns an array containing a single merged range; if the two ranges are disjoint, an array with the two ranges is returned)
  #
  def merge(other)
    if self.overlaps?(other)
      [self | other]
    else
      [self, other]
    end
  end

  #
  # Test if this range overlaps the other
  #
  def overlaps?(other)
    # overlap == start < finish' AND start' < finish
    self.first <= other.actual_last and other.first <= self.actual_last
  end

  #
  # Takes an array of ranges, and returns a new array where all overlapping ranges are combined into a single range
  #
  def self.optimize(ranges)
    ranges = ranges.sort_by(&:first)

    result = [ranges.first]

    ranges[1..-1].each do |elem|
      if result[-1].overlaps?(elem)
        result[-1] = (result[-1] | elem)
      else
        result << elem
      end
    end

    result
  end

end

Version data entries

33 entries across 33 versions & 1 rubygems

Version Path
epitools-0.5.136 lib/epitools/core_ext/range.rb
epitools-0.5.134 lib/epitools/core_ext/range.rb
epitools-0.5.133 lib/epitools/core_ext/range.rb
epitools-0.5.131 lib/epitools/core_ext/range.rb
epitools-0.5.130 lib/epitools/core_ext/range.rb
epitools-0.5.129 lib/epitools/core_ext/range.rb
epitools-0.5.128 lib/epitools/core_ext/range.rb
epitools-0.5.126 lib/epitools/core_ext/range.rb
epitools-0.5.125 lib/epitools/core_ext/range.rb
epitools-0.5.124 lib/epitools/core_ext/range.rb
epitools-0.5.123 lib/epitools/core_ext/range.rb
epitools-0.5.122 lib/epitools/core_ext/range.rb
epitools-0.5.121 lib/epitools/core_ext/range.rb
epitools-0.5.119 lib/epitools/core_ext/range.rb
epitools-0.5.118 lib/epitools/core_ext/range.rb
epitools-0.5.116 lib/epitools/core_ext/range.rb
epitools-0.5.115 lib/epitools/core_ext/range.rb
epitools-0.5.114 lib/epitools/core_ext/range.rb
epitools-0.5.113 lib/epitools/core_ext/range.rb
epitools-0.5.112 lib/epitools/core_ext/range.rb