UNPKG

lgrthms

Version:

Algorithms and data structures for your JavaScript and TypeScript projects 🧑‍💻

140 lines (139 loc) 4.85 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.searchForRange = exports.binarySearchLastIndex = exports.binarySearchLast = exports.binarySearchFirstIndex = exports.binarySearchFirst = exports.shiftedBinarySearchIndex = exports.shiftedBinarySearch = exports.binarySearchIndex = exports.binarySearch = void 0; function binarySearch(array, target, get) { const index = binarySearchIndex(array, target, get); return index !== -1 ? array[index] : undefined; } exports.binarySearch = binarySearch; function binarySearchIndex(array, target, get) { let leftIdx = 0; let rightIdx = array.length - 1; get = get ? get : (element) => element; while (leftIdx <= rightIdx) { const middleIdx = Math.floor((leftIdx + rightIdx) / 2); const element = array[middleIdx]; const value = get(element); if (target === value) { return middleIdx; } if (target < value) { rightIdx = middleIdx - 1; } else { leftIdx = middleIdx + 1; } } return -1; } exports.binarySearchIndex = binarySearchIndex; function shiftedBinarySearch(array, target, get) { const index = shiftedBinarySearchIndex(array, target, get); return index !== -1 ? array[index] : undefined; } exports.shiftedBinarySearch = shiftedBinarySearch; function shiftedBinarySearchIndex(array, target, get) { let leftIdx = 0; let rightIdx = array.length - 1; get = get ? get : (element) => element; while (leftIdx <= rightIdx) { const middleIdx = Math.floor((leftIdx + rightIdx) / 2); const middleValue = get(array[middleIdx]); if (target === middleValue) { return middleIdx; } const leftValue = get(array[leftIdx]); const rightValue = get(array[rightIdx]); if (leftValue <= middleValue) { if (target < middleValue && target >= leftValue) { rightIdx = middleIdx - 1; } else { leftIdx = middleIdx + 1; } } else { if (target > middleValue && target <= rightValue) { leftIdx = middleIdx + 1; } else { rightIdx = middleIdx - 1; } } } return -1; } exports.shiftedBinarySearchIndex = shiftedBinarySearchIndex; function binarySearchFirst(array, target, get) { const index = binarySearchFirstIndex(array, target, get); return index !== -1 ? array[index] : undefined; } exports.binarySearchFirst = binarySearchFirst; function binarySearchFirstIndex(array, target, get) { let leftIdx = 0; let rightIdx = array.length - 1; get = get ? get : (element) => element; while (leftIdx <= rightIdx) { const middleIdx = Math.floor((leftIdx + rightIdx) / 2); const middleValue = get(array[middleIdx]); if (target === middleValue) { if (middleIdx === 0) { return middleIdx; } const middlePreviousValue = get(array[middleIdx - 1]); if (target === middlePreviousValue) { rightIdx = middleIdx - 1; } else { return middleIdx; } } if (target < middleValue) { rightIdx = middleIdx - 1; } else { leftIdx = middleIdx + 1; } } return -1; } exports.binarySearchFirstIndex = binarySearchFirstIndex; function binarySearchLast(array, target, get) { const index = binarySearchLastIndex(array, target, get); return index !== -1 ? array[index] : undefined; } exports.binarySearchLast = binarySearchLast; function binarySearchLastIndex(array, target, get) { let leftIdx = 0; let rightIdx = array.length - 1; get = get ? get : (element) => element; while (leftIdx <= rightIdx) { const middleIdx = Math.floor((leftIdx + rightIdx) / 2); const middleValue = get(array[middleIdx]); if (target === middleValue) { if (middleIdx === array.length - 1) { return middleIdx; } const middleNextValue = get(array[middleIdx + 1]); if (target === middleNextValue) { leftIdx = middleIdx + 1; } else { return middleIdx; } } if (target < middleValue) { rightIdx = middleIdx - 1; } else { leftIdx = middleIdx + 1; } } return -1; } exports.binarySearchLastIndex = binarySearchLastIndex; function searchForRange(array, target, get) { get = get ? get : (element) => element; return [binarySearchFirstIndex(array, target, get), binarySearchLastIndex(array, target, get)]; } exports.searchForRange = searchForRange;