How to find the minimum distance between two numbers in an array with TypeScript

1 Answer

0 votes
/**
 * Utility class for finding distances between values in arrays.
 */
class ArrayDistance {
    /**
     * Prevent instantiation.
     */
    private constructor() {}

    /**
     * Finds the minimum distance between two target values in an array.
     *
     * @param numbers Array to search.
     * @param target1 First target value.
     * @param target2 Second target value.
     * @returns The minimum distance between the targets,
     *          or -1 if no valid pair exists.
     * @throws TypeError If numbers is not an array.
     */
    public static findMinimumDistance(
        numbers: readonly number[],
        target1: number,
        target2: number
    ): number {
        if (!Array.isArray(numbers)) {
            throw new TypeError("numbers must be an array.");
        }

        // Special case: both targets are the same value.
        if (target1 === target2) {
            return this.findMinimumDistanceBetweenDuplicates(
                numbers,
                target1
            );
        }

        let lastSeenIndex: number = -1;
        let minimumDistance: number = Number.MAX_SAFE_INTEGER;

        for (
            let currentIndex: number = 0;
            currentIndex < numbers.length;
            currentIndex++
        ) {
            const currentValue: number = numbers[currentIndex];

            // Skip values that are not targets.
            if (
                currentValue !== target1 &&
                currentValue !== target2
            ) {
                continue;
            }

            /*
             * If we've previously seen one target value and
             * the current value is the other target value,
             * update the minimum distance.
             */
            if (
                lastSeenIndex >= 0 &&
                currentValue !== numbers[lastSeenIndex]
            ) {
                const distance: number =
                    currentIndex - lastSeenIndex;

                minimumDistance = Math.min(
                    minimumDistance,
                    distance
                );
            }

            // Remember the most recent occurrence.
            lastSeenIndex = currentIndex;
        }

        return minimumDistance === Number.MAX_SAFE_INTEGER
            ? -1
            : minimumDistance;
    }

    /**
     * Finds the minimum distance between consecutive occurrences
     * of the same value.
     *
     * @param numbers Array to search.
     * @param target Value to search for.
     * @returns The minimum distance between occurrences,
     *          or -1 if fewer than two occurrences exist.
     */
    private static findMinimumDistanceBetweenDuplicates(
        numbers: readonly number[],
        target: number
    ): number {
        let previousIndex: number = -1;
        let minimumDistance: number = Number.MAX_SAFE_INTEGER;

        for (let i: number = 0; i < numbers.length; i++) {
            if (numbers[i] !== target) {
                continue;
            }

            if (previousIndex >= 0) {
                const distance: number = i - previousIndex;

                minimumDistance = Math.min(
                    minimumDistance,
                    distance
                );
            }

            previousIndex = i;
        }

        return minimumDistance === Number.MAX_SAFE_INTEGER
            ? -1
            : minimumDistance;
    }
}

// Example usage
const numbers: number[] = [2, 3, 7, 3, 3, 4, 8, 8, 8, 11, 9, 1, 3];

const result: number = ArrayDistance.findMinimumDistance(numbers, 3, 8);

console.log(
    result >= 0
        ? `Minimum distance between 3 and 8: ${result}`
        : "No valid pair found."
);


/*
run:

Minimum distance between 3 and 8: 2

*/

 



answered Aug 25, 2022 by avibootz
edited Oct 21 by avibootz
...