Peter’s blog ✴ Week 276 ✴ 1 July 2024

THE WEEKLY CHALLENGE
Round days and frequent numbers

The Perl Camel

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.

Examples


Example 1
Input: @ints = (1, 2, 2, 4, 1, 5)
Output: 4
The maximum frequency is 2.
The elements 1 and 2 has the maximum frequency.

Example 2
Input: @ints = (1, 2, 3, 4, 5)
Output: 5
The maximum frequency is 1.
The elements 1, 2, 3, 4 and 5 has the maximum frequency.

Analysis

Again, the straightforward approach is good enough for even quite large numbers of numbers.

The first loop is over @ints, building $freq{$int} and establishing $max_freq.

The second loop is over keys %freq, adding up the frequencies of all the @ints which occur $max_freq times.

Trying this with a million numbers in the range 0 .. 99 took about 2 seconds on my machine to establish that 10194 occured 91 times.

Perl Weekly’s review

from PW issue 676

I noticed the use of v5.26 and few other bits. I am sure it would work with the latest release too (v5.40). Well done.

This review may cover either or both challenges for this week.

Try it 

Try running the script with any input:



example: 1, 2, 3, 4, 5, 5, 6, 6, 6

Script


#!/usr/bin/perl

# Blog: http://ccgi.campbellsmiths.force9.co.uk/challenge

use v5.26;    # The Weekly Challenge - 2024-07-01
use utf8;     # Week 276 - task 2 - Maximum frequency
use warnings; # Peter Campbell Smith
binmode STDOUT, ':utf8';

my @ints;

maximum_frequency(1, 2, 2, 4, 1, 5);
maximum_frequency(1, 2, 3, 4, 5);
maximum_frequency(1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2);

push @ints, int(rand(15)) for 0 .. 99;
maximum_frequency(@ints);

sub maximum_frequency {
    
    my (@ints, $max_freq, $int, %freq, $count, $explain, $s, $they);
    
    @ints = @_;
    $max_freq = 0;
    for $int (@ints) {
        $freq{$int} ++;
        $max_freq = $freq{$int} if $freq{$int} > $max_freq;
    }
    for $int (sort keys %freq) {
        next unless $freq{$int} == $max_freq;
        $count += $freq{$int};
        $explain .= qq[$int, ];
    }

    printf(qq[\nInput:  \@ints = (%s)\n], join(', ', @ints));
    printf(qq[Output: %d integers occur with frequency %d: %s\n], $count, $max_freq, substr($explain, 0, -2));
}

13 lines of code

Output from script


Input:  @ints = (1, 2, 2, 4, 1, 5)
Output: 4 integers occur with frequency 2: 1, 2

Input:  @ints = (1, 2, 3, 4, 5)
Output: 5 integers occur with frequency 1: 1, 2, 3, 4, 5

Input:  @ints = (1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2)
Output: 6 integers occur with frequency 3: 1, 2

Input:  @ints = (0, 6, 11, 1, 13, 10, 8, 0, 0, 14, 2, 3, 13, 1, 0, 13,
   13, 4, 13, 14, 14, 11, 4, 11, 5, 5, 0, 10, 8, 11, 2, 1, 5, 9, 0, 0,
   0, 11, 0, 1, 0, 0, 7, 13, 4, 10, 5, 8, 13, 0, 1, 4, 3, 4, 13, 2,
   12, 4, 10, 1, 6, 6, 10, 1, 3, 11, 1, 3, 0, 13, 13, 10, 9, 4, 12, 3,
   0, 5, 4, 0, 14, 6, 10, 5, 9, 4, 1, 9, 5, 1, 5, 13, 0, 6, 13, 3, 4,
   0, 1, 4)
Output: 17 integers occur with frequency 17: 0

 

Any content of this website which has been created by Peter Campbell Smith is in the public domain