Perl Weekly Challenge 276: Maximum Frequency

These are some answers to the Week 276, Task 2, 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 July 7, 2024 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.

Task 2: Maximum Frequency

You are given an array of positive integers, @ints.

Write a script to return the total number of elements in the given array which have the highest frequency.

Example 1

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

The maximum frequency is 2.
The elements 1 and 2 has the maximum frequency.

Example 2

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

The maximum frequency is 1.
The elements 1, 2, 3, 4 and 5 has the maximum frequency.

Maximum Frequency in Raku

We use a Bag to store the frequencies. This is very simple because we just need to coerce the input array to a Bag in order to compute the various frequencies. Then, we compute the maximum frequency and finally count the items whose frequency is equal to the maximum frequency.

sub max-frequency (@in) {
    my $frequencies = @in.Bag;
    my $max = $frequencies.values.max;
    my $count = 0;
    for $frequencies.keys -> $i {
        $count += $max if $frequencies{$i} == $max;
    }
    return $count;
}

my @tests = (1, 2, 2, 4, 1, 5), (1, 2, 3, 4, 5);
for @tests -> @test {
    printf "%-15s => ", "@test[]";
    say max-frequency @test;
}

This program displays the following output:

$  raku ./max-frequency.raku
1 2 2 4 1 5     => 4
1 2 3 4 5       => 5

Maximum Frequency in Perl

This is a port to Perl of the above Raku program. Perl having no Bags, we use a hash instead, but we need an explicit for loop to compute the frequencies and populate the %frequencies hash. Similarly, we need a for loop to compute the maximum frequency.

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

sub max_frequency {
    my %frequencies;
    for my $i (@_) {
        $frequencies{$i}++;
    }                                                                                                                       `
    my $max = 0;
    for my $i (values %frequencies) {
        $max = $i if $i > $max;
    }
    my $count = 0;
    for my $i (keys %frequencies) {
        $count += $max if $frequencies{$i} == $max;
    }
    return $count;
}

my @tests = ( [1, 2, 2, 4, 1, 5], [1, 2, 3, 4, 5]);
for my $test (@tests) {
    printf "%-15s => ", "@$test";
    say max_frequency @$test;
}

This program displays the following output:

$ perl  ./max-frequency.pl
1 2 2 4 1 5     => 4
1 2 3 4 5       => 5

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 July 14, 2024. 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.