Peter’s blog ✴ Week 396 ✴ 19 October 2026

THE WEEKLY CHALLENGE
A race and some hills

The Perl Camel

Task 2

Trionic array

You are given an array of $n integers. Write a script to return 'true' if the given array is Trionic, and otherwise return 'false'.

An array is trionic if there exist indices 0 < $p < $q < $n − 1 such that

  • @arr[0 .. $p] is strictly increasing,
  • @arr[$p .. $q] is strictly decreasing, and
  • @arr[$q .. $n − 1] is strictly increasing.

Examples


Example 1
Input: @arr = (1, 3, 5, 4, 2, 6, 8)
Output: true
Choose p = 2 and q = 4
$arr[0..2] = (1, 3, 5) (strictly increasing)
$arr[2..4] = (5, 4, 2) (strictly decreasing)
$arr[4..6] = (2, 6, 8) (strictly increasing)
Valid indices: 0 < p (2) < q (4) < n-1 (6).

Example 2
Input: @arr = (1, 4, 4, 2, 1, 3, 5)
Output: false
The first segment (1, 4, 4) contains duplicate adjacent values, so it
   is not strictly increasing.
No valid p and q exist to satisfy all three strictly monotonic
   conditions.

Example 3
Input: @arr = (2, 10, 3, 1, 9)
Output: true
Choose p = 1 and q = 3.
$arr[0..1] = (2, 10)    (strictly increasing)
$arr[1..3] = (10, 3, 1) (strictly decreasing)
$arr[3..4] = (1, 9)     (strictly increasing)

Example 4
Input: @arr = (1, 2, 3, 4, 3, 2, 1)
Output: false
This is a standard mountain array (strictly increasing, then strictly
   decreasing).
There is no second valley (q) that transitions back into a strictly
   increasing third segment before reaching the end of the array.

Example 5
Input: @arr = (1, 3, 6, 4, 2, 7, 8, 4)
Output: false

Analysis

My algorithm is perhaps rather opaque, but it has the merit of comparing each pair of consecutive heights only once, and being quite short.

In doing so it builds a string containg 'u' for every uphill pair, 'd' for a downhill pair, and immediately returning false for an equal pair.

The string is then matched to m|^((u+)d+)u+$| which translates as a string of 1 or more 'u', then 1 or more 'd', then 1 or more 'u', which matches the trionic definition.

The brackets capture the number of characters preceding the 2 points of inflection, ie the zero-based index of points $p and $q. This uses the fact that Perl allows nested bracket pairs, numbered in the order of the opening brackets.

Try it 

Your input:



eg: 1, 2, 3, 2, 3, 4, 5

Script


#!/usr/bin/perl

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

use v5.26;    # The Weekly Challenge - 2026-10-19
use utf8;     # Week 396 - task 2 - Trionic array
use warnings; # Peter Campbell Smith
binmode STDOUT, ':utf8';
use Encode;

trionic_array(1, 3, 5, 4, 2, 6, 8);
trionic_array(1, 4, 4, 2, 1, 3, 5);
trionic_array(2, 10, 3, 1, 9);
trionic_array(1, 2, 3, 4, 3, 2, 1);
trionic_array(1, 3, 6, 4, 2, 7, 8, 4);
trionic_array(1);
trionic_array(1, 2);
trionic_array(1, 2, 1);
trionic_array(1, 2, 1, 2);
trionic_array(2, 1);
trionic_array(2, 1, 0, 1, 2, 1);
trionic_array(-5 .. 0, -1 .. 5);

sub trionic_array {
    
    my (@array, $j, $profile);
    
    # initialise
    @array = @_;
    $profile = '';
    say qq[\nInput:  (] . join(', ', @array) . ')';
    
    # loop over heights
    for $j (0 .. $#array - 1) {
        if    ($array[$j + 1] > $array[$j]) { $profile .= 'u' }
        elsif ($array[$j + 1] < $array[$j]) { $profile .= 'd' }
        else                                { $profile = ''; last }
    }
    
    # report
    if ($profile =~ m|^((u+)d+)u+$|) {
        say qq[Output: true, \$p = ] . length($2) .  
            qq[, \$q = ] . length($1);
    } else {
        say qq[Output: false]
    }
}

22 lines of code

Output from script


Input:  (1, 3, 5, 4, 2, 6, 8)
Output: true, $p = 2, $q = 4

Input:  (1, 4, 4, 2, 1, 3, 5)
Output: false

Input:  (2, 10, 3, 1, 9)
Output: true, $p = 1, $q = 3

Input:  (1, 2, 3, 4, 3, 2, 1)
Output: false

Input:  (1, 3, 6, 4, 2, 7, 8, 4)
Output: false

Input:  (1)
Output: false

Input:  (1, 2)
Output: false

Input:  (1, 2, 1)
Output: false

Input:  (1, 2, 1, 2)
Output: true, $p = 1, $q = 2

Input:  (2, 1)
Output: false

Input:  (2, 1, 0, 1, 2, 1)
Output: false

Input:  (-5, -4, -3, -2, -1, 0, -1, 0, 1, 2, 3, 4, 5)
Output: true, $p = 5, $q = 6

 

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