// a is arr, key is target, low = 0, hi = a.length-1
// mid = low + (high - low) / 2 to avoid integer overflow
let contains = (a, key, low, high, ans = false) => { // return true/false
while (low <= high) {
let mid = low + (high - low) / 2;
if (a[mid] < key) low = mid + 1;
else if (a[mid] > key) high = mid - 1;
else if (a[mid] == key) {
ans = true;break;
}
}
return ans;
}
let containsfirst = (a, key, low, high, ans = -1) => { // return first occurence of key
while (low <= high) {
let mid = low + (high - low + 1) / 2;
if (a[mid] < key) low = mid + 1;
else if (a[mid] > key) high = mid - 1;
else if (a[mid] == key) {
ans = mid;
high = mid - 1;
}
}
return ans;
}
let containslast = (a, key, low, high, ans = -1) => { // return last occurence of key
while (low <= high) {
let mid = low + (high - low + 1) / 2;
if (a[mid] < key) low = mid + 1;
else if (a[mid] > key) high = mid - 1;
else if (a[mid] == key) {
ans = mid;
low = mid + 1;
}
}
return ans;
}
let noKeyleastgreater = (a, key, low, high, ans = -1) => { // no need to find key
while (low <= high) {
let mid = low + (high - low + 1) / 2;
if (a[mid] < key)low = mid + 1;
else if (a[mid] > key) {
ans = mid;
high = mid - 1;
}else if (a[mid] == key) low = mid + 1;
}
return ans;
}
let noKeygreatestlesser = (a, key, low, high, ans = -1) => {
while (low <= high) {
let mid = low + (high - low + 1) / 2;
if (a[mid] < key) {
ans = mid;
low = mid + 1;
} else if (a[mid] > key || a[mid] == key) high = mid - 1;
}
return ans;
}