DEV Community

Simon Green
Simon Green

Posted on

Weekly Challenge: The Second Sum

Weekly Challenge 378

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: Second Largest Digit

Task

You are given an alphanumeric string.

Write a script to find the second largest distinct digit in the given string. Return -1 if none found.

My solution

For this task I use a set called digits to store the digits found in the input_string. By using a set, duplicate digits are only counted once. If this set has at least two values (unique digits), I return the second higest number. If it is shorter, I return -1.

def second_largest_digit(input_string) -> int:
    digits = set(int(c) for c in input_string if c.isdigit())
    return sorted(digits)[-2] if len(digits) > 1 else -1
Enter fullscreen mode Exit fullscreen mode

As Perl does not have sets, I use a hash to achieve the same functionality.

sub main ($input_string) {
    my %digits = ();
    for my $char ( split //, $input_string ) {
        if ( $char =~ /[0-9]/ ) {
            $digits{$char} = 1;
        }
    }

    if ( scalar( keys(%digits) ) < 2 ) {
        say -1;
    }
    else {
        my @sorted_digits = sort { $a <=> $b } keys %digits;
        say $sorted_digits[-2];
    }
}
Enter fullscreen mode Exit fullscreen mode

Examples

$ ./ch-1.py aaaaa77777
-1

$ ./ch-1.py abcde
-1

$ ./ch-1.py 9zero8eight7seven9
8

$ ./ch-1.py xyz9876543210
8

$ ./ch-1.py 4abc4def2ghi8jkl2
4
Enter fullscreen mode Exit fullscreen mode

Task 2: Sum of Words

Task

You are given three strings consisting of lower case English letters a to j only. The letter value of a = 0, b = 1, c = 3, etc.

Write a script to find if sum of first two strings return the third string.

My solution

For this task I have a function called words_to_number that converts a word to an integer. It also checks that the word only contains the letters a to j. The ord function gives the integer representing the Unicode code point of that character. The letter a has the integer 97, while j is 106.

def word_to_number(word: str) -> int:
    if not re.search('^[a-j]+$', word):
        raise ValueError(f"String '{word}' contains invalid characters")

    number_string = "".join(str(ord(c) - ord('a')) for c in word)
    return int(number_string)
Enter fullscreen mode Exit fullscreen mode

The sum_of_words function simply checks if the math is valid.

def sum_of_words(str1, str2, str3) -> bool:
    return word_to_number(str1) + word_to_number(str2) == word_to_number(str3)
Enter fullscreen mode Exit fullscreen mode

The Perl code follows the same logic.

sub word_to_number($str) {
    if ( $str !~ /^[a-j]+$/ ) {
        die "String '$str' contains invalid characters\n";
    }

    my $number_string = join( "", map { ord($_) - ord('a') } split //, $str );
    return int($number_string);
}

sub main ( $str1, $str2, $str3 ) {
    say word_to_number($str1) + word_to_number($str2) == word_to_number($str3)
      ? 'true'
      : 'false';
}
Enter fullscreen mode Exit fullscreen mode

Examples

$ ./ch-2.py acb cba cdb
true

$ ./ch-2.py aab aac ad
true

$ ./ch-2.py bc je jg
false

$ ./ch-2.py a aaaa aa
true

$ ./ch-2.py c d h
false

$ ./ch-2.py gfi hbf bdhd
true
Enter fullscreen mode Exit fullscreen mode

Top comments (0)