Perl Weekly Challenge 233: Frequency Sort

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

You are given an array of integers.

Write a script to sort the given array in increasing order based on the frequency of the values. If multiple values have the same frequency then sort them in decreasing order.

Example 1

Input: @ints = (1,1,2,2,2,3)
Ouput: (3,1,1,2,2,2)

'3' has a frequency of 1
'1' has a frequency of 2
'2' has a frequency of 3

Example 2

Input: @ints = (2,3,1,3,2)
Ouput: (1,3,3,2,2)

'2' and '3' both have a frequency of 2, so they are sorted in decreasing order.

Example 3

Input: @ints = (-1,1,-6,4,5,-6,1,4,1)
Ouput: (5,-1,4,4,-6,-6,1,1,1)

Frequency Sort in Raku

We write a special-comp subroutine to implement the comparison logic to be used with the sort built-in function. An additional note: %*histo is a dynamic scope variable, which means it is seen and accessible in subroutines called by the routine where it is declared.

sub special-comp {
    return $^b <=> $^a if %*histo{$^a} == %*histo{$^b};
    return %*histo{$^a} <=> %*histo{$^b};
}

sub freq-sort (@in) {
    my %*histo;
    %*histo{$_}++ for @in;
    my @sorted = sort &special-comp, %*histo.keys;
    my @result = map { |($_ xx %*histo{$_})}, @sorted;
}

for <1 1 2 2 2 3>, <2 3 1 3 2>, 
    (-1,1,-6,4,5,-6,1,4,1) -> @test {
    printf "%-25s => ", "@test[]";
    say freq-sort @test;
}

This program displays the following output:

$ raku ./frequency-sort.raku
1 1 2 2 2 3               => [3 1 1 2 2 2]
2 3 1 3 2                 => [1 3 3 2 2]
-1 1 -6 4 5 -6 1 4 1      => [5 -1 4 4 -6 -6 1 1 1]

Please note that I am too late and have no time now to complete the Perl version of this program.

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 September 17, 2023. And, please, also spread the word about the Perl Weekly Challenge if you can.

Leave a comment

About laurent_r

user-pic I am the author of the "Think Perl 6" book (O'Reilly, 2017) and I blog about the Perl 5 and Raku programming languages.