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

1 Answer

0 votes
declare(strict_types=1);

/**
 * Provides utility methods for working with arrays.
 */
final class ArrayDistance
{
    /**
     * Prevent instantiation of this utility class.
     */
    private function __construct()
    {
    }

    /**
     * Finds the minimum distance between two target values in an array.
     *
     * Example:
     * [2, 3, 7, 3, 3, 4, 8, 8, 8, 11, 9, 1, 3]
     *
     * Targets:
     * 3 and 8
     *
     * Result:
     * 2
     *
     * @param int[] $numbers Input array.
     * @param int $target1 First target value.
     * @param int $target2 Second target value.
     *
     * @return int Minimum distance between the targets,
     *             or -1 if no valid pair exists.
     */
    public static function findMinimumDistance(
        array $numbers,
        int $target1,
        int $target2
    ): int {
        // Special case: both targets are the same value.
        if ($target1 === $target2) {
            return self::findMinimumDistanceBetweenDuplicates(
                $numbers,
                $target1
            );
        }

        $lastSeenIndex = -1;
        $minimumDistance = PHP_INT_MAX;

        foreach ($numbers as $currentIndex => $currentValue) {

            // Skip irrelevant values.
            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]) {

                $distance = $currentIndex - $lastSeenIndex;

                $minimumDistance = min(
                    $minimumDistance,
                    $distance
                );
            }

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

        return $minimumDistance === PHP_INT_MAX
            ? -1
            : $minimumDistance;
    }

    /**
     * Finds the minimum distance between consecutive occurrences
     * of the same value.
     *
     * @param int[] $numbers Input array.
     * @param int $target Target value.
     *
     * @return int Minimum distance, or -1 if the value occurs
     *             fewer than two times.
     */
    private static function findMinimumDistanceBetweenDuplicates(
        array $numbers,
        int $target
    ): int {
        $previousIndex = -1;
        $minimumDistance = PHP_INT_MAX;

        foreach ($numbers as $currentIndex => $currentValue) {

            if ($currentValue !== $target) {
                continue;
            }

            if ($previousIndex >= 0) {
                $distance = $currentIndex - $previousIndex;

                $minimumDistance = min(
                    $minimumDistance,
                    $distance
                );
            }

            $previousIndex = $currentIndex;
        }

        return $minimumDistance === PHP_INT_MAX
            ? -1
            : $minimumDistance;
    }
}

/*
 * Example usage
 */
$numbers = [2, 3, 7, 3, 3, 4, 8, 8, 8, 11, 9, 1, 3];

$result = ArrayDistance::findMinimumDistance($numbers, 3, 8);

if ($result >= 0) {
    echo "Minimum distance between 3 and 8: {$result}" . PHP_EOL;
} else {
    echo "No valid pair found." . PHP_EOL;
}


/*
run:

Minimum distance between 3 and 8: 2

*/

 



answered Aug 24, 2022 by avibootz
edited Oct 21 by avibootz

Related questions

...