Camel
Peter
Peter Campbell Smith

Peak at the answers

Weekly challenge 345 — 27 October 2025

Week 345: 27 Oct 2025

Task 2

Task — Last visitor

You are given an integer array @ints where each element is either a positive integer or -1.

Process the array from left to right while maintaining two lists:
@seen stores previously seen positive integers (newest at the front)
@ans stores the answers for each -1

Rules:
If $ints[$i] is a positive number insert it at the front of @seen
If $ints[$i] is -1:
... Let $x be how many -1s in a row we’ve seen before this one.
... If $x < length(@seen) append $seen[$x] to @ans
... Else append -1 to @ans

At the end, return @ans.

Examples


Example 1
Input: @ints = (5, -1, -1)
Output: (5, -1)
@seen = (5)
First  -1: @ans = (5)
Second -1: @ans = (5, -1)

Example 2
Input: @ints = (3, 7, -1, -1, -1)
Output: (7, 3, -1)
@seen = (3, 7)
First  -1: @ans = (7)
Second -1: @ans = (7, 3)
Third  -1: @ans = (7, 3, -1)

Example 3
Input: @ints = (2, -1, 4, -1, -1)
Output: (2, 4, 2)

Example 4
Input: @ints = (10, 20, -1, 30, -1, -1)
Output: (20, 30, 20)

Example 5
Input: @ints = (-1, -1, 5, -1)
Output: (-1, -1, 5)

Analysis

This was a difficult challenge to get my head around!

Eventually I deduced that to match the examples, the line

If $x < length(@seen) append $seen[$x] to @ans

should read append $seen[$#seen - $x] to @ans. In other words, the element to be appended is not the $xth element of @seen, but the $xth element counting back from the end.

Alternatively, perhaps 'newest at the front' means adding successive elements to the start of @seen - like Perl unshift - but that does not match the @seen shown for example 2.

Once I figured that out, the coding just follows the challenge text.

I have yet to discover a real-world use case for this algorithm!

Try it 

Try running the script with any input:



example: 6, 4, -1, 3, -1, 5, 7, 8, -1, -1, -1, -1

Script


#!/usr/bin/perl

# Blog: http://ccgi.campbellsmiths.force9.co.uk/challenge

use v5.26;    # The Weekly Challenge - 2025-10-27
use utf8;     # Week 345 - task 2 - Last visitor
use warnings; # Peter Campbell Smith
binmode STDOUT, ':utf8';
use Encode;

last_visitor(5, -1, -1);
last_visitor(3, 7, -1, -1, -1);
last_visitor(2, -1, 4, -1, -1);
last_visitor(10, 20, -1, 30, -1, -1);
last_visitor(-1, -1, 5, -1);

sub last_visitor {
    
    my (@ints, @ans, @seen, $i, $x);
    
    # initialise
    @ints = @_;
    $x = 0;
    
    for $i (0 .. $#ints) {
        
        # if $ints[i] is +ve push it onto @seen
        if ($ints[$i] > 0) {
            push @seen, $ints[$i];
            $x = 0;

        # if $ints[$i] is -1 ...
        } elsif ($ints[$i] == -1) {
            
            # ... and $x <= length of @seen
            if ($x <= $#seen) {
                
                # push $x'th from last element of @seen onto @ans 
                push @ans, $seen[$#seen - $x];          
            } else {
                
                #  else push -1 onto @ans
                push @ans, -1;
            }
            
            # increment no of consecutive -1s
            $x ++;
        }
    }
    say qq[\nInput:  (] . join(', ', @ints) . ')';
    say qq[Output: (] . join(', ', @ans) . ')';
}

Output


Input:  (5, -1, -1)
Output: (5, -1)

Input:  (3, 7, -1, -1, -1)
Output: (7, 3, -1)

Input:  (2, -1, 4, -1, -1)
Output: (2, 4, 2)

Input:  (10, 20, -1, 30, -1, -1)
Output: (20, 30, 20)

Input:  (-1, -1, 5, -1)
Output: (-1, -1, 5)

 

Any content of this website which has been created by Peter Campbell Smith is in the public domain