Hone logo
Hone
Problems

Type-Level Binary Search in TypeScript

This challenge asks you to implement a binary search algorithm operating entirely at the type level in TypeScript. Type-level programming allows us to perform computations and manipulations using types as if they were values, enabling powerful compile-time checks and optimizations. This exercise will test your understanding of conditional types, mapped types, and recursive type manipulations.

Problem Description

You need to create a type BinarySearch<T extends number[], Target extends number, Start extends number = 0, End extends number = 0> that performs a binary search on a sorted number array T to find the index of a Target number. The Start and End parameters represent the search boundaries, defaulting to 0 and the length of the array respectively. The type should return the index of the Target if found, otherwise it should return -1.

Key Requirements:

  • The input array T must be sorted in ascending order.
  • The Start and End parameters should define the search range within the array.
  • The algorithm should recursively divide the search space in half until the Target is found or the search space is exhausted.
  • The return type should be a number representing the index of the Target in the array, or -1 if the Target is not found.
  • The solution must be purely type-level; no runtime code is allowed.

Expected Behavior:

  • If the Target exists in the array, the type should resolve to the index of the Target.
  • If the Target does not exist in the array, the type should resolve to -1.
  • The type should handle edge cases such as empty arrays, Target smaller than the smallest element, and Target larger than the largest element.

Edge Cases to Consider:

  • Empty array T: Should return -1.
  • Target smaller than the smallest element in T: Should return -1.
  • Target larger than the largest element in T: Should return -1.
  • Target is the first or last element of T.
  • Start and End are out of bounds (though the default values should handle this).

Examples

Example 1:

Input: [1, 2, 3, 4, 5], 3
Output: 2
Explanation: The target 3 is found at index 2 in the array [1, 2, 3, 4, 5].

Example 2:

Input: [1, 2, 3, 4, 5], 6
Output: -1
Explanation: The target 6 is not found in the array [1, 2, 3, 4, 5].

Example 3:

Input: [2, 5, 7, 8, 11, 12], 13, 0, 5
Output: -1
Explanation: The target 13 is not found within the specified range [0, 5] of the array [2, 5, 7, 8, 11, 12].

Example 4:

Input: [1, 2, 3], 1, 0, 0
Output: 0
Explanation: The target 1 is found at index 0 in the array [1, 2, 3] within the range [0, 0].

Constraints

  • T must be an array of numbers (number[]).
  • Target must be a number.
  • Start and End must be numbers.
  • The array T is guaranteed to be sorted in ascending order.
  • The solution should be as efficient as possible in terms of type complexity (avoiding excessively deep recursion).

Notes

  • Consider using conditional types to check if the Target falls within the current search range.
  • You'll likely need to use mapped types to extract elements from the array based on their index.
  • Recursion is essential for implementing the binary search logic at the type level.
  • Think about how to handle the base cases (target found, search space exhausted).
  • The Exclude<number, -1> type can be useful for ensuring the index is a valid positive number.
  • The [key: number] index signature is crucial for accessing array elements by index within types.
Loading editor...
typescript