Convert the Morse sequence to plain text.
To save efforts in typing the decoding table, we can use the %code
hash from Task 98, Text to Morse code, and create the ‘inversed’ hash, where the keys are the Morse sequences, and the values are letters or digits:
my %char = %code.kv.reverse;
Printing this variable shows its contents in the following way:
{- => t, -- => m, --- => o, ----- => 0, ----. => 9, ---.. => 8,
--. => g, --.- => q, --.. => z, --... => 7, -. => n, -.- => k,
-.-- => y, -.-. => c, -.. => d, -..- => x, -... => b, -.... => 6,
. => e, .- => a, .-- => w, .--- => j, .---- => 1,.--. => p,
.-. => r, .-.. => l, .. => i, ..- => u, ..--- => 2, ..-. => f,
... => s, ...- => v, ...-- => 3, .... => h, ....- => 4, ..... => 5}
Despite the fact that Perl 6’s output does not print quotes, all the keys and values in %char
are strings. The next step is to replace the sequences from the keys of the hash with its values. The small difficulty is that, unlike the text-to-Morse conversion, a regex has to search for the sequence of a few characters (dots and dashes), so it must anchor to the boundaries of the Morse characters.
The built-in <<
and >>
regex anchors for word boundaries assume that the words are sequences of letters and digits, while Morse sequences are dots and dashes. Let’s use a space to serve as a separating character. To simplify the task, just add an additional space to the string before decoding it.
my $text = prompt('Morse phrase> ') ~ ' ';
$text ~~ s:g/(<[.-]>+) ' '/%char{$0}/;
$text ~~ s:g/\s+/ /;
say $text;