Perl Weekly Challenge #234 - Sharing is Caring
Hi everybody! Back this week with a (surprisingly long) solution to just Task 1 of the weekly challenge. Task 2 makes no sense to me at all because it seems like examples 1 and 3 disagree with each other. Just sticking to one challenge for that reason. Anyways, let's dive into it!
The goal here is to find the letters that all the provided words share. Here's the code:
#!/usr/bin/perl
use v5.36;
my @words;
my %result_chars;
for(@ARGV) {
push(@words, [split(//, $_)])
}
@words = sort {$#{$a} <=> $#{$b}} @words;
$result_chars{$_}++ for @{$words[0]};
for my $word (1..$#words) {
for my $key (keys(%result_chars)) {
my $occurrences = grep(/$key/, @{$words[$word]});
if($occurrences == 0) {
delete($result_chars{$key});
next;
} elsif($occurrences <= $result_chars{$key}) {
$result_chars{$key} = $occurrences;
}
}
}
for my $char (@{$words[0]}) {
if($result_chars{$char}) {
$result_chars{$char}--;
say $char;
}
}
First we make a 2D array of the characters in all the words. That way we only have to split the words up once, instead of repeatedly as we seek through them. It does mean a bit more complexity to deal with a matrix, unfortunately.
We also sort the words by length so the shortest one is first, then make a histogram of all the letters in it. Now it's important to keep all the letters and not remove duplicates, because we have to print duplicates as we see from the example that prints "e, l, l".
We loop through each word, then loop through each letter in the first word (keys of the histogram) and search the current word for that letter. If we don't find it, we delete the letter from the histogram. If we find fewer occurrences than in the histogram, we remove some from the histogram to show how many we actually can make in the current word. If that letter is in the histogram fewer or equal times to the occurrences in the word, we move on to the next letter.
Next, for printing, we would have to have multiple loops to loop through the histogram and remove one instance at a time, so instead I decided I should simply search the original word for characters that successfully passed the test of the other words, then print those characters.
When I first started, I thought this would be super easy, but I discovered complications numerous times through the challenge. Perhaps others will have some better ideas of solutions I can learn from. Unfortunately Flavio Poletti hasn't been doing his solutions recently, I always enjoyed them very much, but be sure to check out past solutions of his at github.polettix.it.
Hopefully I'll be back next week with more solutions!
Leave a comment