The Weekly Challenge 318

Repeated Characters & Reversing Subarrays!

Original Challenge Link

Task 1: Group Position

"Triplet Tracker: Finding Long Consecutive Sequences!"

Identify all substrings of three or more consecutive identical letters in a given string.

The Strategy: Use a regular expression with a backreference to match any character followed by itself two or more times: (.){2,}. In Python, re.finditer extracts all such non-overlapping matches. In Perl, a global match //g combined with proper handling of capturing groups yields the desired substrings.
Perl Implementation
sub group_position ($str) {
    my @groups = ( $str =~ /((.){2,})/g );
    my @result;
    for ( my $i = 0; $i < @groups; $i += 2 ) {
        push @result, $groups[$i];
    }
    return \@result;
}
Python Implementation
def group_position(text: str) -> list[str]:
    return [match.group(0) for match in re.finditer(r"([a-z]){2,}", text)]

Task 2: Reverse Equals

"Mirror Magic: Matching Arrays via a Single Flip!"

Determine if one array can be made identical to another by reversing exactly one contiguous subarray.

The Strategy: First, handle the case where the arrays are already equal (reversing any 1-element subarray preserves equality). For unequal arrays, find the leftmost and rightmost indices where the elements differ. Reverse the subarray between these boundaries in the source array and check if the result matches the target.
Perl Implementation
sub reverse_equals ($source, $target) {
    my $left = 0;
    ++$left while $left < @$source && $source->[$left] == $target->[$left];
    return 1 if $left == @$source;

    my $right = $#$source;
    --$right while $right >= 0 && $source->[$right] == $target->[$right];

    my @candidate = @$source;
    @candidate[ $left .. $right ] = reverse @candidate[ $left .. $right ];
    return (join ',', @candidate) eq (join ',', @$target);
}
Python Implementation
def reverse_equals(source: Sequence[int], target: Sequence[int]) -> bool:
    if list(source) == list(target): return True
    left = 0
    while left < len(source) and source[left] == target[left]:
        left += 1
    right = len(source) - 1
    while right >= 0 and source[right] == target[right]:
        right -= 1
    candidate = list(source)
    candidate[left : right + 1] = reversed(candidate[left : right + 1])
    return candidate == list(target)