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