Peter’s blog ✴ Week 320 ✴ 5 May 2025

THE WEEKLY CHALLENGE
Fun with integers

The Perl Camel

Task 1

Maximum count

You are given an array of integers. Write a script to return the maximum between the number of positive and negative integers. Zero is neither positive nor negative.

Examples


Example 1
Input: @ints = (-3, -2, -1, 1, 2, 3)
Output: 3
There are 3 positive integers.
There are 3 negative integers.
The maximum between 3 and 3 is 3.

Example 2
Input: @ints = (-2, -1, 0, 0, 1)
Output: 2
There are 1 positive integers.
There are 2 negative integers.
The maximum between 2 and 1 is 2.

Example 3
Input: @ints = (1, 2, 3, 4)
Output: 4
There are 4 positive integers.
There are 0 negative integers.
The maximum between 4 and 0 is 4.

Analysis

I am content for this challenge to do it nearly all in one line:

$count{$_ < 0 ? 'neg' : ($_ > 0 ? 'pos' : 'zero')} ++ for @_;

It's perhaps unusual to have a quite complicated expression to generate the key of the array, but I think it is clear enough to meet my criteria of understandable and maintainable.

For a very large array it would probably be faster to hold the counts in scalars - $pos, $neg and $zero. That would take more lines of Perl at compile time, but I think it likely that computing the keys of my hash will extend the run time of my submitted version.

Perl Weekly’s review

from PW issue 720

Clever use of eval to get the expected result. Don't forget to try DRY tool.

Try it 

Try running the script with any input:



example: -7, 7, -5, 5, 3, -3, 0

Script


#!/usr/bin/perl

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

use v5.26;    # The Weekly Challenge - 2025-05-05
use utf8;     # Week 320 - task 1 - Maximum count
use warnings; # Peter Campbell Smith
binmode STDOUT, ':utf8';
use Encode;

maximum_count(-3, -2, -1, 1, 2, 3);
maximum_count(-2, -1, 0, 0, 1);
maximum_count(1, 2, 3, 4);
maximum_count(0, 0, 0);

# larger example
my @nums;
push @nums, int(rand(41)) - 20 for 0 .. 99;
maximum_count(@nums);

sub maximum_count {
    
    my %count = (pos => 0, neg => 0, zero => 0);
    
    # count +ves, -ves and 0s
    $count{$_ < 0 ? 'neg' : ($_ > 0 ? 'pos' : 'zero')} ++ for @_;
    
    # report
    say qq[\nInput:  (] . join (', ', @_) . ')';;
    say qq[Output: ] . ($count{pos} > $count{neg} ? $count{pos} : $count{neg}) .
        qq[ ($count{neg} negative, $count{pos} positive, $count{zero} zero)];
}

6 lines of code

Output from script


Input:  (-3, -2, -1, 1, 2, 3)
Output: 3 (3 negative, 3 positive, 0 zero)

Input:  (-2, -1, 0, 0, 1)
Output: 2 (2 negative, 1 positive, 2 zero)

Input:  (1, 2, 3, 4)
Output: 4 (0 negative, 4 positive, 0 zero)

Input:  (0, 0, 0)
Output: 0 (0 negative, 0 positive, 3 zero)

Input:  (-20, -2, 1, -16, -6, 14, -10, 0, -19, -15, 0, 18,
   9, -18, 19, 10, -1, 15, 0, 8, 19, -5, -19, 20, 14, -14,
   16, 12, -7, 9, 3, 9, 1, -12, -5, 14, -5, -3, 3, 14, 17,
   -11, -1, -15, 16, -15, 5, 3, -2, 5, 15, -13, 4, -6, 14,
   18, 7, -20, -2, -12, 18, -14, 15, 6, -12, 13, 16, 16,
   -6, -13, 3, 1, 0, 19, 1, 16, 2, 18, 16, -18, -10, 19,
   0, -18, 3, -13, 13, 19, 5, 14, -10, -17, -16, 20, -20,
   -14, -16, -6, -11, 13)
Output: 52 (43 negative, 52 positive, 5 zero)

 

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