Perl Weekly Challenge: Week 358

Challenge 1:

Max Str Value

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.

Example 1
Input: @strings = ("123", "45", "6")
Output: 123

"123" -> 123
"45"  -> 45
"6"   -> 6
Example 2
Input: @strings = ("abc", "de", "fghi")
Output: 4

"abc"  -> 3
"de"   -> 2
"fghi" -> 4
Example 3
Input: @strings = ("0012", "99", "a1b2c")
Output: 99

"0012"  -> 12
"99"    -> 99
"a1b2c" -> 5
Example 4
Input: @strings = ("x", "10", "xyz", "007")
Output: 10

"x"   -> 1
"xyz" -> 3
"007" -> 7
"10"  -> 10
Example 5
Input: @strings = ("hello123", "2026", "perl")
Output: 2026

"hello123" -> 8
"perl"     -> 4
"2026"     -> 2026

This one is quite simple really.

We store the strings and their computed values in a hash.

my %vals;

For each string, if it contains only digits (ascertained with .match() and a regular expression,) we store it into a hash as a number with .Int or if it contains non-digit characters, we find it's length with .chars() and store that.

for @strings -> $str {
    %vals{$str} = $str.match(/^ <(\d+)> $/) ?? $str.Int !! $str.chars;
}

Finally we .sort() the .values() of the hash in ascending numeric order and find the maximum one (i.e. the last value,) with .tail() and print it out with .say().

%vals.values.sort({$^a <=> $^b}).tail.say;

(Full code on Github.)

The Perl version mainly followe Raku except...

my %vals;

for my $str (@strings) {
    $vals{$str} = $str =~ /^\d+$/ ? $str : length $str;
}

...in lieu of .tail() we take the -1st index of the sorted list of values and before using `say() we have to prefix the result with 0 to repress a warning.

say 0+(sort { $a <=> $b } values %vals)[-1];

(Full code on Github.)

Challenge 2:

Encrypted String

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 $intth character after $char in the alphabet, wrapping if needed and return the encrypted string.

Example 1
Input: $str = "abc", $int = 1
Output: "bcd"
Example 2
Input: $str = "xyz", $int = 2
Output: "zab"
Example 3
Input: $str = "abc", $int = 27
Output: "bcd"
Example 4
Input: $str = "hello", $int = 5
Output: "mjqqt"
Example 5
Input: $str = "perl", $int = 26
Output: "perl"

Another easy one. In fact, we can do it in Raku in one line.

The first command-line argument is the string. It is split into single characters with .comb(). Then for each character (using .map(),) we find its ordinal value with .ord() and subtract it from the ordinal value of 'a' which will give us the position of the character in the alphabet. To that, we add the second command-line argument (the integer) modulo 26. This amount is added to the ordinal value of 'a' and we now have the ordinal value of the rotated character. This is converted back into a character with .chr(). All the rotated characters are .join()ed back into a string which is printed out with .say().

@*ARGS[0].comb.map({ ("a".ord + ($_.ord - "a".ord + @*ARGS[1]) % 26).chr} ).join.say

(Full code on Github.)

The Perl version is also a one-liner and only slightly longer than the Raku version. It works in exactly the same way.

say join q{}, map{ chr(ord("a") + (ord($_) - ord("a") + $ARGV[1]) %26) } split //,$ARGV[0]

(Full code on Github.)