The Weekly Challenge 345

Mountain Peaks & Visitor Queues!

Original Challenge Link

Task 1: Peak Positions

"Spotting the Summits: Where Are the Peaks?"

Given an array of integers, find all peaks — elements that are strictly greater than both their left and right neighbours. Return the indices of all such positions.

The Strategy: Iterate once over the array. For each index, compare the element with its left neighbour (if any) and right neighbour (if any). An element qualifies as a peak only when it is strictly greater than both. The first and last elements can also be peaks if they exceed their single neighbour.
Perl Implementation
sub peak_positions ($ints_ref) {
    state $check = compile( ArrayRef [Int] );
    my ($ints) = $check->($ints_ref);

    my @peaks;
    for my $idx ( 0 .. $#$ints ) {
        my $current = $ints->[$idx];
        my $left    = $idx > 0       ? $ints->[ $idx - 1 ] : undef;
        my $right   = $idx < $#$ints ? $ints->[ $idx + 1 ] : undef;

        next if defined($left)  && $current <= $left;
        next if defined($right) && $current <= $right;

        push @peaks, $idx;
    }

    return \@peaks;
}
Python Implementation
def peak_positions(ints: list[int]) -> list[int]:
    """Return indices of all elements strictly greater than their neighbours."""
    peaks = []
    for i, val in enumerate(ints):
        left = ints[i - 1] if i > 0 else None
        right = ints[i + 1] if i < len(ints) - 1 else None

        if left is not None and val <= left:
            continue
        if right is not None and val <= right:
            continue
        peaks.append(i)
    return peaks

Task 2: Last Visitor

"Queue Jumping: Who Was the Last Visitor?"

Process an array where positive integers are added to the front of a queue and -1 values request the x-th most recent visitor, where x counts consecutive -1s. Return the answers for each -1 encountered.

The Strategy: Maintain a list of seen positive integers (newest at front) and a counter for consecutive -1 values. For each -1, look up the x-th element in the seen list. If x exceeds the list length, return -1. Reset the counter whenever a positive number arrives.
Perl Implementation
sub last_visitor ($ints_ref) {
    state $check = compile( ArrayRef [Int] );
    my ($ints) = $check->($ints_ref);

    my @seen;
    my @answer;
    my $neg_run = 0;

    for my $value (@$ints) {
        if ( $value == -1 ) {
            my $lookup = $neg_run < @seen ? $seen[$neg_run] : -1;
            push @answer, $lookup;
            $neg_run++;
            next;
        }

        unshift @seen, $value;
        $neg_run = 0;
    }

    return \@answer;
}
Python Implementation
def last_visitor(ints: list[int]) -> list[int]:
    """Process visitor queue: positive ints add, -1 looks up x-th most recent."""
    seen: list[int] = []
    answer: list[int] = []
    neg_run = 0

    for val in ints:
        if val == -1:
            lookup = seen[neg_run] if neg_run < len(seen) else -1
            answer.append(lookup)
            neg_run += 1
            continue

        seen.insert(0, val)
        neg_run = 0

    return answer