Peter’s blog ✴ Week 396 ✴ 19 October 2026
THE WEEKLY CHALLENGE
A race and some hills
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.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
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.
#!/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
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