Weekly Challenge 358
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: Max Str Value
Task
You are given an array of alphanumeric string, @strings.
Write a script to find the max value of alphanumeric string in the given array. The numeric representation of the string, if it comprises of digits only otherwise length of the string.
My solution
This task can be achieved in a single line in both Python and Perl, while still maintaining readability. For the Python solution I use list comprehension to convert each string into an integer (if it is all digits) or the length of string (if it isn't). This is wrapped around the max function to return maximum (largest) of these values.
def max_string_value(input_strings: list) -> int:
return max(int(s) if s.isdigit() else len(s) for s in input_strings)
Not to out-shinned, Perl can achieve similar functionality by using the map function, converting each string into its numeric representation or its length. Perl doesn't have a built-in max function, but it is available from the List::Util package.
sub main (@input_strings) {
say max( map { /^\d+$/ ? $_ : length($_) } @input_strings );
}
Examples
$ ./ch-1.py "123" "45" "6"
123
$ ./ch-1.py "abc" "de" "fghi"
4
$ ./ch-1.py "0012" "99" "a1b2c"
99
$ ./ch-1.py "x" "10" "xyz" "007"
10
$ ./ch-1.py "hello123" "2026" "perl"
2026
Task 2: Encrypted String
Task
You are given a string $str and an integer $int.
Write a script to encrypt the string using the algorithm - for each character $char in $str, replace $char with the $int th character after $char in the alphabet, wrapping if needed and return the encrypted string.
My solution
For this task, I start by setting $int (called i in Python as int is a reserved word) to be the modulus (remainder) of 26. If that value is 0, I return the original string as no encryption is required.
def encrypted_string(input_string: str, i: int) -> str:
i = i % 26
if i == 0:
return input_string
The next step is creating a mapping table. I start with the variable old_letters that has all the lower case letters of the English alphabet. I create a new_letters string by slicing the old_letters string at the appropriate point. I then double the length of each string by adding the upper case equivalent string. Finally, I use dict(zip()) to convert the strings to a dictionary where the key is the original letter and the value is the new letter.
old_letters = string.ascii_lowercase
new_letters = old_letters[i:] + old_letters[:i]
old_letters += old_letters.upper()
new_letters += new_letters.upper()
mapping = dict(zip(old_letters, new_letters))
The final step is to loop through each character and use the mapping dictionary to replace the letter, or use the original character if it is not found (numbers, spaces, punctuation characters, etc).
return "".join(mapping.get(char, char) for char in input_string)
The Perl code follows the same logic. It uses the splice method to create the new_letters variable, and both old_letters and new_letters are arrays. The mesh function also comes from the List::Util package. Perl will automatically convert a flat list to key/value pairs in the mapping hash.
sub main ( $input_string, $i ) {
$i %= 26;
if ( $i == 0 ) {
say $input_string;
return;
}
my @old_letters = my @new_letters = ( "a" .. "z" );
push @new_letters, splice( @new_letters, 0, $i );
push @old_letters, map { uc } @old_letters;
push @new_letters, map { uc } @new_letters;
my %mapping = mesh \@old_letters, \@new_letters;
say join "", map { $mapping{$_} // $_ } split //, $input_string;
Examples
$ ./ch-2.py abc 1
bcd
$ ./ch-2.py xyz 2
zab
$ ./ch-2.py abc 27
bcd
$ ./ch-2.py hello 5
mjqqt
$ ./ch-2.py perl 26
perl
Top comments (0)