// This code is in C++11
 
#include <iostream>
#include <algorithm>
#include <functional>
#include <memory>
#include <climits>
#include <iterator>
 
using namespace std;
 
// :), generic functor
template <typename ArgType, typename ResultType>
struct PredUniqueElements : public std::unary_function<ArgType, ResultType> {
 
public:
    PredUniqueElements(ArgType ref) : prev(ref) {}
 
   ResultType operator() (ArgType curr) {
      ArgType old = prev;
      prev = curr;
      return curr != old;
   }
 
private:
    ArgType prev;
};
 
int GenerateDataSet(int A[], int size) {
    for(int i = 0; i < size; i++)
        A[i] = rand()%size;
 
    sort(A, A+size);
 
    // predicate funtor definition
    PredUniqueElements<int, bool> pred(INT_MIN);
 
    // Retain only unique elements
    auto it = copy_if (A, A+size, A, pred);
    return distance(A, it);
}
 
// Returns location of key, or -1 if not found
int BinarySearchSimple(int A[], int l, int r, int key, int &count)
{
    int m;
 
    while( l <= r )
    {
        m = l + (r-l)/2;
 
        count++;
        if( A[m] == key ) // first comparison
            return m;
 
        count++;
        if( A[m] < key ) // second comparison
            l = m + 1;
        else
            r = m - 1;
    }
 
    return -1;
}
 
int BinarySearch(int A[], int l, int r, int key, int &count)
{
    int m;
 
    while( r - l > 1 )
    {
        m = l + (r-l)/2;
 
        count++;
        if( A[m] <= key )
            l = m;
        else
            r = m;
    }
 
    count++;
    if( A[l] == key )
        return l;
    else
        return -1;
}
 
void TestCase_01() {
    int size = 2048;
    auto_ptr<int> buf(new int[size]);
    int *A = buf.get();
 
    size = GenerateDataSet(A, size);
 
    copy(A, A+size, ostream_iterator<int>(cout, " ")), cout << endl;
 
    int key = 193;
    int count;
 
    // We are only interested in comparison count
    count = 0;
    BinarySearchSimple(A, 0, size-1, key, count);
    cout << "BinarySearchSimple " << count << endl;
 
    count = 0;
    BinarySearch(A, 0, size-1, key, count);
    cout << "BinarySearch " << count << endl;
}
 
