Weekly Challenge 364
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: Decrypt String
Task
You are given a string formed by digits and #. Write a script to map the given string to English lowercase characters following the given rules.
- Characters
atoiare represented by1to9respectively. - Characters
jtozare represented by10#to26#respectively.
My solution
This task calls for regular expressions to be used. Both Python and Perl allow call back functions in the replacement section (i.e. you can call a function to find the new string).
For the Python solution, I have a (callback) function called replace_digits. It takes a Match object as input and returns a string.
def replace_digits(m: re.Match) -> str:
c = m.group(0)
return chr(96 + int(c[:2]))
The variable c has the matching string (either a single digit or two digits (10-26) followed by a hash character. Things to note:
-
c[:2]will remove the hash if it is present. -
int(...)will convert this into a number -
chr(...)will turn this into a letter of the alphabet. The ASCII code for the letterais97.
The main function checks that the input is valid. It then uses re.sub to perform the substitution in the replace_digits function.
def decrypt_string(input_string: str) -> str:
if not re.search(r'^(1\d#|2[0-6]#|\d)*$', input_string):
raise ValueError("String not in expected format")
return re.sub(r'(1\d#|2[0-6]#|\d)', replace_digits, input_string)
The Perl solution follows the same logic, except that the replacement value can be code (not just a function call). This negates the need for a separate function. The substr function is used to remove the hash character.
sub main ($input_string) {
if ( $input_string !~ /^(1\d#|2[0-6]#|\d)*$/ ) {
die "String not in expected format\n";
}
my $output_string = $input_string;
$output_string =~ s/(1\d#|2[0-6]#|\d)/chr(96 + substr($1,0,2))/eg;
say $output_string;
}
In the regular expression, /e indicates that the replacement value is a expression (as opposed to the literal string), and /g means to run the regular expression globally (on all occurrences).
Examples
$ ./ch-1.py 10#11#12
jkab
$ ./ch-1.py 1326#
acz
$ ./ch-1.py 25#24#123
yxabc
$ ./ch-1.py 20#5
te
$ ./ch-1.py 1910#26#
aijz
Task 2: Goal Parser
Task
You are given a string, $str.
Write a script to interpret the given string using Goal Parser. The Goal Parser interprets G as the string G, () as the string o, and (al) as the string al. The interpreted strings are then concatenated in the original order.
My solution
For this task, I use a regular expression to check that the input_string is in the expected format. I then use the replace function to change the string to the required output.
def good_parser(input_string: str) -> str:
if not re.search(r'^(G|\(\)|\(al\))*$', input_string):
raise ValueError("Unexpected input received")
return input_string.replace('()', 'o').replace('(al)', 'al')
Perl doesn't have a replace function, so I use a regular expression to perform the replacement.
sub main ($input_string) {
if ($input_string !~ /^(G|\(\)|\(al\))*$/) {
die "Unexpected input received\n;"
}
my $output_string = $input_string;
$output_string =~s/\(\)/o/g;
$output_string =~ s/\(al\)/al/g;
say $output_string;
}
Examples
Parentheses have special meaning in bash, so quotes are used to handle this.
$ ./ch-2.pl "G()(al)"
Goal
$ ./ch-2.pl "G()()()()(al)"
Gooooal
$ ./ch-2.pl "(al)G(al)()()"
alGaloo
$ ./ch-2.pl "()G()G"
oGoG
$ ./ch-2.pl "(al)(al)G()()"
alalGoo
Top comments (0)