#include <iostream>
using namespace std;
#include <stdio.h>
#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))
int BinarySearchIndexOfMinimumRotatedArray(int A[], int l, int r) {
// extreme condition, size zero or size two
int m;
// Precondition: A[l] > A[r]
if( A[l] <= A[r] )
return l;
while( l <= r ) {
// Termination condition (l will eventually falls on r, and r always point minimum possible value)
if( l == r )
return l;
m = l + (r-l)/2; // 'm' can fall in first pulse, second pulse or exactly in the middle
if( A[m] < A[r] )
// local min can't be in the range (m < i <= r), we can exclude A[m+1 ... r]
r = m;
else
// local min must be in the range (m < i <= r), we must search in A[m+1 ... r]
l = m+1;
}
return -1;
}
int BinarySearchIndexOfMinimumRotatedArray(int A[], int size) {
return BinarySearchIndexOfMinimumRotatedArray(A, 0, size-1);
}
////////////////////////////////////////////////////////////////////////////////
// Helper functions to test our implementation
void RotateToLeftByOnePosition(int A[], int size) {
int aux = A[0];
for(int i = 0; i < size-1; i++)
A[i] = A[i+1];
A[size-1] = aux;
}
void PrintArray(int A[], int size) {
for(int i = 0; i < size; i++)
printf("%4d", A[i]);
printf("\n");
}
////////////////////////////////////////////////////////////////////////////////
void TestCase_01(void) {
// Odd size array
int A[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
int size = ARRAY_SIZE(A);
int minIndex;
int i = -1;
printf("\nTest Case 01\n");
do {
PrintArray(A, size);
minIndex = BinarySearchIndexOfMinimumRotatedArray(A, size);
printf("%d\n", A[minIndex]);
RotateToLeftByOnePosition(A, size);
} while(++i < size);
}
void TestCase_02(void) {
// Even size array
int A[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int size = ARRAY_SIZE(A);
int minIndex;
int i = -1;
printf("\nTest Case 02\n");
do {
PrintArray(A, size);
minIndex = BinarySearchIndexOfMinimumRotatedArray(A, size);
printf("%d\n", A[minIndex]);
RotateToLeftByOnePosition(A, size);
} while(++i < size);
}
void TestCase_03(void) {
// Corner case
int A[] = {2, 1};
int size = ARRAY_SIZE(A);
printf("\nTest Case 03\n");
PrintArray(A, size);
printf("%d\n", A[BinarySearchIndexOfMinimumRotatedArray(A, size)]);
}
void TestCase_04(void) {
// Corner case
int A[] = {1};
int size = ARRAY_SIZE(A);
printf("\nTest Case 04\n");
PrintArray(A, size);
printf("%d\n", A[BinarySearchIndexOfMinimumRotatedArray(A, size)]);
}
int main() {
TestCase_01();
TestCase_02();
TestCase_03();
TestCase_04();
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKI2luY2x1ZGUgPHN0ZGlvLmg+CgojZGVmaW5lIEFSUkFZX1NJWkUoYSkgKHNpemVvZihhKS9zaXplb2YoYVswXSkpCgppbnQgQmluYXJ5U2VhcmNoSW5kZXhPZk1pbmltdW1Sb3RhdGVkQXJyYXkoaW50IEFbXSwgaW50IGwsIGludCByKSB7CiAgICAvLyBleHRyZW1lIGNvbmRpdGlvbiwgc2l6ZSB6ZXJvIG9yIHNpemUgdHdvCiAgICBpbnQgbTsKCiAgICAvLyBQcmVjb25kaXRpb246IEFbbF0gPiBBW3JdCiAgICBpZiggQVtsXSA8PSBBW3JdICkKICAgICAgICByZXR1cm4gbDsKCiAgICB3aGlsZSggbCA8PSByICkgewogICAgICAgIC8vIFRlcm1pbmF0aW9uIGNvbmRpdGlvbiAobCB3aWxsIGV2ZW50dWFsbHkgZmFsbHMgb24gciwgYW5kIHIgYWx3YXlzIHBvaW50IG1pbmltdW0gcG9zc2libGUgdmFsdWUpCiAgICAgICAgaWYoIGwgPT0gciApCiAgICAgICAgICAgIHJldHVybiBsOwoKICAgICAgICBtID0gbCArIChyLWwpLzI7ICAgIC8vICdtJyBjYW4gZmFsbCBpbiBmaXJzdCBwdWxzZSwgc2Vjb25kIHB1bHNlIG9yIGV4YWN0bHkgaW4gdGhlIG1pZGRsZQoKICAgICAgICBpZiggQVttXSA8IEFbcl0gKQogICAgICAgICAgICAvLyBsb2NhbCBtaW4gY2FuJ3QgYmUgaW4gdGhlIHJhbmdlIChtIDwgaSA8PSByKSwgd2UgY2FuIGV4Y2x1ZGUgQVttKzEgLi4uIHJdCiAgICAgICAgICAgIHIgPSBtOwogICAgICAgIGVsc2UKICAgICAgICAgICAgLy8gbG9jYWwgbWluIG11c3QgYmUgaW4gdGhlIHJhbmdlIChtIDwgaSA8PSByKSwgd2UgbXVzdCBzZWFyY2ggaW4gQVttKzEgLi4uIHJdCiAgICAgICAgICAgIGwgPSBtKzE7CiAgICB9CgogICAgcmV0dXJuIC0xOwp9CgppbnQgQmluYXJ5U2VhcmNoSW5kZXhPZk1pbmltdW1Sb3RhdGVkQXJyYXkoaW50IEFbXSwgaW50IHNpemUpIHsKICAgIHJldHVybiBCaW5hcnlTZWFyY2hJbmRleE9mTWluaW11bVJvdGF0ZWRBcnJheShBLCAwLCBzaXplLTEpOwp9CgovLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwovLyBIZWxwZXIgZnVuY3Rpb25zIHRvIHRlc3Qgb3VyIGltcGxlbWVudGF0aW9uCnZvaWQgUm90YXRlVG9MZWZ0QnlPbmVQb3NpdGlvbihpbnQgQVtdLCBpbnQgc2l6ZSkgewogICAgaW50IGF1eCA9IEFbMF07CiAgICBmb3IoaW50IGkgPSAwOyBpIDwgc2l6ZS0xOyBpKyspCiAgICAgICAgQVtpXSA9IEFbaSsxXTsKCiAgICBBW3NpemUtMV0gPSBhdXg7Cn0Kdm9pZCBQcmludEFycmF5KGludCBBW10sIGludCBzaXplKSB7CiAgICBmb3IoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKQogICAgICAgIHByaW50ZigiJTRkIiwgQVtpXSk7CgogICAgcHJpbnRmKCJcbiIpOwp9Ci8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCgp2b2lkIFRlc3RDYXNlXzAxKHZvaWQpIHsKICAgIC8vIE9kZCBzaXplIGFycmF5CiAgICBpbnQgQVtdID0gezEsIDIsIDMsIDQsIDUsIDYsIDcsIDgsIDl9OwogICAgaW50IHNpemUgPSBBUlJBWV9TSVpFKEEpOwogICAgaW50IG1pbkluZGV4OwogICAgaW50IGkgPSAtMTsKICAgIAogICAgcHJpbnRmKCJcblRlc3QgQ2FzZSAwMVxuIik7CgogICAgZG8gewogICAgICAgIFByaW50QXJyYXkoQSwgc2l6ZSk7CiAgICAgICAgbWluSW5kZXggPSBCaW5hcnlTZWFyY2hJbmRleE9mTWluaW11bVJvdGF0ZWRBcnJheShBLCBzaXplKTsKICAgICAgICBwcmludGYoIiVkXG4iLCBBW21pbkluZGV4XSk7CiAgICAgICAgUm90YXRlVG9MZWZ0QnlPbmVQb3NpdGlvbihBLCBzaXplKTsKICAgIH0gd2hpbGUoKytpIDwgc2l6ZSk7Cn0KCnZvaWQgVGVzdENhc2VfMDIodm9pZCkgewogICAgLy8gRXZlbiBzaXplIGFycmF5CiAgICBpbnQgQVtdID0gezEsIDIsIDMsIDQsIDUsIDYsIDcsIDgsIDksIDEwfTsKICAgIGludCBzaXplID0gQVJSQVlfU0laRShBKTsKICAgIGludCBtaW5JbmRleDsKICAgIGludCBpID0gLTE7CiAgICAKICAgIHByaW50ZigiXG5UZXN0IENhc2UgMDJcbiIpOwoKICAgIGRvIHsKICAgICAgICBQcmludEFycmF5KEEsIHNpemUpOwogICAgICAgIG1pbkluZGV4ID0gQmluYXJ5U2VhcmNoSW5kZXhPZk1pbmltdW1Sb3RhdGVkQXJyYXkoQSwgc2l6ZSk7CiAgICAgICAgcHJpbnRmKCIlZFxuIiwgQVttaW5JbmRleF0pOwogICAgICAgIFJvdGF0ZVRvTGVmdEJ5T25lUG9zaXRpb24oQSwgc2l6ZSk7CiAgICB9IHdoaWxlKCsraSA8IHNpemUpOwp9Cgp2b2lkIFRlc3RDYXNlXzAzKHZvaWQpIHsKICAgIC8vIENvcm5lciBjYXNlCiAgICBpbnQgQVtdID0gezIsIDF9OwogICAgaW50IHNpemUgPSBBUlJBWV9TSVpFKEEpOwogICAgCiAgICBwcmludGYoIlxuVGVzdCBDYXNlIDAzXG4iKTsKICAgIFByaW50QXJyYXkoQSwgc2l6ZSk7CiAgICBwcmludGYoIiVkXG4iLCBBW0JpbmFyeVNlYXJjaEluZGV4T2ZNaW5pbXVtUm90YXRlZEFycmF5KEEsIHNpemUpXSk7Cn0KCnZvaWQgVGVzdENhc2VfMDQodm9pZCkgewogICAgLy8gQ29ybmVyIGNhc2UKICAgIGludCBBW10gPSB7MX07CiAgICBpbnQgc2l6ZSA9IEFSUkFZX1NJWkUoQSk7CiAgICAKICAgIHByaW50ZigiXG5UZXN0IENhc2UgMDRcbiIpOwogICAgUHJpbnRBcnJheShBLCBzaXplKTsKICAgIHByaW50ZigiJWRcbiIsIEFbQmluYXJ5U2VhcmNoSW5kZXhPZk1pbmltdW1Sb3RhdGVkQXJyYXkoQSwgc2l6ZSldKTsKfQoKaW50IG1haW4oKSB7CiAgICBUZXN0Q2FzZV8wMSgpOwogICAgVGVzdENhc2VfMDIoKTsKICAgIFRlc3RDYXNlXzAzKCk7CiAgICBUZXN0Q2FzZV8wNCgpOwogICAgCiAgICByZXR1cm4gMDsKfQo=