Perl Weekly Challenge 316.

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

Task 1: Circular

Submitted by: Mohammad Sajid Anwar
You are given a list of words.

Write a script to find out whether the last character of each word is the
first character of the following word.


Example 1
Input: @list = ("perl", "loves", "scala")
Output: true

Example 2
Input: @list = ("love", "the", "programming")
Output: false

Example 3
Input: @list = ("java", "awk", "kotlin", "node.js")
Output: true

I join all words in a single space separated string. Then I look repeatedly for the pattern:

  • some letter,
  • a space,
  • the same letter

using a regular expression, in which I use a backreference to the first match \1 and use the /g modifier. If the number of matches is one less than the number of words, the result is True. This yields a one-liner.

Example 1:

perl -E '
@r=($x="@ARGV")=~/\w*(.)\s\1/g; say "@ARGV -> ", @r==@ARGV-1?"True":"False";
' perl loves scala

Results:

perl loves scala -> True

Example 2:

perl -E '
@r=($x="@ARGV")=~/\w*(.)\s\1/g; say "@ARGV -> ", @r==@ARGV-1?"True":"False";
' love the programming

Results:

love the programming -> False

Example 3:

perl -E '
@r=($x="@ARGV")=~/\w*(.)\s\1/g; say "@ARGV -> ", @r==@ARGV-1?"True":"False";
' java awk kotlin node.js

Results:

java awk kotlin node.js -> True

The full code is similar:

 1  # Perl weekly challenge 316
 2  # Task 1:  Circular
 3  #
 4  # See https://wlmb.github.io/2025/04/07/PWC316/#task-1-circular
 5  use v5.36;
 6  die <<~"FIN" unless @ARGV;
 7      Usage: $0 W1 W2...W_N
 8      to find if the last letter of the word W{n} coincides with the
 9      first letter of the word W{n+1} for n=1...N-1.
10      FIN
11  for(@ARGV){die "Expected single word: $_" unless /^\S+$/}
12  my @words=map{lc}@ARGV;     #normalize to lower case
13  my $all="@words";
14  my @matches=$all=~/(\w)\s\1/g;
15  my $results=(@matches==@words-1)?"True":"False";
16  say "@ARGV -> $results";

Example:

./ch-1.pl perl loves scala
./ch-1.pl love the programming
./ch-1.pl java awk kotlin node.js

Results:

perl loves scala -> True
love the programming -> False
java awk kotlin node.js -> True

Task 2: Subsequence

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

Write a script to find out if one string is a subsequence of another.

A subsequence of a string is a new string that is formed from the original string
by deleting some (can be none)  of the characters without disturbing the relative
positions of the remaining characters.

Example 1
Input: $str1 = "uvw", $str2 = "bcudvew"
Output: true

Example 2
Input: $str1 = "aec", $str2 = "abcde"
Output: false

Example 3
Input: $str1 = "sip", $str2 = "javascript"
Output: true

I build a regular expression that allows arbitrary characters between the actual characters of one string and use it to match the other string. The result fits a 1.5-liner.

perl -E '
for my ($x,$y)(@ARGV){say "$x $y -> ", f($x,$y)||f($y,$x)?"True":"False";}
sub f($x,$y){$r=join ".*",split "", $x; $y=~/$r/}
' uvw bcudvew aec abcde sip javascript

Results:

uvw bcudvew -> True
aec abcde -> False
sip javascript -> True

The corresponding full code is:

 1  # Perl weekly challenge 316
 2  # Task 2:  Subsequence
 3  #
 4  # See https://wlmb.github.io/2025/04/07/PWC316/#task-2-subsequence
 5  use v5.36;
 6  die <<~"FIN" unless @ARGV and @ARGV%2==0;
 7      Usage: $0 S11 S12 S21 S22...
 8      to find if the strings strings Sn1 are a subsecuence of Sn2 or viceversa
 9      FIN
10  for my ($x,$y)(@ARGV){
11      say "$x $y -> ", subsec($x,$y)||subsec($y,$x)?"True":"False";
12  }
13  sub subsec($x,$y){
14      my $re = join ".*", split "", $x;
15      $y=~/$re/;
16  }

Example:

./ch-2.pl uvw bcudvew aec abcde sip javascript

Results:

uvw bcudvew -> True
aec abcde -> False
sip javascript -> True

/;

Written on April 7, 2025