THE WEEKLY CHALLENGE - 234

https://theweeklychallenge.org/blog/perl-weekly-challenge-234/

Table of Contents

Task 1 - Common Characters

Blog Entry: Finding Common Characters in Words

Introduction

Finding common characters across multiple strings is a classic problem in the realm of string manipulation. While it might seem straightforward, this task can be a fun exercise, especially when we need to consider all words and not just a pair. In this article, we delve into solutions in Perl, Python, and Raku.

Problem Statement

Given an array of words made up of alphabetic characters only, return all alphabetic characters that show up in all words.

Perl Solution

In Perl, we can make efficient use of hashes to emulate set-like behavior:

  1. Create a hash for each word that counts occurrences of each character.
  2. Compare the keys of the first hash with the keys of subsequent hashes.
  3. If a character is in all hashes, it's a common character.
use strict;
use warnings;
use List::Util qw(all);

sub common_characters {
    my @words = @_;

    # Count characters for each word
    my @char_counts;
    for my $word (@words) {
        my %count;
        $count{$_}++ for split //, $word;
        push @char_counts, \%count;
    }

    # Find common characters
    my @common_chars;
    for my $char (keys %{$char_counts[0]}) {
        if (all { exists $_->{$char} } @char_counts) {
            push @common_chars, $char;
        }
    }

    return @common_chars;
}

Python Solution

Python's built-in set type makes this task quite concise:

  1. Start with the set of characters from the first word.
  2. Intersect this set with the set of characters from each subsequent word.
def common_characters(words: List[str]) -> List[str]:
    """
    Returns a list of characters that appear in all the given words.
    """
    # Start with the set of characters from the first word
    common_chars = set(words[0])

    # Intersect with other words
    for word in words[1:]:
        common_chars &= set(word)

    return list(common_chars)

Raku Solution

Raku, with its expressive syntax, provides a simple way to handle this problem using sets:

  1. Convert the first word to a set of characters.
  2. For each subsequent word, intersect this set with the set of characters from the word.
sub common-characters(@words) {
    # Convert the first word into a set of characters
    my $common-set = @words[0].comb.Set;

    # Intersect with other words
    for @words[1..*] -> $word {
        $common-set ∩= $word.comb.Set;
    }

    return $common-set.keys;
}

Conclusion

Finding common characters across strings is a practical task that can be approached in multiple ways. Whether using hashes in Perl, sets in Python, or Raku's expressive syntax, the core idea remains: intersect character collections from all words to determine the common characters. As we've seen, each language offers unique tools that can make this process both efficient and readable.


Task 2 - Unequal Triplets