Perl Weekly Challenge 278.

My solutions (task 1 and task 2 ) to the The Weekly Challenge - 278.

Task 1: Sort String

``````Submitted by: Mohammad Sajid Anwar
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"
``````

I split the input into word-number strings, split each into word and number parts using a regular expression, sort according to number and output the result (Schwartzian transform). This yields a one-liner.

Examples:

``````perl -E '
say"\$_ -> ",join" ",map {\$_->[0]}sort{\$a->[1]<=>\$b->[1]}map{/^(.+?)([0-9]+)\$/;[\$1,\$2]} split " " for @ARGV;
' \
"and2 Raku3 cousins5 Perl1 are4" \
"guest6 Python1 most4 the3 popular5 is2 language7" \
"Challenge3 The1 Weekly2"
``````

Results:

``````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
``````

I assumed there are no punctuation characters.

The full code makes a few checks, and sorts according to word if necessary.

`````` 1  # Perl weekly challenge 278
2  # Task 1:  Sort String
3  #
4  # See https://wlmb.github.io/2024/07/15/PWC278/#task-1-sort-string
5  use v5.36;
6  die <<~"FIN" unless @ARGV;
7      Usage: \$0 S1 S2...
8      Sort the strings S1 S2...
9      Each string is formed of space-separated word-number strings, i.e., a word concatenated to a
10      non-negative number giving its position.
11      FIN
12  for(@ARGV){
13      my @pair_strings=split " ", \$_;
14      my @pairs;
15      for(@pair_strings){
16  	/^(.+)?([0-9]+)\$/ or die "Expected WD where W are word characters and D are digits: \$_";
17  	push @pairs, [\$1, \$2];
18      }
19      my @sorted=map {\$_->[0]} sort {\$a->[1] <=> \$b->[1] || lc \$a->[0] cmp lc \$b->[0]} @pairs;
20      say "\$_ -> @sorted";
21  }
``````

Examples:

``````./ch-1.pl "and2 Raku3 cousins5 Perl1 are4" \
"guest6 Python1 most4 the3 popular5 is2 language7" \
"Challenge3 The1 Weekly2"
``````

Results:

``````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
``````

Task 2: Reverse Word

``````Submitted by: Mohammad Sajid Anwar
You are given a word, \$word and a character, \$char.

Write a script to replace the substring up to and including \$char with its characters
sorted alphabetically. If the \$char doesn’t exist then DON'T do anything.

Example 1
Input: \$str = "challenge", \$char = "e"
Ouput: "acehllnge"
Example 2
Input: \$str = "programming", \$char = "a"
Ouput: "agoprrmming"
Example 3
Input: \$str = "champion", \$char = "b"
Ouput: "champion"
``````

I can split the word into the before and after parts, split the before characters, sort them and join them. The code fits a one-liner.

Examples:

``````perl -Mexperimental=for_list -E '
for my(\$s, \$c)(@ARGV){say "\$s \$c -> ", \$s=~/^(.*?\$c)(.*)\$/?join("",sort{\$a cmp \$b}split"",\$1).\$2:\$s}
' challenge e programming a champion b
``````

Results:

``````challenge e -> acehllnge
programming a -> agoprrmming
champion b -> champion
``````

The full code

`````` 1  # Perl weekly challenge 278
2  # Task 2:  Reverse Word
3  #
4  # See https://wlmb.github.io/2024/07/15/PWC278/#task-2-reverse-word
5  use v5.36;
6  use experimental qw(for_list);
7  die <<~"FIN" unless @ARGV and @ARGV%2==0;
8      Usage: \$0 S1 C1 S2 C2...
9      to sort the characters of each string Si upto the character Ci
10      FIN
11  for my(\$string, \$char)(@ARGV){
12      warn "Expected a single character: \$char" unless length \$char == 1;
13      my \$out=\$string =~ /^(.*?\$char)(.*)\$/
14  	? join("", sort{\$a cmp \$b} split "", \$1) . \$2
15          : \$string;
16      say "\$string \$char -> \$out"
17  }
``````

Example:

``````./ch-2.pl challenge e programming a champion b
``````

Results:

``````challenge e -> acehllnge
programming a -> agoprrmming
champion b -> champion
``````

/;

Written on July 15, 2024