Perl Weekly Challenge 224: Special Notes
These are some answers to the Week 224, Task 1, of the Perl Weekly Challenge organized by Mohammad S. Anwar.
Spoiler Alert: This weekly challenge deadline is due in a few days from now (on July 9, 2023, at 23:59). This blog post offers some solutions to this challenge. Please don’t read on if you intend to complete the challenge on your own.
Task 1: Special Notes
You are given two strings, $source
and $target
.
Write a script to find out if using the characters (only once) from source, a target string can be created.
Example 1
Input: $source = "abc"
$target = "xyz"
Output: false
Example 2
Input: $source = "scriptinglanguage"
$target = "perl"
Output: true
Example 3
Input: $source = "aabbcc"
$target = "abc"
Output: true
This task is somewhat similar to the "Good String" task of week 221, and we'll use essentially the same methods.
Special Notes in Raku
We can store the input source characters in a Bag and use the ⊆ subset of or equal to operator, infix_%E2%8A%86) to figure out whether all letters of a word can be found in the input string. In this context, bags are clever enough to manage duplicates in the input characters and use input characters only once.
sub special-note ($source, $target) {
my $chars = $source.comb.Bag;
return $target.comb.Bag ⊆ $chars;
}
for ("abc", "xyz"), ("scriptinglanguage", "perl"),
("aabbcc", "abc") -> @test {
printf "%-20s - %-7s => ", "@test[0]", "@test[1]";
say special-note @test[0], @test[1];
}
This program displays the following output:
$ raku ./main.raku
abc - xyz => False
scriptinglanguage - perl => True
aabbcc - abc => True
Special Notes in Perl
Perl doesn't have Bags
and set operators, but we can use a hash as a letter histogram to the same effect, with a loop to check whether each letter of $target
word can be found in $source
string.
use strict;
use warnings;
use feature 'say';
sub special_note {
my ($source, $target) = @_;
my %chars;
$chars{$_}++ for split //, $source;
for my $let (split //, $target) {
return "false" unless $chars{$let};
$chars{$let}--;
}
return "true";
}
for my $test ([ "abc", "xyz"],
["scriptinglanguage", "perl"], ["aabbcc", "abc"] ) {
printf "%-20s - %-7s => ", "@$test[0]", "@$test[1]";
say special_note @$test[0], @$test[1];
}
_
This program displays the following output:
$ perl ./special-note.pl
abc - xyz => false
scriptinglanguage - perl => true
aabbcc - abc => true
Wrapping up
The next week Perl Weekly Challenge will start soon. If you want to participate in this challenge, please check https://perlweeklychallenge.org/ and make sure you answer the challenge before 23:59 BST (British summer time) on July 16, 2023. And, please, also spread the word about the Perl Weekly Challenge if you can.
Leave a comment