1*cda5da8dSAndroid Build Coastguard Worker"""Bisection algorithms.""" 2*cda5da8dSAndroid Build Coastguard Worker 3*cda5da8dSAndroid Build Coastguard Worker 4*cda5da8dSAndroid Build Coastguard Workerdef insort_right(a, x, lo=0, hi=None, *, key=None): 5*cda5da8dSAndroid Build Coastguard Worker """Insert item x in list a, and keep it sorted assuming a is sorted. 6*cda5da8dSAndroid Build Coastguard Worker 7*cda5da8dSAndroid Build Coastguard Worker If x is already in a, insert it to the right of the rightmost x. 8*cda5da8dSAndroid Build Coastguard Worker 9*cda5da8dSAndroid Build Coastguard Worker Optional args lo (default 0) and hi (default len(a)) bound the 10*cda5da8dSAndroid Build Coastguard Worker slice of a to be searched. 11*cda5da8dSAndroid Build Coastguard Worker """ 12*cda5da8dSAndroid Build Coastguard Worker if key is None: 13*cda5da8dSAndroid Build Coastguard Worker lo = bisect_right(a, x, lo, hi) 14*cda5da8dSAndroid Build Coastguard Worker else: 15*cda5da8dSAndroid Build Coastguard Worker lo = bisect_right(a, key(x), lo, hi, key=key) 16*cda5da8dSAndroid Build Coastguard Worker a.insert(lo, x) 17*cda5da8dSAndroid Build Coastguard Worker 18*cda5da8dSAndroid Build Coastguard Worker 19*cda5da8dSAndroid Build Coastguard Workerdef bisect_right(a, x, lo=0, hi=None, *, key=None): 20*cda5da8dSAndroid Build Coastguard Worker """Return the index where to insert item x in list a, assuming a is sorted. 21*cda5da8dSAndroid Build Coastguard Worker 22*cda5da8dSAndroid Build Coastguard Worker The return value i is such that all e in a[:i] have e <= x, and all e in 23*cda5da8dSAndroid Build Coastguard Worker a[i:] have e > x. So if x already appears in the list, a.insert(i, x) will 24*cda5da8dSAndroid Build Coastguard Worker insert just after the rightmost x already there. 25*cda5da8dSAndroid Build Coastguard Worker 26*cda5da8dSAndroid Build Coastguard Worker Optional args lo (default 0) and hi (default len(a)) bound the 27*cda5da8dSAndroid Build Coastguard Worker slice of a to be searched. 28*cda5da8dSAndroid Build Coastguard Worker """ 29*cda5da8dSAndroid Build Coastguard Worker 30*cda5da8dSAndroid Build Coastguard Worker if lo < 0: 31*cda5da8dSAndroid Build Coastguard Worker raise ValueError('lo must be non-negative') 32*cda5da8dSAndroid Build Coastguard Worker if hi is None: 33*cda5da8dSAndroid Build Coastguard Worker hi = len(a) 34*cda5da8dSAndroid Build Coastguard Worker # Note, the comparison uses "<" to match the 35*cda5da8dSAndroid Build Coastguard Worker # __lt__() logic in list.sort() and in heapq. 36*cda5da8dSAndroid Build Coastguard Worker if key is None: 37*cda5da8dSAndroid Build Coastguard Worker while lo < hi: 38*cda5da8dSAndroid Build Coastguard Worker mid = (lo + hi) // 2 39*cda5da8dSAndroid Build Coastguard Worker if x < a[mid]: 40*cda5da8dSAndroid Build Coastguard Worker hi = mid 41*cda5da8dSAndroid Build Coastguard Worker else: 42*cda5da8dSAndroid Build Coastguard Worker lo = mid + 1 43*cda5da8dSAndroid Build Coastguard Worker else: 44*cda5da8dSAndroid Build Coastguard Worker while lo < hi: 45*cda5da8dSAndroid Build Coastguard Worker mid = (lo + hi) // 2 46*cda5da8dSAndroid Build Coastguard Worker if x < key(a[mid]): 47*cda5da8dSAndroid Build Coastguard Worker hi = mid 48*cda5da8dSAndroid Build Coastguard Worker else: 49*cda5da8dSAndroid Build Coastguard Worker lo = mid + 1 50*cda5da8dSAndroid Build Coastguard Worker return lo 51*cda5da8dSAndroid Build Coastguard Worker 52*cda5da8dSAndroid Build Coastguard Worker 53*cda5da8dSAndroid Build Coastguard Workerdef insort_left(a, x, lo=0, hi=None, *, key=None): 54*cda5da8dSAndroid Build Coastguard Worker """Insert item x in list a, and keep it sorted assuming a is sorted. 55*cda5da8dSAndroid Build Coastguard Worker 56*cda5da8dSAndroid Build Coastguard Worker If x is already in a, insert it to the left of the leftmost x. 57*cda5da8dSAndroid Build Coastguard Worker 58*cda5da8dSAndroid Build Coastguard Worker Optional args lo (default 0) and hi (default len(a)) bound the 59*cda5da8dSAndroid Build Coastguard Worker slice of a to be searched. 60*cda5da8dSAndroid Build Coastguard Worker """ 61*cda5da8dSAndroid Build Coastguard Worker 62*cda5da8dSAndroid Build Coastguard Worker if key is None: 63*cda5da8dSAndroid Build Coastguard Worker lo = bisect_left(a, x, lo, hi) 64*cda5da8dSAndroid Build Coastguard Worker else: 65*cda5da8dSAndroid Build Coastguard Worker lo = bisect_left(a, key(x), lo, hi, key=key) 66*cda5da8dSAndroid Build Coastguard Worker a.insert(lo, x) 67*cda5da8dSAndroid Build Coastguard Worker 68*cda5da8dSAndroid Build Coastguard Workerdef bisect_left(a, x, lo=0, hi=None, *, key=None): 69*cda5da8dSAndroid Build Coastguard Worker """Return the index where to insert item x in list a, assuming a is sorted. 70*cda5da8dSAndroid Build Coastguard Worker 71*cda5da8dSAndroid Build Coastguard Worker The return value i is such that all e in a[:i] have e < x, and all e in 72*cda5da8dSAndroid Build Coastguard Worker a[i:] have e >= x. So if x already appears in the list, a.insert(i, x) will 73*cda5da8dSAndroid Build Coastguard Worker insert just before the leftmost x already there. 74*cda5da8dSAndroid Build Coastguard Worker 75*cda5da8dSAndroid Build Coastguard Worker Optional args lo (default 0) and hi (default len(a)) bound the 76*cda5da8dSAndroid Build Coastguard Worker slice of a to be searched. 77*cda5da8dSAndroid Build Coastguard Worker """ 78*cda5da8dSAndroid Build Coastguard Worker 79*cda5da8dSAndroid Build Coastguard Worker if lo < 0: 80*cda5da8dSAndroid Build Coastguard Worker raise ValueError('lo must be non-negative') 81*cda5da8dSAndroid Build Coastguard Worker if hi is None: 82*cda5da8dSAndroid Build Coastguard Worker hi = len(a) 83*cda5da8dSAndroid Build Coastguard Worker # Note, the comparison uses "<" to match the 84*cda5da8dSAndroid Build Coastguard Worker # __lt__() logic in list.sort() and in heapq. 85*cda5da8dSAndroid Build Coastguard Worker if key is None: 86*cda5da8dSAndroid Build Coastguard Worker while lo < hi: 87*cda5da8dSAndroid Build Coastguard Worker mid = (lo + hi) // 2 88*cda5da8dSAndroid Build Coastguard Worker if a[mid] < x: 89*cda5da8dSAndroid Build Coastguard Worker lo = mid + 1 90*cda5da8dSAndroid Build Coastguard Worker else: 91*cda5da8dSAndroid Build Coastguard Worker hi = mid 92*cda5da8dSAndroid Build Coastguard Worker else: 93*cda5da8dSAndroid Build Coastguard Worker while lo < hi: 94*cda5da8dSAndroid Build Coastguard Worker mid = (lo + hi) // 2 95*cda5da8dSAndroid Build Coastguard Worker if key(a[mid]) < x: 96*cda5da8dSAndroid Build Coastguard Worker lo = mid + 1 97*cda5da8dSAndroid Build Coastguard Worker else: 98*cda5da8dSAndroid Build Coastguard Worker hi = mid 99*cda5da8dSAndroid Build Coastguard Worker return lo 100*cda5da8dSAndroid Build Coastguard Worker 101*cda5da8dSAndroid Build Coastguard Worker 102*cda5da8dSAndroid Build Coastguard Worker# Overwrite above definitions with a fast C implementation 103*cda5da8dSAndroid Build Coastguard Workertry: 104*cda5da8dSAndroid Build Coastguard Worker from _bisect import * 105*cda5da8dSAndroid Build Coastguard Workerexcept ImportError: 106*cda5da8dSAndroid Build Coastguard Worker pass 107*cda5da8dSAndroid Build Coastguard Worker 108*cda5da8dSAndroid Build Coastguard Worker# Create aliases 109*cda5da8dSAndroid Build Coastguard Workerbisect = bisect_right 110*cda5da8dSAndroid Build Coastguard Workerinsort = insort_right 111