Perl Weekly Challenge 278: Sort String

These are some answers to the Week 278, Task 1, of the Perl Weekly Challenge organized by Mohammad S. Anwar.

Spoiler Alert: This weekly challenge deadline is due in a few days from now (on July 21, 2024, at 23:59). This blog post provides some solutions to this challenge. Please don’t read on if you intend to complete the challenge on your own.

You are given a shuffle string, `\$str`.

Write a script to return the sorted string.

A string is shuffled by appending word position to each word.

Example 1

``````Input: \$str = "and2 Raku3 cousins5 Perl1 are4"
Output: "Perl and Raku are cousins"
``````

Example 2

``````Input: \$str = "guest6 Python1 most4 the3 popular5 is2 language7"
Output: "Python is the most popular guest language"
``````

Example 3

``````Input: \$str = "Challenge3 The1 Weekly2"
Output: "The Weekly Challenge"
``````

There are a number of ways this could go wrong with faulty input. We will not try to validate the input, and we will assume correct input.

Sort String in Raku

We first split the input string into space-separated words, using the words method. We then use a regex to capture separately the letters and the digits, and store the letters in the `@positions` array, at the index given by the digit part.

``````sub sort-string (\$in) {
my @positions;
for \$in.words -> \$word {
\$word ~~ m/(\D+)(\d+)/;
@positions[\$/[1]] = ~\$/[0];

}
return "@positions[1..@positions.end]";
}
my @tests = "and2 Raku3 cousins5 Perl1 are4",
"guest6 Python1 most4 the3 popular5 is2 language7",
"Challenge3 The1 Weekly2";
for @tests -> \$test {
say \$test;
say sort-string \$test;
say "";
}
``````

This program displays the following output:

``````\$ raku ./sort-sting.raku
and2 Raku3 cousins5 Perl1 are4
Perl and Raku are cousins

guest6 Python1 most4 the3 popular5 is2 language7
Python is the most popular guest language

Challenge3 The1 Weekly2
The Weekly Challenge
``````

Sort String in Perl

This is a port to Perl of the above Raku program. Here, the words are separated using the `split` built-in function. Then, we use regular expression captures to retrieve the alphabetical part and the numeric part, which are then stored into the `@positions` array.

``````use strict;
use warnings;
use feature 'say';

sub sort_string {
my @positions;
my @words = split /\s+/, shift;
for my \$word (@words) {
my (\$letters, \$digits) = (\$word =~ m/(\D+)(\d+)/);
\$positions[\$digits] = \$letters;

}
return "@positions[1..\$#positions]";
}
my @tests = ("and2 Raku3 cousins5 Perl1 are4",
"guest6 Python1 most4 the3 popular5 is2 language7",
"Challenge3 The1 Weekly2");
for my \$test (@tests) {
say \$test;
say sort_string \$test;
say "";
}
``````

This program displays the following output:

``````\$ perl  ./sort-sting.pl
and2 Raku3 cousins5 Perl1 are4
Perl and Raku are cousins

guest6 Python1 most4 the3 popular5 is2 language7
Python is the most popular guest language

Challenge3 The1 Weekly2
The Weekly Challenge
``````

Wrapping up

The next week Perl Weekly Challenge will start soon. If you want to participate in this challenge, please check https://perlweeklychallenge.org/ and make sure you answer the challenge before 23:59 BST (British summer time) on July 28, 2024. And, please, also spread the word about the Perl Weekly Challenge if you can.