## Perl Weekly Challenge 245: Sort Language

These are some answers to the Week 245, 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 December 3, 2023 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 two arrays of languages and its popularity.

Write a script to sort the language based on popularity.

Example 1

``````Input: @lang = ('perl', 'c', 'python')
@popularity = (2, 1, 3)
Output: ('c', 'perl', 'python')
``````

Example 2

``````Input: @lang = ('c++', 'haskell', 'java')
@popularity = (1, 3, 2)
``````

### Sort Language in Raku

On reading the assignment, I initially thought for a minute or so that it would be quite easy to sort one array (`@lang`) in accordance with the values of another one (`@popularity`). But it immediately came to my mind that, in fact, you don't even need to actually sort anything. You can just use the second array (`@popularity`) as an index slice for the first one (`@lang`), so that we avoid the algorithmic complexity of a `sort` procedure and return directly the languages in the proper order. The `sort-lang` subroutine is thus a simple one-liner. Note that the input popularity is given with values starting at 1, whereas array or list indices start at 0, so we need the `map {\$_ - 1}` expression to convert popularities into array indices.

``````sub sort-lang (@lang, @pop) {
return ~ @lang[map {\$_ - 1}, @pop];
}

my @tests =
{ lang => <perl c python>, pop => (2, 1, 3)},
{ lang => <c++ haskell java>, pop  => (1, 3, 2)};

for @tests -> %test {
printf "%-20s", "%test<lang> => ";
say sort-lang %test<lang>, %test<pop>;
}
``````

This program displays the following output:

``````\$ raku ./sort-language.raku
perl c python =>    c perl python
``````

### Sort Language in Perl

This is a port to Perl of the Raku program above, and we are using array slices just like in the Raku implementation. Please refer to the previous section for any explanation.

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

sub sort_lang {
my @lang = @{\$_[0]};
my @pop  = @{\$_[1]};
return join " ",  @lang[map {\$_ - 1} @pop];
}

my @tests =
({ lang => [<perl c python>],    pop => [2, 1, 3]},
{ lang => [<c++ haskell java>], pop => [1, 3, 2]});

for my \$test (@tests) {
printf "%-22s", "@{\$test->{lang}} => ";
say sort_lang \$test->{lang}, \$test->{pop};
}
``````

This program displays the following output:

``````\$ perl ./sort-language.pl
perl c python =>      c perl python