Weekly Challenge 380
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: Sum of Frequencies
Task
You are given a string consisting of English letters.
Write a script to find the vowel and consonant with maximum frequency. Return the sum of two frequencies.
My solution
I start this task by creating a frequency dict (hash in Perl) called freq using the Counter function from the collections module. I create two variables max_vowels and max_consonants with both set to zero.
I loop through the freq dict, and update the one of the maximum variables if it is larger than the existing value. I finish by returning the sum of these two variables.
from collections import Counter
def sum_of_frequencies(input_string: str) -> int:
freq = Counter(input_string.lower())
max_vowels = 0
max_consonants = 0
for letter, count in freq.items():
if letter in {"a", "e", "i", "o", "u"}:
if count > max_vowels:
max_vowels = count
else:
if count > max_consonants:
max_consonants = count
return max_vowels + max_consonants
As Perl does not have an equivalent of the Counter function, I create the freq hash manually. The rest of the code follows the same logic.
sub main ($input_string) {
my %freq = ();
$freq{$_}++ foreach ( split //, $input_string );
my $max_vowels = 0;
my $max_consonants = 0;
while ( my ( $letter, $count ) = each %freq ) {
if ( index( "aeiou", $letter ) != -1 ) {
if ( $count > $max_vowels ) {
$max_vowels = $count;
}
}
else {
if ( $count > $max_consonants ) {
$max_consonants = $count;
}
}
}
say $max_vowels + $max_consonants;
}
Examples
$ ./ch-1.py banana
5
$ ./ch-1.py teestett
7
$ ./ch-1.py aeiouuaa
3
$ ./ch-1.py rhythm
2
$ ./ch-1.py x
1
Task 2: Reverse Degree
Task
You are given a string.
Write a script to find the reverse degree of the given string.
For each character, multiply its position in the reversed alphabet (a = 26, b = 25, …, z = 1) with its position in the string. Sum these products for all characters in the string to get the reverse degree.
My solution
Both Python and Perl has the ord function which returns the integer Unicode code point value to for the supplied character. For the lower case English alphabet, 97 is a while 122 is the letter z.
For this task, I start by checking that the supplied string only contains English letters.
import re
def reverse_degree(input_string: str) -> int:
if not re.search("^[a-zA-Z]*$", input_string):
raise ValueError("String must only contain English letters")
I then generate a list (array in Perl) called number that has the revered alphabet number of each letter in input_string. Rather than relying on the character after z in the ASCII table being {, I use ord("z") + 1 to get the correct values.
numbers = [ord("z") - ord(char) + 1 for char in input_string.lower()]
Finally I use the sum function and list comprehension to compute the correct number.
return sum(number * pos for number, pos in enumerate(numbers, start=1))
The Perl solution is similar. To compute the correct number, I use the pre-increment operator ++$pos and the map function. The map function is also used to generate the numbers array.
use List::Util 'sum';
sub main ($input_string) {
if ( $input_string !~ /^[a-zA-Z]*$/ ) {
die "String must only contain English letters\n";
}
my @numbers = map { ord("z") - ord($_) + 1 } split //, lc $input_string;
my $pos = 0;
say sum( map { $_ * ++$pos } @numbers );
}
Examples
$ ./ch-2.py z
1
$ ./ch-2.py a
26
$ ./ch-2.py bbc
147
$ ./ch-2.py racecar
560
$ ./ch-2.py zyx
14
Top comments (0)