def find_ge(v, data, start, stop): """Return the index of the first value within sorted data[start:stop] that is greater than or equal to v. If no such value exists, return stop. """ debug(v,data,start,stop) # debugging trace # Initial version: sequential search for k in range(start,stop): if data[k] >= v: return k return stop # ------------------------------------------ def debug(v,data,start,stop): if len(data) < 20: print ('find_ge(%d, data, %d, %d) called' % (v,start,stop)) print ('data: ' + str(data)) print # ------------------------------------------ import sys import random import time random.seed(0) def test(N): offset = N data = [offset+random.randrange(N) for _ in range(N)] data.sort() j = 0 answers = [] for k in range(N+2): while j < len(data) and data[j] < offset+k-1: j += 1 answers.append(j) timeOnTask = 0 for k in range(N+2): key = offset+k-1 start = time.time() temp = find_ge(key, data, 0, len(data)) timeOnTask += (time.time() - start) if temp != answers[k]: print 'Failed in search for %d' % key print 'You returned %d' % temp small = max(0,temp-4) large = min(temp+4,len(data)) print "data before index %d:"%temp, print "..., " + ', '.join(str(s) for s in data[small:temp]) print "data at index %d: "%temp, print ', '.join(str(s) for s in data[temp:large])+", ..." return print 'N=%7d: Success!!! (time: %3.8f)' % (N,timeOnTask) for N in [10, 100, 1000, 10000, 100000, 1000000]: test(N)