Weekly Challenge 375
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. Unless otherwise stated, Copilot (and other AI tools) have NOT been used to generate the solution. It's a great way for us all to practice some coding.
Task 1: Single Common Word
Task
You are given two array of strings.
Write a script to return the number of strings that appear exactly once in each of the two given arrays. String comparison is case sensitive.
My solution
For input from the command, I take two space separated strings to generate the two arrays.
For this task, I start by counting the frequency of words in each list (array in Perl).
from collections import Counter
def single_common_word(array1: list[str], array2: list[str]) -> int:
freq1 = Counter(array1)
freq2 = Counter(array2)
I then create two sets of words which only appear once in each list.
unique1 = {word for word in freq1 if freq1[word] == 1}
unique2 = {word for word in freq2 if freq2[word] == 1}
Finally, I return the length of the intersection of both sets.
return len(unique1 & unique2)
The Perl solution follows a similar logic. Using the scalar function will return the number of items in the array.
use Array::Utils 'intersect';
sub main ( $str1, $str2 ) {
my @array1 = split /\s+/, $str1;
my @array2 = split /\s+/, $str2;
my ( %freq1, %freq2 );
$freq1{$_}++ foreach @array1;
$freq2{$_}++ foreach @array2;
my @unique1 = grep { $freq1{$_} == 1 } keys %freq1;
my @unique2 = grep { $freq2{$_} == 1 } keys %freq2;
say scalar( intersect( @unique1, @unique2 ) );
}
Examples
$ ./ch-1.py "apple banana cherry" "banana cherry date"
2
$ ./ch-1.py "a ab abc" "a a ab abc"
2
$ ./ch-1.py "orange lemon" "grape melon"
0
$ ./ch-1.py "test test demo" "test demo demo"
0
$ ./ch-1.py "Hello world" "hello world"
1
Task 2: Find K-Beauty
Task
You are given a number and a digit k.
Write a script to find the K-Beauty of the given number. The K-Beauty of an integer number is defined as the number of substrings of given number when it is read as a string has length of k and is a divisor of given number.
My solution
This is relatively straight forward. Python treats integers and strings as different types (and methods that can be called). The first thing I do is convert num to a string called s.
def k_beauty(num: int, k: int) -> int:
s = str(num)
I then generate all possible substrings of length k and check if it is evenly divisible from the original number. If it is I increment the count variable. At the end, I return the final count value.
count = 0
for start in range(len(s) - k + 1):
if num % int(s[start:start+k]) == 0:
count += 1
return count
Perl doesn't care (most of the times) about integers vs strings. This makes the code a little more straight forward.
sub main ( $num, $k ) {
my $count = 0;
foreach my $start ( 0 .. length($num) - $k ) {
if ( $num % substr( $num, $start, $k ) == 0 ) {
++$count;
}
}
say $count;
}
Examples
$ ./ch-2.py 240 2
2
$ ./ch-2.py 1020 2
3
$ ./ch-2.py 444 2
0
$ ./ch-2.py 17 2
1
$ ./ch-2.py 123 1
2
Top comments (1)
After submitting my solutions, I look at some other peoples solutions. Seems I messed an important edge case in the second task. If
numis 1001 andkis 2, it would raise a division by zero error. Didn't think about that one.