diff options
author | Charlie Barto <charlie@westquad-148080.reshall.umich.edu> | 2014-03-23 18:28:05 -0400 |
---|---|---|
committer | Charlie Barto <charlie@westquad-148080.reshall.umich.edu> | 2014-03-23 18:28:05 -0400 |
commit | baa304f37013b6be642aa6c9ae20990b6c489573 (patch) | |
tree | 6c144fa7ee77b618e96d305172d14a8700c4b44d | |
parent | d310b01db1c6f2c8e63a561c40352b17978e1bdb (diff) | |
download | Nim-baa304f37013b6be642aa6c9ae20990b6c489573.tar.gz |
added lowerBound function to algorithm library
-rw-r--r-- | lib/pure/algorithm.nim | 24 | ||||
-rw-r--r-- | tests/stdlib/talgorithm.nim | 3 |
2 files changed, 27 insertions, 0 deletions
diff --git a/lib/pure/algorithm.nim b/lib/pure/algorithm.nim index 921c659de..b6a97b5da 100644 --- a/lib/pure/algorithm.nim +++ b/lib/pure/algorithm.nim @@ -55,6 +55,30 @@ proc smartBinarySearch*[T](a: openArray[T], key: T): int = const onlySafeCode = true +proc lowerBound*[T](a: openarray[T], key: T, cmp: proc(x,y: T): int {.closure.}): int = + ## same as binarySearch except that if key is not in `a` then this + ## returns the location where `key` would be if it were. In other + ## words if you have a sorted sequence and you call insert(thing, elm, lowerBound(thing, elm)) + ## the sequence will still be sorted + ## + ## `cmp` is the comparator function to use, the expected return values are the same as + ## that of system.cmp + result = a.low + var pos = result + var count, step: int + count = a.high - a.low + 1 + while count != 0: + pos = result + step = count div 2 + pos += step + if cmp(a[pos], key) < 0: + pos.inc + result = pos + count -= step + 1 + else: + count = step + +proc lowerBound*[T](a: openarray[T], key: T): int = lowerBound(a, key, system.cmp[T]) proc merge[T](a, b: var openArray[T], lo, m, hi: int, cmp: proc (x, y: T): int {.closure.}, order: TSortOrder) = template `<-` (a, b: expr) = diff --git a/tests/stdlib/talgorithm.nim b/tests/stdlib/talgorithm.nim index 7ab652c82..3ca425fbc 100644 --- a/tests/stdlib/talgorithm.nim +++ b/tests/stdlib/talgorithm.nim @@ -6,3 +6,6 @@ doAssert product(@[@[1,2]]) == @[@[1,2]], "a simple case of one element" doAssert product(@[@[1,2], @[3,4]]) == @[@[2,4],@[1,4],@[2,3],@[1,3]], "two elements" doAssert product(@[@[1,2], @[3,4], @[5,6]]) == @[@[2,4,6],@[1,4,6],@[2,3,6],@[1,3,6], @[2,4,5],@[1,4,5],@[2,3,5],@[1,3,5]], "three elements" doAssert product(@[@[1,2], @[]]) == newSeq[seq[int]](), "two elements, but one empty" +doAssert lowerBound([1,2,4], 3, system.cmp[int]) == 2 +doAssert lowerBound([1,2,2,3], 4, system.cmp[int]) == 4 +doAssert lowerBound([1,2,3,10], 11) == 4 \ No newline at end of file |