codon/stdlib/bisect.codon

91 lines
2.5 KiB
Python
Raw Normal View History

2021-09-27 18:02:44 +00:00
def bisect_left(a, x, lo: int = 0, hi: int = -1) -> int:
"""
Return the index where to insert item x in list a, assuming a is sorted.
The return value i is such that all e in a[:i] have e < x, and all e in
a[i:] have e >= x. So if x already appears in the list, a.insert(x) will
insert just before the leftmost x already there.
Optional args lo (default 0) and hi (default len(a)) bound the
slice of a to be searched.
Default values: lo=0, high=None
For now seq will use len(a) instead of None
"""
if lo < 0:
raise ValueError('lo must be non-negative')
if hi == -1:
hi = len(a)
while lo < hi:
mid = (lo + hi) // 2
if a[mid] < x: lo = mid+1
else: hi = mid
return lo
def bisect_right(a, x, lo: int = 0, hi: int = -1) -> int:
"""
Return the index where to insert item x in list a, assuming a is sorted.
The return value i is such that all e in a[:i] have e <= x, and all e in
a[i:] have e > x. So if x already appears in the list, a.insert(x) will
insert just after the rightmost x already there.
Optional args lo (default 0) and hi (default len(a)) bound the
slice of a to be searched.
Default values: lo=0, high=None
For now seq will use len(a) instead of None
"""
# lo = 0
# hi = len(a)
if lo < 0:
raise ValueError('lo must be non-negative')
if hi == -1:
hi = len(a)
while lo < hi:
mid = (lo + hi) // 2
if x < a[mid]: hi = mid
else: lo = mid+1
return lo
def bisect(a, x, lo: int = 0, hi: int = -1) -> int:
"""
bisect = bisect_right
"""
# lo, hi = 0, len(a)
return bisect_right(a, x, lo, hi)
def insort_left(a, x, lo: int = 0, hi: int = -1):
"""
Insert item x in list a, and keep it sorted assuming a is sorted.
If x is already in a, insert it to the left of the leftmost x.
Default values: lo=0, high=None
For now seq will use len(a) instead of None
"""
lo = bisect_left(a, x, lo, hi)
a.insert(lo, x)
def insort_right(a, x, lo: int = 0, hi: int = -1):
"""
Insert item x in list a, and keep it sorted assuming a is sorted.
If x is already in a, insert it to the right of the rightmost x.
Default values: lo=0, high=None
For now seq will use len(a) instead of None
"""
lo = bisect_right(a, x, lo, hi)
if lo == len(a):
a.append(x)
else:
a.insert(lo, x)
def insort(a, x, lo: int = 0, hi: int = -1):
"""
insort = insort_right
"""
insort_right(a, x, lo, hi)