Perl Weekly Challenge 396.
My solutions (task 1 and task 2 ) to the The Weekly Challenge - 396.
Task 1: Finishing Order
Submitted by: Mohammad Sajid Anwar
You are given two array of integers, @order and @friends.
The @order (size n) contains every integer from 1 to n
exactly once. The @friends contains ID in sorted in strictly
increasing order.
Write a script to return the array containing IDs in
finishing order.
Example 1
Input: @order = (3, 1, 4, 2, 5)
@friends = (1, 2, 4)
Output: (1, 4, 2)
ID 1 finished 2nd.
ID 4 finished 3rd.
ID 2 finished 4th.

Example 2
Input: @order = (5, 4, 3, 2, 1)
@friends = (1, 3, 5)
Output: (5, 3, 1)
ID 5 finished 1st.
ID 3 finished 3rd.
ID 1 finished 5th.

Example 3
Input: @order = (2, 4, 1, 3)
@friends = (1, 2, 3, 4)
Output: (2, 4, 1, 3)
ID 2 finished 1st.
ID 4 finished 2nd.
ID 1 finished 3rd.
ID 3 finished 4th.

Example 4
Input: @order = (4, 1, 3, 2)
@friends = (3)
Output: (3)

Example 5
Input: @order = (1, 3, 2, 6, 5, 4)
@friends = (1, 2, 3)
Output: (1, 3, 2)
ID 1 finished 1st.
ID 3 finished 2nd.
ID 2 finished 3rd.

I assume the inputs lists are given as space separated lists
of numbers in @ARGV. I make a map ids to places and use it to
sort_by (from List__UtilsBy) the array of ids. The
result takes a two-liner.
Examples:
perl -MList::UtilsBy=sort_by -E '
for my ($x,$y)(@ARGV){($p,$q)=map{[split" "]}$x,$y;$i=1; @l=();
$l[$_]=$i++ for@$p;say"$x; $y -> ", join " ", sort_by{$l[$_]}@$q}
' "3 1 4 2 5" "1 2 4" "5 4 3 2 1" "1 3 5" "2 4 1 3" "1 2 3 4" \
"4 1 3 2" "3" "1 3 2 6 5 4" "1 2 3"
Results:
3 1 4 2 5; 1 2 4 -> 1 4 2
5 4 3 2 1; 1 3 5 -> 5 3 1
2 4 1 3; 1 2 3 4 -> 2 4 1 3
4 1 3 2; 3 -> 3
1 3 2 6 5 4; 1 2 3 -> 1 3 2
The full code is:
1 # Perl weekly challenge 396
2 # Task 1: Finishing Order
3 #
4 # See https://wlmb.github.io/2026/10/19/PWC396/#task-1-finishing-order
5 use v5.36;
6 use feature qw(try);
7 use List::UtilsBy qw(sort_by);
8 die <<~"FIN" unless @ARGV && @ARGV%2==0;
9 Usage: $0 O0 F0 O1 F1...
10 to find the order of arrival of our friends Fn given
11 the order of arrival On. Fn and On are space separated lists
12 of integers.
13 FIN
14 for my ($order_string, $friends_string)(@ARGV){
15 my ($order, $friends)=map {[split " "]} $order_string, $friends_string;
16 my $i=1;
17 my %map;
18 $map{$_} = $i++ for @$order;
19 for(@$friends){
20 die "Friend is unknown: $_" unless defined $map{$_};
21 }
22 say"$order_string; $friends_string -> ",
23 join " ", sort_by{$map{$_}} @$friends;
24 }
Examples:
./ch-1.pl "3 1 4 2 5" "1 2 4" "5 4 3 2 1" "1 3 5" "2 4 1 3" "1 2 3 4" \
"4 1 3 2" "3" "1 3 2 6 5 4" "1 2 3"
Results:
3 1 4 2 5; 1 2 4 -> 1 4 2
5 4 3 2 1; 1 3 5 -> 5 3 1
2 4 1 3; 1 2 3 4 -> 2 4 1 3
4 1 3 2; 3 -> 3
1 3 2 6 5 4; 1 2 3 -> 1 3 2
An advantage of using a hash for the map is that I can use any string as an id. For example:
./ch-1.pl "Ana Beto Carlos David Elías" "Elías Carlos Ana"
Results:
Ana Beto Carlos David Elías; Elías Carlos Ana -> Ana Carlos Elías
Task 2: Trionic Array
Submitted by: Mohammad Sajid Anwar
You are given an array of integer.
Write a script to return true if the given array is Trionic
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
I compare consecutive elements. If any are equal, the result is false. If not, I count state changes, from initial to increasing to decreasing to increasing again. If there are additional or missing state changes, the result is false. Otherwise, it is true. The result fits a 3-liner.
Examples:
perl -E '
for(@ARGV){@x=split" ";$c=$d=$f=0;for(1..@x-1){$s=$x[$_-1]<=>$x[$_];
$f=1,last if (!$s||$c==0 && $s>0||$c==2&&$s>0);$c=1 if $d==0&&$s<0;$d=1
if $c==1&&$s>0;$c=2 if $d==1&&$s<0;}say "$_ -> ", ($f||$c<2)?"F":"T";}
' "1 3 5 4 2 6 8" "1 4 4 2 1 3 5" "2 10 3 1 9" \
"1 2 3 4 3 2 1" "1 3 6 4 2 7 8 4"
Results:
1 3 5 4 2 6 8 -> T
1 4 4 2 1 3 5 -> F
2 10 3 1 9 -> T
1 2 3 4 3 2 1 -> F
1 3 6 4 2 7 8 4 -> F
The full code is:
1 # Perl weekly challenge 396
2 # Task 2: Trionic Array
3 #
4 # See https://wlmb.github.io/2026/10/19/PWC396/#task-2-trionic-array
5 use v5.36;
6 die <<~"FIN" unless @ARGV;
7 Usage: $0 L0 L1...
8 to find if the space separated list Ln is trionic,
9 i.e., strictly increasing, decreasing and then increasing.
10 FIN
11 for(@ARGV){
12 my @arr = split " ";
13 my ($increasing, $decreasing, $failed) = (0, 0, 0);
14 for(1..@arr-1){
15 my $sign = $arr[$_-1] <=> $arr[$_];
16 $failed=1,last
17 if (!$sign # not strictly increasing or decreasing
18 || $increasing==0 && $sign > 0 # decreasing before increasing
19 || $increasing==2 && $sign > 0); # decreasing after increasing twice
20 $increasing = 1,next
21 if $decreasing == 0 && $sign < 0; # first increasing
22 $decreasing = 1,next
23 if $increasing==1 && $sign > 0; # first decreasing
24 $increasing = 2, next
25 if $decreasing == 1 && $sign<0; # second increasing
26 }
27 say "$_ -> ", ($failed || $increasing < 2)?"False":"True";
28 }
Examples:
./ch-2.pl "1 3 5 4 2 6 8" "1 4 4 2 1 3 5" "2 10 3 1 9" \
"1 2 3 4 3 2 1" "1 3 6 4 2 7 8 4"
Results:
1 3 5 4 2 6 8 -> True
1 4 4 2 1 3 5 -> False
2 10 3 1 9 -> True
1 2 3 4 3 2 1 -> False
1 3 6 4 2 7 8 4 -> False
/;