11 April 2025 | Challenge 316 |
Regular Sequences
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
Solution
Though the task description from task 1 in week 314 is quite different from this task, there is a very similar solution.
Quoting my post for challenge 314, the solution to this task…
…may be found with a single regex. To this end we join the strings with a character not contained in any of the strings. For simplicity this will be the newline character
"\n"
in the following, which will not be matched by thedot
metacharacter.
The last character of a word may be captured with .*+(?<=(.))
.
The the beginning of following word starting with this captured character will be matched with
\n(?=\1)
.
A complete word chain is then matched by /^(?:.*+(?<=(.))\n(?=\1))*+.*+$/
.
The usage of “possessive” quantifiers suppresses backtracking in case of a failing match.
use strict;
use warnings;
sub circular {
join("\n", @_) =~ /^(?:.*+(?<=(.))\n(?=\1))*+.*+$/;
}
See the full solution to task 1.
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
Solution
Each character in $str1
will be quoted if it represents a regex meta-character and may be followed by zero or more other characters.
$str2
is then matched against the result of the first step.
use strict;
use warnings;
use experimental 'signatures';
sub subsequence ($str1, $str2) {
$str2 =~ ($str1 =~ s/./\Q$&\E.*/gr);
}
See the full solution to task 2.
If you have a question about this post or if you like to comment on it, feel free to open an issue in my github repository.