Perl Weekly Challenge 371.
My solutions (task 1 and task 2 ) to the The Weekly Challenge - 371.
Task 1: Missing Letter
Submitted by: Reinier Maliepaard
You are given a sequence of 5 lowercase letters, with one
letter replaced by ‘?’. Each letter maps to its position in
the alphabet (‘a = 1’, ‘b = 2’, …, ‘z = 26’). The sequence
follows a repeating pattern of step sizes between
consecutive letters. The pattern is either a constant step
(e.g., ‘+2, +2, +2, +2’) or a simple alternating pattern of
two distinct steps (e.g., ‘+2, +3, +2, +3’).
Example 1
Input: @seq = qw(a c ? g i)
Output: e
The pattern of the sequence is +2,+2,+2,+2.
1: a
3: c
5: e
7: g
9: i

Example 2
Input: @seq = qw(a d ? j m)
Output: g
The pattern of the sequence is +3,+3,+3,+3.
1: a
4: d
7: g
10: j
13: m

Example 3
Input: @seq = qw(a e ? m q)
Output: i
The pattern of the sequence is +4,+4,+4,+4.
1: a
5: e
9: i
13: m
17: q

Example 4
Input: @seq = qw(a c f ? k)
Output: h
The pattern of the sequence is +2,+3,+2,+3.
1: a
3: c
6: f
8: h
11: k

Example 5
Input: @seq = qw(b e g ? l)
Output: j
The pattern of the sequence is +3,+2,+3,+2.
2: b
5: e
7: g
10: j
12: l

The simple pattern, with spacing m, is a particular case of the alternating pattern, with spacings m and n. Assuming the input is well formed, I need two consecutive values to get both n and m. For example, if the question mark is at position 0, I can use the intervals between positions 1 and 2, and between positions 2 and 3, i.e., the intervals starting at 1 and at 2, as they are unrelated to the unknown element at 0. Similarly, if the question mark is at position 2, I could use the intervals 3-4 and 0-1. Notice that 0 and 3 have opposite parity, so they information yielded by the two intervals is not redundant. I make a small table to illustrate this.
| Position of ? | Interval 1 | Interval 2 |
|---|---|---|
| 0 | 1-2 | 2-3 |
| 1 | 2-3 | 3-4 |
| 2 | 3-4 | 0-1 |
| 3 | 0-1 | 1-2 |
| 4 | 1-2 | 2-3 |
Notice that in all cases, if the question mark is at position k, I can use the intervals starting at k+1 and k+2, both modulo 4. Finally, after finding both n and m I can reconstruct the character at position k from that at position k-1 or that at position k+1. This yields a 2-liner.
Examples:
perl -E '
for(@ARGV){/^(.*)\?.*$/;$k=length($1);@x=map{ord}split"";@s=map{$x[$_+1]-$x[$_]}
map{$_%4}($k+1,$k+2);say "$_ -> ", chr($k?$x[$k-1]+$s[0]:$x[$k+1]-$s[1]);}
' ac?gi ad?jm ae?mq acf?k beg?l
Results:
ac?gi -> e
ad?jm -> g
ae?mq -> i
acf?k -> h
beg?l -> j
For the full code I add a couple of tests.
1 # Perl weekly challenge 371
2 # Task 1: Missing Letter
3 #
4 # See https://wlmb.github.io/2026/04/27/PWC371/#task-1-missing-letter
5 use v5.36;
6 use feature qw(try);
7 die <<~"FIN" unless @ARGV;
8 Usage: $0 S0 S1...
9 to find the missing letter in string Sn.
10 The strings should contain four lower case English letters a-z and
11 exactly one question mark, and they should be compatible with
12 a simple or an alternating sequence.
13 FIN
14 my $length=5;
15 for(@ARGV){
16 try {
17 die "Wrong length: $_" unless length$_ == $length;
18 die "Only lowercase English letters or question marks allowed: $_" unless /^([a-z]|\?)*$/;
19 die "Expected only one question mark: $_" if /\?(.*)\?/;
20 die "Expected a question mark: $_" unless /^(.*)\?(.*)$/;
21 my $unknown = length($1);
22 my @codes = map{ord} split "";
23 my @separations = map{$codes[$_+1]-$codes[$_]}
24 map {$_% ($length-1)}
25 ($unknown+1, $unknown+2);
26 my @newcodes;
27 $newcodes[0] = $unknown?$codes[0]:$codes[1]-$separations[1];
28 @newcodes[$_]=$newcodes[$_-1] + $separations[($unknown+$_)%2] for 1..$length-1;
29 die "Replacement out of range: $_" unless ord("a") <= $newcodes[$unknown] <= ord("z");
30 my $newstring = join "", map {chr} @newcodes;
31 my $re=s/^(.*)\?(.*)$/$1.$2/r;
32 die "Inconsistent string: $_" unless $newstring=~/$re/;
33 say "$_ -> ", chr $newcodes[$unknown];
34 }
35 catch($e) { warn $e; }
36 }
Examples:
./ch-1.pl ac?gi ad?jm ae?mq acf?k beg?l
Results:
ac?gi -> e
ad?jm -> g
ae?mq -> i
acf?k -> h
beg?l -> j
Other examples:
./ch-1.pl 2>&1 abc a?c AB?DE a?c?e abcde ?abcd wxyz? ab?ef
Results:
Wrong length: abc at ./ch-1.pl line 18.
Wrong length: a?c at ./ch-1.pl line 18.
Only lowercase English letters or question marks allowed: AB?DE at ./ch-1.pl line 19.
Expected only one question mark: a?c?e at ./ch-1.pl line 20.
Expected a question mark: abcde at ./ch-1.pl line 21.
Replacement out of range: ?abcd at ./ch-1.pl line 30.
Replacement out of range: wxyz? at ./ch-1.pl line 30.
Inconsistent string: ab?ef at ./ch-1.pl line 33.
Task 2: Subset Equilibrium
Submitted by: Mohammad Sajid Anwar
You are given an array of numbers.
Write a script to find all proper subsets with more than one
element where the sum of elements equals the sum of their
indices.
Example 1
Input: @nums = (2, 1, 4, 3)
Output: (2, 1), (1, 4), (4, 3), (2, 3)
Subset 1: (2, 1)
Values: 2 + 1 = 3
Positions: 1 + 2 = 3
Subset 2: (1, 4)
Values: 1 + 4 = 5
Positions: 2 + 3 = 5
Subset 3: (4, 3)
Values: 4 + 3 = 7
Positions: 3 + 4 = 7
Subset 4: (2, 3)
Values: 2 + 3 = 5
Positions: 1 + 4 = 5

