Mean Brazilians

Weekly challenge 157 — 21 March 2022

Week 157 - 21 Mar 2022

Task 1

You are given a set of integers.

Write a script to compute all three Pythagorean Means ie Arithmetic Mean, Geometric Mean and Harmonic Mean of the given set of integers. Please refer to Wikipedia page for more information.

Example 1: Input: @n = (1,3,5,6,9) Output: AM = 4.8, GM = 3.9, HM = 2.8Example 2: Input: @n = (2,4,6,8,10) Output: AM = 6.0, GM = 5.2, HM = 4.4Example 3: Input: @n = (1,2,3,4,5) Output: AM = 3.0, GM = 2.6, HM = 2.2

I'm never quite sure what is wanted or considered good in these tasks. The options seem to be:

- There's a module to do this
- I can do this in one somewhat inscrutable line
- I can do this in a readable way with lots of comments

If we're aiming to save coder time and not reinventing the wheel, then option 1 is clearly correct. I would almost always use that in a production environment.

Option 2 gives people a chance to demonstrate how compact - and maybe fast - Perl can be, which is a valid aim. If the code is never going to be changed then it's fine, but I suspect that whoever has to come along later and maintain it - even if that's you - is going to scratch their heads for a while.

Option 3 is the way to go if you're trying to write easily maintainable code. It may not be the fastest solution - although often it is easily fast enough.

So for this task I went squarely for option 3: code it just as it's explained in Wikipedia, ie take the list elements one at a time and produce a running sum, product and sum of reciprocals.

#!/usr/bin/perl # Peter Campbell Smith - 2022-03-22 # PWC 157 task 1 use v5.28; use strict; use warnings; use utf8; my ($sum, $n, $product, $reciprocals, @examples, $example, $string); # given sets of integers @examples = ([1, 3, 5, 6, 9], [2, 4, 6, 8, 10], [1, 2, 3, 4, 5], [73, 201, 1, 99, 123, 14, 83, 46, 77]); # loop over sets for $example (@examples) { # get started $product = 1; $sum = $reciprocals = 0; $string = ''; # form sum, product and sum of reciprocals for $n (@$example) { $sum += $n; $product *= $n; $reciprocals += 1 / $n; $string .= qq[$n, ]; } # and tell the world say qq[\nInput: \@n = (] . substr($string, 0, -2) . qq[)\nOutput: ] . qq[AM = ] . sprintf('%1.1f', ($sum / scalar @$example)) . qq[, GM = ] . sprintf('%1.1f', ($product ** (1 / scalar @$example))) . qq[, HM = ] . sprintf('%1.1f', (scalar @$example / $reciprocals)); }

Input: @n = (1, 3, 5, 6, 9) Output: AM = 4.8, GM = 3.8, HM = 2.8 Input: @n = (2, 4, 6, 8, 10) Output: AM = 6.0, GM = 5.2, HM = 4.4 Input: @n = (1, 2, 3, 4, 5) Output: AM = 3.0, GM = 2.6, HM = 2.2 Input: @n = (73, 201, 1, 99, 123, 14, 83, 46, 77) Output: AM = 79.7, GM = 44.9, HM = 7.8

The content of this website which has been created by

Peter Campbell Smith is hereby placed in the public domain

Peter Campbell Smith is hereby placed in the public domain