The Weekly Challenge 316

Chained Words & Subsequence Verification!

Original Challenge Link

Task 1: Circular

"Chain Reaction: Linking Words via Matching Boundaries!"

Determine if a list of words forms a chain where the last character of each word matches the first character of the next word.

The Strategy: Iterate through the list of words using a pair-wise comparison (current word and next word). For each pair, check if the substr(current, -1, 1) matches substr(next, 0, 1). In Python, this is cleanly done using zip(words, words[1:]) and all(). In Perl, a simple loop through the indices handles the check.
Perl Implementation
sub is_circular () {
    return 1 if @$words <= 1;
    for my $i ( 0 .. $#$words - 1 ) {
        my $a = $words->[$i];
        my $b = $words->[ $i + 1 ];
        return 0 if substr( $a, -1, 1 ) ne substr( $b, 0, 1 );
    }
    return 1;
}
Python Implementation
def is_circular(words: Sequence[str]) -> bool:
    if len(words) <= 1:
        return True
    return all(a[-1] == b[0] for a, b in zip(words, words[1:]))

Task 2: Subsequence

"Hidden Patterns: Detecting Subsequences within Strings!"

Check if one string is a subsequence of another, meaning it can be formed by deleting characters from the second string while maintaining the relative order of the remaining characters.

The Strategy: Use a single pointer to track our progress through the target subsequence string. Iterate through the characters of the source string; whenever we find a character that matches the one at our pointer's position in the subsequence, increment the pointer. If the pointer reaches the end of the subsequence string, we have successfully found all characters in order.
Perl Implementation
sub is_subsequence ($str1, $str2) {
    return 1 if $str1 eq '';
    my $i = 0;
    for my $ch ( split //, $str2 ) {
        my $want = substr( $str1, $i, 1 );
        if ( $ch eq $want ) {
            ++$i;
            return 1 if $i == length($str1);
        }
    }
    return 0;
}
Python Implementation
def is_subsequence(str1: str, str2: str) -> bool:
    if not str1:
        return True
    idx = 0
    for ch in str2:
        if ch == str1[idx]:
            idx += 1
            if idx == len(str1):
                return True
    return False