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:
- Create a hash for each word that counts occurrences of each character.
- Compare the keys of the first hash with the keys of subsequent hashes.
- 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:
- Start with the set of characters from the first word.
- 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:
- Convert the first word to a set of characters.
- 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.