def sorted_rngs_to_iter_nontouch_ranges(sorted_rngs): it = PeekableIterator(sorted_rngs) while not it.is_empty(): (begin, end_) = it.read1() # raise StopIteration while not it.is_empty(): head = it.head assert (begin, end_) <= head (_begin, _end) = head if _begin <= end_: #bug: end_ = _end # merge end_ = max(end_, _end) # merge it.read1() continue break yield (begin, end_) # instead of rng return
def intersection__xtouch_ranges(lhs_xtouch_ranges, rhs_xtouch_ranges): r""" nontouch_ranges -> xtouch_ranges -> nontouch_ranges xtouch_ranges -> nontouch_ranges -> nontouch_ranges touch_ranges -> touch_ranges -> touch_ranges #""" lhs = PeekableIterator(lhs_xtouch_ranges) rhs = PeekableIterator(rhs_xtouch_ranges) while not (lhs.is_empty() or rhs.is_empty()): (begin_, end_) = lhs.head # raise StopIteration (_begin, _end) = rhs.head # raise StopIteration if _end <= begin_: rhs.read1() elif end_ <= _begin: lhs.read1() else: assert _begin < _end assert begin_ < end_ lhs.read1() rhs.read1() assert _begin < end_ assert begin_ < _end begin = max(begin_, _begin) end = min(end_, _end) assert begin < end yield begin, end # intersection #### if end_ < _end: _begin = end_ rhs.append_left((_begin, _end)) elif end_ > _end: begin_ = _end lhs.append_left((begin_, end_)) return
def difference__xtouch_ranges(lhs_xtouch_ranges, rhs_xtouch_ranges): r""" nontouch_ranges -> xtouch_ranges -> nontouch_ranges touch_ranges -> xtouch_ranges -> touch_ranges #""" lhs = PeekableIterator(lhs_xtouch_ranges) rhs = PeekableIterator(rhs_xtouch_ranges) while not lhs.is_empty(): (begin_, end_) = lhs.head # raise StopIteration if rhs.is_empty(): yield from lhs return (_begin, _end) = rhs.head if _end <= begin_: rhs.read1() elif end_ <= _begin: yield lhs.read1() else: assert _begin < _end assert begin_ < end_ lhs.read1() rhs.read1() assert _begin < end_ assert begin_ < _end if begin_ < _begin: yield begin_, _begin #### if end_ < _end: _begin = end_ rhs.append_left((_begin, _end)) elif end_ > _end: begin_ = _end lhs.append_left((begin_, end_)) return
def iter_with_middle_state_of_subset_relation_ex__xtouch_ranges( lhs_xtouch_ranges, rhs_xtouch_ranges, *, lhs_maynot_be_nontouch_ranges: bool, rhs_maynot_be_nontouch_ranges: bool): r""" -> iter regex<int>"[56]?[0123]" maybe middle state (5 | 6): not lhs <= rhs => 6 #faster:rhs_maynot_be_nontouch_ranges==False not lhs >= rhs => 5 #faster:lhs_maynot_be_nontouch_ranges=False final value (0 | 1 | 2 | 3): lhs < rhs => 1 lhs > rhs => 2 lhs == rhs => 3 otherwise => 0 #lhs <= rhs => bool(result & 1) #lhs >= rhs => bool(result & 2) #""" R = PartialOrderingCompareResult F = R.get_mirror_class() lhs = PeekableIterator(lhs_xtouch_ranges) rhs = PeekableIterator(rhs_xtouch_ranges) lhs_maynot_be_nontouch_ranges = bool(lhs_maynot_be_nontouch_ranges) rhs_maynot_be_nontouch_ranges = bool(rhs_maynot_be_nontouch_ranges) largs = (R, F, lhs, rhs, lhs_maynot_be_nontouch_ranges, rhs_maynot_be_nontouch_ranges) rargs = (F, R, rhs, lhs, rhs_maynot_be_nontouch_ranges, lhs_maynot_be_nontouch_ranges) fs = _4_iter_mid_st r = R.EQ saved_r = r while 1: # r =[def]= prev util now, cmp result # r != R.NA assert not R.na(r) if saved_r != r: yield 4 | r saved_r = r if lhs.is_empty(): yield fs.on_lhs_is_empty(largs, r) return if rhs.is_empty(): yield fs.on_lhs_is_empty(rargs, r) return (begin_, end_) = lhs.head (_begin, _end) = rhs.head if _end <= begin_: r = fs.on_rend_le_lbegin(largs, r, _end, begin_) # r may be NA elif end_ <= _begin: r = fs.on_rend_le_lbegin(rargs, r, end_, _begin) # r may be NA else: assert _begin < _end assert begin_ < end_ lhs.read1() rhs.read1() assert _begin < end_ assert begin_ < _end if begin_ < _begin: #not le #bug: r ^= R.LT r &= ~R.LT # r may be NA elif begin_ > _begin: #not ge #bug: r ^= R.GT r &= ~R.GT # r may be NA # r may be NA #### if end_ < _end: _begin = end_ rhs.append_left((_begin, _end)) if not lhs_maynot_be_nontouch_ranges: #lhs_is_nontouch_ranges #not ge #bug: r ^= R.GT r &= ~R.GT # r may be NA elif end_ > _end: begin_ = _end lhs.append_left((begin_, end_)) if not rhs_maynot_be_nontouch_ranges: # rhs_is_nontouch_ranges #not le #bug: r ^= R.LT r &= ~R.LT # r may be NA # r may be NA ###### if R.na(r): yield r return return
def union_ex__xtouch_ranges(lhs_xtouch_ranges, rhs_xtouch_ranges, *, faster_output_iter_touch_ranges: bool): r""" if faster_output_iter_touch_ranges: output touch_ranges instead of xtouch_ranges this touch_ranges is more fragmentary than "not faster_output_iter_touch_ranges" case else: nontouch_ranges -> nontouch_ranges -> nontouch_ranges touch_ranges -> xtouch_ranges -> touch_ranges xtouch_ranges -> touch_ranges -> touch_ranges #""" lhs = PeekableIterator(lhs_xtouch_ranges) rhs = PeekableIterator(rhs_xtouch_ranges) faster_output_iter_touch_ranges = bool(faster_output_iter_touch_ranges) while 1: if lhs.is_empty(): yield from rhs return if rhs.is_empty(): yield from lhs return (begin_, end_) = lhs.head (_begin, _end) = rhs.head if _end < begin_: rhs.read1() yield (_begin, _end) elif end_ < _begin: lhs.read1() yield (begin_, end_) else: assert _begin < _end assert begin_ < end_ lhs.read1() rhs.read1() assert _begin <= end_ assert begin_ <= _end begin = min(begin_, _begin) end = max(end_, _end) assert begin < end #### rng = (begin, end) if faster_output_iter_touch_ranges: #bug: yield rng; continue #fixed: skip-until-end yield rng #skip-until-end if end_ < _end: _skip_util(lhs, end) elif end_ > _end: _skip_util(rhs, end) else: if end_ < _end: rhs.append_left(rng) elif end_ > _end: lhs.append_left(rng) else: yield rng return
def symmetric_difference_ex__xtouch_ranges( lhs_xtouch_ranges, rhs_xtouch_ranges, *, faster_output_iter_touch_ranges: bool): r""" if faster_output_iter_touch_ranges: output touch_ranges instead of xtouch_ranges this touch_ranges is more fragmentary than "not faster_output_iter_touch_ranges" case else: nontouch_ranges -> nontouch_ranges -> nontouch_ranges touch_ranges -> xtouch_ranges -> touch_ranges xtouch_ranges -> touch_ranges -> touch_ranges #""" lhs = PeekableIterator(lhs_xtouch_ranges) rhs = PeekableIterator(rhs_xtouch_ranges) faster_output_iter_touch_ranges = bool(faster_output_iter_touch_ranges) while 1: if lhs.is_empty(): yield from rhs return if rhs.is_empty(): yield from lhs return (begin_, end_) = lhs.head (_begin, _end) = rhs.head if _end <= begin_: rhs.read1() if _end == begin_ and not faster_output_iter_touch_ranges: begin_ = _begin # merge lhs.read1() lhs.append_left((begin_, end_)) else: yield (_begin, _end) elif end_ <= _begin: lhs.read1() if end_ == _begin and not faster_output_iter_touch_ranges: _begin = begin_ # merge rhs.read1() rhs.append_left((_begin, _end)) else: yield (begin_, end_) else: assert _begin < _end assert begin_ < end_ lhs.read1() rhs.read1() assert _begin < end_ assert begin_ < _end if begin_ < _begin: yield begin_, _begin elif begin_ > _begin: yield _begin, begin_ #### if end_ < _end: _begin = end_ rhs.append_left((_begin, _end)) elif end_ > _end: begin_ = _end lhs.append_left((begin_, end_)) return
def subset_cmp_ex__xtouch_ranges(lhs_xtouch_ranges, rhs_xtouch_ranges, *, rhs_maynot_be_nontouch_ranges: bool): r""" -> (-1 | 0 | +1) rel = is_proper_subset | is_eq_set | not_subset lhs `rel` rhs #""" R = PartialOrderingCompareResult st_or_r = subset_relation_ex__xtouch_ranges( lhs_xtouch_ranges, rhs_xtouch_ranges ##### , rhs_maynot_be_nontouch_ranges=rhs_maynot_be_nontouch_ranges, faster_return_not_le=True ##### , lhs_maynot_be_nontouch_ranges=True, faster_return_not_ge=False) if st_or_r == R.LT: return -1 elif st_or_r == R.EQ: return 0 elif st_or_r in [R.get_FASTER_NOT_LE(), R.NA, R.GT]: return +1 else: raise logic - error ############# old impl ########## lhs = PeekableIterator(lhs_xtouch_ranges) rhs = PeekableIterator(rhs_xtouch_ranges) #lhs_maynot_be_nontouch_ranges = bool(lhs_maynot_be_nontouch_ranges) rhs_maynot_be_nontouch_ranges = bool(rhs_maynot_be_nontouch_ranges) is_eq = True while 1: if lhs.is_empty(): return 0 if is_eq and rhs.is_empty() else -1 if rhs.is_empty(): return +1 (begin_, end_) = lhs.head (_begin, _end) = rhs.head if _end <= begin_: if not rhs_maynot_be_nontouch_ranges: # rhs_is_nontouch_ranges if _end == begin_: return +1 rhs.read1() is_eq = False elif end_ <= _begin: return +1 lhs.read1() else: assert _begin < _end assert begin_ < end_ lhs.read1() rhs.read1() assert _begin < end_ assert begin_ < _end if begin_ < _begin: return +1 elif begin_ > _begin: is_eq = False #### if end_ < _end: _begin = end_ rhs.append_left((_begin, _end)) elif end_ > _end: if not rhs_maynot_be_nontouch_ranges: # rhs_is_nontouch_ranges return +1 begin_ = _end lhs.append_left((begin_, end_)) return