Plex plugin to to play various online streams (mostly Latvian).

intranges.py 1.5KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. """
  2. Given a list of integers, made up of (hopefully) a small number of long runs
  3. of consecutive integers, compute a representation of the form
  4. ((start1, end1), (start2, end2) ...). Then answer the question "was x present
  5. in the original list?" in time O(log(# runs)).
  6. """
  7. import bisect
  8. def intranges_from_list(list_):
  9. """Represent a list of integers as a sequence of ranges:
  10. ((start_0, end_0), (start_1, end_1), ...), such that the original
  11. integers are exactly those x such that start_i <= x < end_i for some i.
  12. """
  13. sorted_list = sorted(list_)
  14. ranges = []
  15. last_write = -1
  16. for i in range(len(sorted_list)):
  17. if i+1 < len(sorted_list):
  18. if sorted_list[i] == sorted_list[i+1]-1:
  19. continue
  20. current_range = sorted_list[last_write+1:i+1]
  21. range_tuple = (current_range[0], current_range[-1] + 1)
  22. ranges.append(range_tuple)
  23. last_write = i
  24. return tuple(ranges)
  25. def intranges_contain(int_, ranges):
  26. """Determine if `int_` falls into one of the ranges in `ranges`."""
  27. tuple_ = (int_, int_)
  28. pos = bisect.bisect_left(ranges, tuple_)
  29. # we could be immediately ahead of a tuple (start, end)
  30. # with start < int_ <= end
  31. if pos > 0:
  32. left, right = ranges[pos-1]
  33. if left <= int_ < right:
  34. return True
  35. # or we could be immediately behind a tuple (int_, end)
  36. if pos < len(ranges):
  37. left, _ = ranges[pos]
  38. if left == int_:
  39. return True
  40. return False