Example 2
Input: @nums = (3, 0, 3, 0)
Output: (3, 0), (3, 0, 3)
Subset 1: (3, 0)
Values: 3 + 0 = 3
Positions: 1 + 2 = 3
Subset 2: (3, 0, 3)
Values: 3 + 0 + 3 = 6
Positions: 1 + 2 + 3 = 6

Example 3
Input: @nums = (5, 1, 1, 1)
Output: (5, 1, 1)
Subset 1: (5, 1, 1)
Values: 5 + 1 + 1 = 7
Positions: 1 + 2 + 4 = 7

Example 4
Input: @nums = (3, -1, 4, 2)
Output: (3, 2), (3, -1, 4)
Subset 1: (3, 2)
Values: 3 + 2 = 5
Positions: 1 + 4 = 5
Subset 2: (3, -1, 4)
Values: 3 + (-1) + 4 = 6
Positions: 1 + 2 + 3 = 6

Example 5
Input: @nums = (10, 20, 30, 40)
Output: ()
The examples show that the same numbers at different
positions are to be considered as different set elements.
There is a small notational error in example 5 above, as it
seems to imply that the empty subset is the answer, while it is
meant that the set of answers is empty. This could be fixed
by using extra parenthesis in the answers of all the
previous examples.
I use subsets from Algorithm::Combinatorics to build
all proper subsets and I filter them to keep those that are
in equilibrium and have the appropriate length.
I also use sum from List::Util to
check the balance. The problem setup is based on one-based
arrays, so in Perl I have to add the number of indices to
the sum of indices. The result fits a two-liner.
Examples:
perl -MAlgorithm::Combinatorics=subsets -MList::Util=sum -E '
for(@ARGV){@d=split" ";@i=0..@d-1;@r=map{"[@d[@$_]]"}grep{1<@$_<@d
&&sum(@$_)+@$_==sum @d[@$_]}subsets(\@i);say"$_ -> [ @r ]";}
' -- "2 1 4 3" "3 0 3 0" "5 1 1 1" "3 -1 4 2" "10 20 30 40"
Results:
2 1 4 3 -> [ [4 3] [2 3] [1 4] [2 1] ]
3 0 3 0 -> [ [3 0 3] [3 0] ]
5 1 1 1 -> [ [5 1 1] ]
3 -1 4 2 -> [ [3 2] [3 -1 4] ]
10 20 30 40 -> [ ]
The full code is:
1 # Perl weekly challenge 371
2 # Task 2: Subset Equilibrium
3 #
4 # See https://wlmb.github.io/2026/04/27/PWC371/#task-2-subset-equilibrium
5 use v5.36;
6 use feature qw(try);
7 use Algorithm::Combinatorics qw(subsets);
8 use List::Util qw(all sum);
9 use Scalar::Util qw(looks_like_number);
10 die <<~"FIN" unless @ARGV;
11 Usage: $0 S0 S1...
12 to find the subsets of the space separated sets of numbers
13 Sn whose sum equal the sum of their indices (one-based).
14 FIN
15 for(@ARGV){
16 try {
17 my @numbers = split " ";
18 die "Expected space separated numbers: $_"
19 unless all {looks_like_number $_} @numbers;
20 my @indices = 0..@numbers-1;
21 my @results = map{
22 "[@numbers[@$_]]"
23 } grep {
24 1 < @$_ < @numbers #check length of subset
25 && sum(@$_)+@$_== sum @numbers[@$_] # check sums
26 }
27 subsets(\@indices);
28 say"$_ -> [ @results ]";
29 }
30 catch($e){ warn $e; }
31 }
Example:
./ch-2.pl "2 1 4 3" "3 0 3 0" "5 1 1 1" "3 -1 4 2" "10 20 30 40"
Results:
2 1 4 3 -> [ [4 3] [2 3] [1 4] [2 1] ]
3 0 3 0 -> [ [3 0 3] [3 0] ]
5 1 1 1 -> [ [5 1 1] ]
3 -1 4 2 -> [ [3 2] [3 -1 4] ]
10 20 30 40 -> [ ]
Notice that if large arrays are expected, then subsets
can be used as an iterator, to generate and process the
subsets one by one in a loop, instead of using grep and map.
/;