# Perl Weekly Challenge 279.

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

``````Submitted by: Mohammad Sajid Anwar
You are given two arrays, @letters and @weights.

Write a script to sort the given array @letters based on the @weights.

Example 1
Input: @letters = ('R', 'E', 'P', 'L')
@weights = (3, 2, 1, 4)
Output: PERL
Example 2
Input: @letters = ('A', 'U', 'R', 'K')
@weights = (2, 4, 1, 3)
Output: RAKU
Example 3
Input: @letters = ('O', 'H', 'Y', 'N', 'P', 'T')
@weights = (5, 4, 2, 6, 1, 3)
Output: PYTHON
``````

I assume the inputs are a string of characters and a string with space separated numbers (they could be more than one digit long). I split both arguments, use `zip` from `List::Utils` to make a Schwartzian transform for sorting, i.e., I make arrays of the form `[string, number]`, sort according to `number` and extract `string`. The result fits a 1.5liner.

``````perl -Mexperimental=for_list -MList::Util=zip -E '
for my(\$l,\$n)(@ARGV){say "Letters: \$l, numbers: \$n -> ", join "", map {\$_->[0]}
sort {\$a->[1] <=> \$b->[1]} zip [split "", \$l], [split " ", \$n]}
' REPL "3 2 1 4" AURK "2 4 1 3" OHYNPT "5 4 2 6 1 3"
``````

Results:

``````Letters: REPL, numbers: 3 2 1 4 -> PERL
Letters: AURK, numbers: 2 4 1 3 -> RAKU
Letters: OHYNPT, numbers: 5 4 2 6 1 3 -> PYTHON
``````

The full code is similar but checks for special situations.

`````` 1  # Perl weekly challenge 279
2  # Task 1:  Sort Letters
3  #
5  use v5.36;
6  use experimental qw(for_list);
7  use List::Util qw(zip);
8  die <<~"FIN" unless @ARGV && @ARGV%2==0;
9      Usage: \$0 S1 N1 S2 N2...
10      to sort the characters of string Si according to the space-separated numbers Ni.
11      FIN
12  PAIRS:
13  for my(\$chars, \$numbers)(@ARGV){
14      my @chars = split "", \$chars;
15      my @numbers = split " ", \$numbers;
16      warn("Expected one number per char: chars: @chars, numbers: @numbers"), next PAIR
17          unless @chars == @numbers;
18      for(@numbers){warn("Only digits allowed: \$_"), next PAIR unless /^[\d\s]+\$/;}
19      my @schwartz=zip \@chars, \@numbers;
20      my \$out = join "", map {\$_->[0]} sort {\$a->[1] <=> \$b->[1] || \$a->[0] cmp \$b->[0]}
21                @schwartz;
22      say "chars: \$chars, numbers: \$numbers -> \$out";
23  }
24
``````

Example:

``````./ch-1.pl REPL "3 2 1 4" AURK "2 4 1 3" OHYNPT "5 4 2 6 1 3"
``````

Results:

``````chars: REPL, numbers: 3 2 1 4 -> PERL
chars: AURK, numbers: 2 4 1 3 -> RAKU
chars: OHYNPT, numbers: 5 4 2 6 1 3 -> PYTHON
``````

``````Submitted by: Mohammad Sajid Anwar
You are given a string, \$str.

Write a script to split the given string into two containing exactly same number
of vowels and return true if you can otherwise false.

Example 1
Input: \$str = "perl"
Ouput: false
Example 2
Input: \$str = "book"
Ouput: true

Two possible strings "bo" and "ok" containing exactly one vowel each.
Example 3
Input: \$str = "good morning"
Ouput: true

Two possible strings "good " and "morning" containing two vowels each or "good m"
and "orning" containing two vowels each.
``````

The result is true whenever the number of vowels is even. These would include the extreme cases of no vowels or no letters. I can use `tr` to count vowels, yielding a half-liner.

``````perl -E 'say "\$_ -> ", tr/aeiou//%2==0?"True":"False" for @ARGV' perl book "good morning"
``````

Results:

``````perl -> False
book -> True
good morning -> True
``````

The full code is similar:

`````` 1  # Perl weekly challenge 279
2  # Task 2:  Split String
3  #
5  use v5.36;
6  die <<~"FIN" unless @ARGV;
7      Usage: \$0 S1 S2...
8      to check if string Si may be split into strings with the same
9      number of vowels each.
10      FIN
11  say "\$_ -> ", tr/aeiou//%2==0?"True":"False" for(@ARGV)
12
``````

Example:

``````./ch-2.pl perl book "good morning"
``````

Results:

``````perl -> False
book -> True
good morning -> True
``````
Written on July 22, 2024