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