25 April 2025 | Challenge 318 |
Reverse Groups
Task 1: Group Position
Submitted by: Mohammad Sajid Anwar
You are given a string of lowercase letters.
Write a script to find the position of all groups in the given string. Three or more consecutive letters form a group. Return ""
if none found.
Example 1
Input: $str = "abccccd"
Output: "cccc"
Example 2
Input: $str = "aaabcddddeefff"
Output: "aaa", "dddd", "fff"
Example 3
Input: $str = "abcdd"
Output: ""
Solution
A group may be identified with the regex (.)\1{2,}
as a single character followed by itself two or more times.
To capture the whole group, one additional capturing group is necessary around this expression, but we are interested in the first capture only.
To hide the second capturing group, it can be embedded in a
“postponed” regular subexpression as (??{...})
.
Thus the list of all groups is the result of a global match in list context with
/((??{qr{(.)\1{2,}}}))/g
leading to such an implementation:
use v5.14;
use warnings;
say '"' . join('", "', group_position(shift)) . '"';
sub group_position {
shift =~ /((??{qr{(.)\1{2,}}}))/g;
}
See the full solution to task 1.
Task 2: Reverse Equals
Submitted by: Roger Bell West
You are given two arrays of integers, each containing the same elements as the other.
Write a script to return true if one array can be made to equal the other by reversing exactly one contiguous subarray.
Example 1
Input: @source = (3, 2, 1, 4)
@target = (1, 2, 3, 4)
Output: true
Reverse elements: 0-2
Example 2
Input: @source = (1, 3, 4)
@target = (4, 1, 3)
Output: false
Example 3
Input: @source = (2)
@target = (2)
Output: true
Solution
Source and target can be split into three (possibly empty) subarrays: a prefix and a suffix of equal elements and an infix where at least the first and last element differ. This infix needs to be reversed in source and target to satisfy the condition in this task.
There is an edge case where infix (and suffix) are empty and thus the lists are equal.
We find the indices of all elements that differ between source and target. The infix consists of the subarray that extends from the first to the last found index.
use v5.14;
use warnings;
use PDL;
use PDL::NiceSlice;
say +(qw(true false))[!reverse_equals(@ARGV)];
sub reverse_equals {
my ($s, $t) = map long($_), @_;
my $ne = which $s != $t;
$ne->isempty || all $s($ne(-1):$ne(0)) == $t($ne(0):$ne(-1));
}
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.