I’ve been doing the Weekly
Challenges. The
latest
involved various sorts of string parsing. (Note that this ends today.)
Task 1: Decrypt String
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.
Probably the more Perlish approach would involve regular expressions,
but stepping through a list of characters works well/
sub decryptstring($a) {
Initialise output string.
my $out = "";
Create character list.
my @c = split '',$a;
Step to first character of the string.
my $s = 0;
while ($s < scalar @c) {
Every valid cluster starts with a digit.
my $m = $c[$s];
If the string is long enough, and two characters ahead is a #, it's a
digit-digit-hash sequence.
if ($s + 2 < scalar @c && $c[$s + 2] eq '#') {
So extract the next digit and calculate the value.
$m = $m * 10 + $c[$s + 1];
And step two characters ahead.
$s += 2;
}
In any case, always step one character ahead.
$s++;
We have an output value, so convert it into a character and append it
to the output string.
$out .= chr(96 + $m);
}
Return the output string.
$out;
}
Task 2: Goal Parser
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.
This is similarly a parser for variable-length tokens. (If I were
doing this Seriously, I'd be very tempted to use the winnow parsing
library for Rust.)
Since it's easy to do so, if the string does not match one of the
three valid character groups, the function returns an empty string.
Scala:
def goalparser(a: String): String = {
Set up output string.
var out = ""
Step to first character of the input string.
var s = 0
while (s < a.length) {
For each possible sequence, if we see it at the current point, append
the translated value to the output and step the character index
forwards.
if (a.substring(s).startsWith("G")) {
s += 1
out += "G"
} else if (a.substring(s).startsWith("()")) {
s += 2
out += "o"
} else if (a.substring(s).startsWith("(al)")) {
s += 4
out += "al"
If we didn't see one of the three possible sequences, return an empty
string.
} else {
s = a.length
out = ""
}
}
out
}
Full code on
codeberg.