Camel
Peter
Peter Campbell Smith

Adding ones and
maxing the mean

Weekly challenge 304 — 13 January 2025

Week 304: 13 Jan 2025

Task 2

Task — Maximum average

You are given an array of integers, @ints and an integer, $n which is less than or equal to total elements in the given array. Write a script to find the contiguous subarray whose length is the given integer, $n, and has the maximum average. It should return the average.

Examples


Example 1
Input: @ints = (1, 12, -5, -6, 50, 3), $n = 4
Output: 12.75
Subarray: (12, -5, -6, 50)
Average: (12 - 5 - 6 + 50) / 4 = 12.75

Example 2
Input: @ints = (5), $n = 1
Output: 5

Analysis

The easy way to do this is just to calculate the average of all the possible subarrays, of which there will only be length(@ints) - $n + 2. Even if @ints contains 10 000 integers this takes less than a second.

So that's what I am submitting.

Try it 

Try running the script with any input:



example: 1, 99, -43, 78, 20, 71, -40



example: 4

Script


#!/usr/bin/perl

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

use v5.26;    # The Weekly Challenge - 2025-01-13
use utf8;     # Week 304 - task 2 - Maximum average
use warnings; # Peter Campbell Smith
binmode STDOUT, ':utf8';

maximum_average([1, 12, -5, -6, 50, 3], 4);
maximum_average([5, 5, 5, 5, 0, 0, 0], 4);
maximum_average([0, 0, 0, 0, 0, 6, 6], 5);

my @ints;
push @ints, int(rand(100)) - 50 for 1 .. 100;
maximum_average(\@ints, 10);

sub maximum_average {
    
    my (@ints, $n, $max_average, $max_suum, $start, $sum, $average, $subarray);
    
    # initialise
    @ints = @{$_[0]};
    $n = $_[1];
    $max_average = 0;
    
    # loop over staring points
    for $start (0 .. $#ints - $n + 1) {
        $sum = 0;
        $sum += $_ for @ints[$start .. $start + $n - 1];
        $average = $sum / $n;
        
        # potential answer
        if ($average > $max_average) {
            $max_average = $average;
            $subarray = join(', ', @ints[$start .. $start + $n - 1]);
        }
    }
    
    # report
    say qq[\nInput:  \@ints = (] . join(', ', @ints) . qq[), \$n = $n];
    say qq[Output: $max_average - ($subarray)];
}

Output



Input:  @ints = (1, 12, -5, -6, 50, 3), $n = 4
Output: 12.75 - (12, -5, -6, 50)

Input:  @ints = (5, 5, 5, 5, 0, 0, 0), $n = 4
Output: 5 - (5, 5, 5, 5)

Input:  @ints = (0, 0, 0, 0, 0, 6, 6), $n = 5
Output: 2.4 - (0, 0, 0, 6, 6)

Input:  @ints = (26, -4, 24, -28, -1, -7, 4, -35, -5,
-6, -37, 22, 14, 2, -37, -25, -26, 23, 6, -13, 40, -10,
12, 21, 38, 3, 43, 1, -34, 18, 21, 25, 2, -16, 44, -22,
-33, -50, 28, -9, -40, 29, 43, -32, -3, -9, 1, -7, 5,
-27, -28, 3, -19, -24, -17, 10, -42, -31, 21, 32, 17, -7,
-32, 18, -17, -13, -40, 0, 27, 22, 42, 18, -30, 37, 3,
-17, -14, 13, 28, -9, 13, 15, -12, 16, -37, -31, -38, 42,
39, 37, 2, 39, -32, -16, 19, -4, 18, 6, 6, 27), $n = 10
Output: 16.3 - (23, 6, -13, 40, -10, 12, 21, 38, 3, 43)

 

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