Camel
Peter
Peter Campbell Smith

Fun with integers

Weekly challenge 320 — 5 May 2025

Week 320: 5 May 2025

Task 1

Task — 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.

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)];
}

Output


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