Weekly Challenge 308
Each week Mohammad S. Anwar sends out The Weekly Challenge, a chance for all of us to come up with solutions to two weekly tasks. My solutions are written in Python first, and then converted to Perl. It's a great way for us all to practice some coding.
Task 1: Count Common
Task
You are given two array of strings, @str1
and @str2
.
Write a script to return the count of common strings in both arrays.
My solution
The tasks and examples don't mention what to do if a string appears more than once in both arrays. I've made the assumption that we only need to return it once.
For the command line input, I take two strings that are space separated as shown in the example.
In Python this is a one liner. I turn the lists into sets (which only has unique values) and take the length of the intersection of these two sets.
def count_common(str1: list, str2: list) -> int:
return len(set(str1) & set(str2))
Perl does not have sets or intersections built in. For the Perl solution, I turn both strings into a hash with the key being the strings. I then iterate through the keys of the first hash to see if they appear in the second hash. If they do, I increment the count
variable.
sub main (@inputs) {
my %str1 = map { $_, 1 } split( /\s+/, $inputs[0] );
my %str2 = map { $_, 1 } split( /\s+/, $inputs[1] );
my $count = 0;
foreach my $str ( keys %str1 ) {
$count++ if exists $str2{$str};
}
say $count;
}
Examples
$ ./ch-1.py "perl weekly challenge" "raku weekly challenge"
2
$ ./ch-1.py "perl raku java" "python java"
1
$ ./ch-1.py "guest contribution" "fun weekly challenge"
0
Task 2: Decode XOR
Task
You are given an encoded array and an initial integer.
Write a script to find the original array that produced the given encoded array. It was encoded such that encoded[i] = orig[i] XOR orig[i + 1]
.
My solution
This is relatively straight forward. For the command line input, I take the last value as the initial
integer, and the rest as the encoded
integers.
For this task, I create the orig
list (array in Perl) with the initial
value. I then iterate over each item in the encoded
list and takes the exclusive-or of it and the last value in the orig
list.
def decode_xor(encoded: list, initial: int) -> list:
orig = [initial]
for i in encoded:
orig.append(i ^ orig[-1])
return orig
Examples
$ ./ch-2.py 1 2 3 1
[1, 0, 2, 1]
$ ./ch-2.py 6 2 7 3 4
[4, 2, 0, 7, 4]
Top comments (1)
I prefer tools like map and grep to loops, b/c they are more concise.
my @str1 = qw ( perl weekly challenge perl);
my @str2 = qw ( raku challenge weekly raku);
@seen{@str1} = ();
@merged = (@str1, grep{!exists $seen{$_}} @str2);
print scalar @merged;
#6
#OR
my %saw;
my @out = grep( !$saw{$_}++, @str1, @str2);
print scalar @out;
#4