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
/;