int main() {
    srand(unsigned(time(NULL)));
 
    TestCase_01();
 
    return 0;
}
 
				Ci8vIFRoaXMgY29kZSBpcyBpbiBDKysxMQoKI2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8YWxnb3JpdGhtPgojaW5jbHVkZSA8ZnVuY3Rpb25hbD4KI2luY2x1ZGUgPG1lbW9yeT4KI2luY2x1ZGUgPGNsaW1pdHM+CiNpbmNsdWRlIDxpdGVyYXRvcj4KCnVzaW5nIG5hbWVzcGFjZSBzdGQ7CgovLyA6KSwgZ2VuZXJpYyBmdW5jdG9yCnRlbXBsYXRlIDx0eXBlbmFtZSBBcmdUeXBlLCB0eXBlbmFtZSBSZXN1bHRUeXBlPgpzdHJ1Y3QgUHJlZFVuaXF1ZUVsZW1lbnRzIDogcHVibGljIHN0ZDo6dW5hcnlfZnVuY3Rpb248QXJnVHlwZSwgUmVzdWx0VHlwZT4gewoKcHVibGljOgogICAgUHJlZFVuaXF1ZUVsZW1lbnRzKEFyZ1R5cGUgcmVmKSA6IHByZXYocmVmKSB7fQogICAgCiAgIFJlc3VsdFR5cGUgb3BlcmF0b3IoKSAoQXJnVHlwZSBjdXJyKSB7CiAgICAgIEFyZ1R5cGUgb2xkID0gcHJldjsKICAgICAgcHJldiA9IGN1cnI7CiAgICAgIHJldHVybiBjdXJyICE9IG9sZDsKICAgfQoKcHJpdmF0ZToKICAgIEFyZ1R5cGUgcHJldjsKfTsKCmludCBHZW5lcmF0ZURhdGFTZXQoaW50IEFbXSwgaW50IHNpemUpIHsKICAgIGZvcihpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspCiAgICAgICAgQVtpXSA9IHJhbmQoKSVzaXplOwoKICAgIHNvcnQoQSwgQStzaXplKTsKICAgIAogICAgLy8gcHJlZGljYXRlIGZ1bnRvciBkZWZpbml0aW9uCiAgICBQcmVkVW5pcXVlRWxlbWVudHM8aW50LCBib29sPiBwcmVkKElOVF9NSU4pOwoKICAgIC8vIFJldGFpbiBvbmx5IHVuaXF1ZSBlbGVtZW50cwogICAgYXV0byBpdCA9IGNvcHlfaWYgKEEsIEErc2l6ZSwgQSwgcHJlZCk7CiAgICByZXR1cm4gZGlzdGFuY2UoQSwgaXQpOwp9CgovLyBSZXR1cm5zIGxvY2F0aW9uIG9mIGtleSwgb3IgLTEgaWYgbm90IGZvdW5kCmludCBCaW5hcnlTZWFyY2hTaW1wbGUoaW50IEFbXSwgaW50IGwsIGludCByLCBpbnQga2V5LCBpbnQgJmNvdW50KQp7CiAgICBpbnQgbTsKIAogICAgd2hpbGUoIGwgPD0gciApCiAgICB7CiAgICAgICAgbSA9IGwgKyAoci1sKS8yOwogCiAgICAgICAgY291bnQrKzsKICAgICAgICBpZiggQVttXSA9PSBrZXkgKSAvLyBmaXJzdCBjb21wYXJpc29uCiAgICAgICAgICAgIHJldHVybiBtOwogCiAgICAgICAgY291bnQrKzsKICAgICAgICBpZiggQVttXSA8IGtleSApIC8vIHNlY29uZCBjb21wYXJpc29uCiAgICAgICAgICAgIGwgPSBtICsgMTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIHIgPSBtIC0gMTsKICAgIH0KIAogICAgcmV0dXJuIC0xOwp9CgppbnQgQmluYXJ5U2VhcmNoKGludCBBW10sIGludCBsLCBpbnQgciwgaW50IGtleSwgaW50ICZjb3VudCkKewogICAgaW50IG07CiAKICAgIHdoaWxlKCByIC0gbCA+IDEgKQogICAgewogICAgICAgIG0gPSBsICsgKHItbCkvMjsKIAogICAgICAgIGNvdW50Kys7CiAgICAgICAgaWYoIEFbbV0gPD0ga2V5ICkKICAgICAgICAgICAgbCA9IG07CiAgICAgICAgZWxzZQogICAgICAgICAgICByID0gbTsKICAgIH0KIAogICAgY291bnQrKzsKICAgIGlmKCBBW2xdID09IGtleSApCiAgICAgICAgcmV0dXJuIGw7CiAgICBlbHNlCiAgICAgICAgcmV0dXJuIC0xOwp9Cgp2b2lkIFRlc3RDYXNlXzAxKCkgewogICAgaW50IHNpemUgPSAyMDQ4OwogICAgYXV0b19wdHI8aW50PiBidWYobmV3IGludFtzaXplXSk7CiAgICBpbnQgKkEgPSBidWYuZ2V0KCk7CiAgICAKICAgIHNpemUgPSBHZW5lcmF0ZURhdGFTZXQoQSwgc2l6ZSk7CiAgICAKICAgIGNvcHkoQSwgQStzaXplLCBvc3RyZWFtX2l0ZXJhdG9yPGludD4oY291dCwgIiAiKSksIGNvdXQgPDwgZW5kbDsKICAgIAogICAgaW50IGtleSA9IDE5MzsKICAgIGludCBjb3VudDsKICAgIAogICAgLy8gV2UgYXJlIG9ubHkgaW50ZXJlc3RlZCBpbiBjb21wYXJpc29uIGNvdW50CiAgICBjb3VudCA9IDA7CiAgICBCaW5hcnlTZWFyY2hTaW1wbGUoQSwgMCwgc2l6ZS0xLCBrZXksIGNvdW50KTsKICAgIGNvdXQgPDwgIkJpbmFyeVNlYXJjaFNpbXBsZSAiIDw8IGNvdW50IDw8IGVuZGw7CiAgICAKICAgIGNvdW50ID0gMDsKICAgIEJpbmFyeVNlYXJjaChBLCAwLCBzaXplLTEsIGtleSwgY291bnQpOwogICAgY291dCA8PCAiQmluYXJ5U2VhcmNoICIgPDwgY291bnQgPDwgZW5kbDsKfQoKaW50IG1haW4oKSB7CiAgICBzcmFuZCh1bnNpZ25lZCh0aW1lKE5VTEwpKSk7CiAgICAKICAgIFRlc3RDYXNlXzAxKCk7CiAgICAKICAgIHJldHVybiAwOwp9Cg==