DEV Community

Simon Green
Simon Green

Posted on

The Weekly Challenge: The Common Beauty

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.

Challenge, My solutions

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)
Enter fullscreen mode Exit fullscreen mode

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}
Enter fullscreen mode Exit fullscreen mode

Finally, I return the length of the intersection of both sets.

    return len(unique1 & unique2)
Enter fullscreen mode Exit fullscreen mode

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 ) );
}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Top comments (1)

Collapse
 
simongreennet profile image
Simon Green

After submitting my solutions, I look at some other peoples solutions. Seems I messed an important edge case in the second task. If num is 1001 and k is 2, it would raise a division by zero error. Didn't think about that one.