Perl Weekly Challenge 392.

My solutions (task 1 and task 2 ) to the The Weekly Challenge - 392.

Task 1: Convert Palindrome

Submitted by: Mohammad Sajid Anwar
You are given a string.

Write a script to convert the given string to palindrome by
adding characters in front of it.

Example 1
Input: $str = "pinnipeds"
Output: "sdepinnipeds"

Example 2
Input: $str = "abcd"
Output: "dcbabcd"

Example 3
Input: $str = "bananas"
Output: "sananabananas"

Example 4
Input: $str = "dissident"
Output: "tnedissident"

Example 5
Input: $str = "cailliachs"
Output: "shcailliachs"

A trivial solution is to prepend the full string reversed, but this would not yield the smallest solution. An optimal solution is to separate the string as ABCD where ABC is the largest leading palindrome, C is the reverse of A and B is a single middle letter or empty. A and C could be empty if there is no leading palindrome besides the first letter. Then the solution would be to prepend the reverse of D. I can use a single substitution using the (??{ *code*}) construction as it executes code within the given regular expression to build the actual regular expression to match. The code fits a one-liner, which I explain in the full code below.

Examples:

perl -E '
for(@ARGV){say "$_ -> ", s/^((.*)(.?)(??{"".reverse($2)}))(.*)$/reverse($4).$1.$4/re;}
' pinnipeds abcd bananas dissident cailliachs

Results:

pinnipeds -> sdepinnipeds
abcd -> dcbabcd
bananas -> sananabananas
dissident -> tnedissident
cailliachs -> shcailliachs

 1  # Perl weekly challenge 392
 2  # Task 1:  Convert Palindrome
 3  #
 4  # See https://wlmb.github.io/2026/09/20/PWC392/#task-1-convert-palindrome
 5  use v5.36;
 6  die <<~"FIN" unless @ARGV;
 7      Usage: $0 S0 S1...
 8      to find the smallest palindrome that may be obtained by
 9      prepending letters to the string Sn
10      FIN
11  for(@ARGV){
12      say "$_ -> ",
13          s/^               # start of string
14            (               # start of leading palindrome $1
15            (.*)            # first half of leading palindrome, maybe empty $2
16            (.?)            # middle letter, if any  $3
17            (??{            # start code
18             "".reverse($2) # build second half of palindrome
19                            # by reversing first half
20            })              # end of second half
21            )               # end of leading palindrome $1
22            (.*)            # remaining letters $4
23            $               # end of string
24        /reverse($4).$1.$4  #
25        /rex;               # return modified string, expressions in replacement, legible
26  }

Example:

./ch-1.pl pinnipeds abcd bananas dissident cailliachs

Results:

pinnipeds -> sdepinnipeds
abcd -> dcbabcd
bananas -> sananabananas
dissident -> tnedissident
cailliachs -> shcailliachs

Task 2: Words Length Product

Submitted by: Mohammad Sajid Anwar
You are given an array of strings.

Write a script to return the maximum value of
len($words[i]) * len($words[j]) where the two words do not
share common letters. If no such two words exist, return 0.

Example 1
Input: @words = ("a", "ab", "abc", "d", "de", "def")
Output: 9

Two words are "abc" and "def".

Example 2
Input: @words = ("a", "aa", "aaa", "aaaa")
Output: 0

Since no two words can be chosen without sharing letters,
the result is 0.

Example 3
Input: @words = ("meet", "app", "code", "sky", "bold")
Output: 16

Two words are "meet" and "bold".

Example 4
Input: @words = ("a", "ab", "abc", "abcd", "efghi")
Output: 20

Two words are "abcd" and "efghi".

Example 5
Input: @words = ("xyz", "w", "abcdefg", "hij")
Output: 21

Two words are "abcdefg" and "hij".

I assume the words are given in @ARGV as space separated strings. I build all pair of words, use one word of each pair to build a regular expression to check if it has any character in common with the other word, through away all words that do, multiply the lengths of the remaining words and find the maximum. I use map and grep to build and filter the pairs, and max from List::Util to get the maximum product. The result fits a 2-liner.

Examples:

perl -MList::Util=max -E '
for(@ARGV){@w=split" ";say"$_ -> ",max 0,map {($x,$y)=@$_;length($x)*length($y);}
grep{($x,$y)=@$_;$r=join"|",split"",$x;!($y=~m/$r/)}map {$w=$_; map {[$w,$_]} @w} @w;}
' "a ab abc d de def"  "a aa aaa aaaa"  "meet app code sky bold" \
  "a ab abc abcd efghi" "xyz w abcdefg hij"

Results:

a ab abc d de def -> 9
a aa aaa aaaa -> 0
meet app code sky bold -> 16
a ab abc abcd efghi -> 20
xyz w abcdefg hij -> 21

The full code is:

 1  # Perl weekly challenge 392
 2  # Task 2:  Words Length Product
 3  #
 4  # See https://wlmb.github.io/2026/09/20/PWC392/#task-2-words-length-product
 5  use v5.36;
 6  use List::Util qw(max);
 7  die <<~"FIN" unless @ARGV;
 8      Usage: $0 L0 L1...
 9      to find the maximum product of the lengths of
10      two words with no common letters taken from the space
11      separated lists Ln.
12      FIN
13  for(@ARGV){
14      my @words = split " ";                   # get list of words
15      say"$_ -> ",
16          max                                  # maximize
17          0,                                   # default value
18          map {                                # products of lengths
19              my ($x,$y) = @$_;
20              length($x)*length($y);
21          }
22          grep{
23              my ($x,$y) = @$_;
24              my $re = join "|", split "", $x; # i.e., convert abc to regular expression a|b|c
25              !($y =~ m/$re/)                  # match means letters in common, reject pair
26          }
27          map {                                # build pairs of words
28              my $w1 = $_;
29              map { [$w1, $_] } @words
30         } @words;
31  }

Examples:

./ch-2.pl "a ab abc d de def"  "a aa aaa aaaa"  "meet app code sky bold" \
          "a ab abc abcd efghi" "xyz w abcdefg hij"

Results:

a ab abc d de def -> 9
a aa aaa aaaa -> 0
meet app code sky bold -> 16
a ab abc abcd efghi -> 20
xyz w abcdefg hij -> 21

/;

Written on September 20, 2026