# The Weekly Challenge - 262 (March 25th 2024)

## Task #1: Max Positive Negative

You are given an array of integers, @ints. Write a script to return the maximum number of either positive or negative integers in the given array.

*Assumption there are no zero values (or we count them as neither +ve or -ve*

**Example 1**

Input: -3,1,2,-1,3,-2,4 Output: 4

4 positive and 3 negative values – so answer is 4.

**Example 2**

Input: -1,-2,-3,1 Output: 3

3 negative values, 1 positive – answer 3

**Example 3**

Input: 1,2 Output: 2

Only 2 positive values – answer 2

## Solution

We use the spaceship operator `<=>`

to get the signum of each value – and the perl trick that in an array of 3 elements the -1 element is the 2 element.

We then use the spaceship operator again to get the maximum of the +/- counts – which are 1 & 2.

ADDENDUM

If you want to count `0s`

as both +ve and -ve then the last line can be replaced with “`$c[ $c[1] <=> $c[2] ] + $c[0]`

“.

#### 262-task1.pl - perl

`sub max_positive_negative {`

my @c = (0, 0, 0);

$c[ $_ <=> 0 ] ++ for @_;

$c[ $c[1] <=> $c[2] ]

}

## Task #2: Count equal divisible

You are given an array of integers, `@ints`

and an integer `$k`

. Write a script to return the number of pairs `($i, $j)`

where `$i < $j`

, `$ints[$i] == $ints[$j]`

and `$i*$j`

is divisible by `$k`

;

*Here we are going to produce two solutions, in both cases $k is passed in as the last element of the array (hence pop rather than shift):*

**Example 1**

Input: @ints = (3,1,2,2,2,1,3), $k = 2 Output: 4

The two 3s are in positions 0 & 6 product even so + 1

The two 1s are in positions 1 & 5 the product is not even so + 0

The three 2s are in positions 2,3,4 all products are even so + 3

**Example 2**

Input: @ints = (1,2,3), $k = 1 Output: 0

None are equal

**Example 3**

Input: @ints = (2,1,1,1,1,3,3,3,3), $k = 12 Output: 2

Only index pairs to consider are 2,6; 3,4; 3,8; 4,6

**Example 4**

Input: @ints = (5,3,1,3,4,1,1,3,5,2,4,2,4,1,1,2,2,3,3,2), $k = 6 Output: 13

**Example 5**

Input: @ints = (6,6,1,9,1,3,6,2,5,1,4,8,9,6,9,9,4,2,2,4,9, 6,2,4,8,4,1,6,9,4,4,6,4,7,3,4,4,4,1,4,6,6, 1,1,5,6,9,5,8,7,2,6,6,3,8,4,8,4,6,8,5,2,4, 8,5,5,3,3,6,7,4,8,6,5,5,7,3,9,4,4,4,4,7,2, 6,8,7,7,3,3,5,3,2,5,5,6,1,5,1,1), $k = 12 Output: 171

## Solution 1 - nested loop over all pairs (naive)

We loop through `$i`

& `$j`

– we check that the product is divisible by `$k`

(it is divisible if `($i*$j) % $k`

is `0`

), then values are the same and if they increment the count `$c`

– we use `||`

and `&&`

to replace if not true and if true; Note as we are using a postfix `for`

then “`$j`

” is replaced by “`$_`

“

#### perl

`sub count_equal_divisible {`

my($k,$c) = (pop,0);

for my $i ( 0 .. $#_ - 1 ) {

( $i * $_ ) % $k || $_[ $i ] == $_[ $_ ]

&& $c++ for $i + 1 .. $#_;

}

$c

}

## Solution 2 - hashing and then looping over common values

In this case we create a hash for which the keys are the values in the list and the values are arrays of the indices of that number.

We then do the solution 1 loop for each element of the hash, i.e. the indices which have the same values – this though is simplified as we no longer need to do the value comparison inside the loops.

#### perl

`sub count_equal_divisible_h {`

my ( $k, $p, $c, %h ) = ( pop, 0, 0 );

push @{ $h{$_} }, $p++ for @_;

for my $x ( values %h ) {

while( @{$x} ) {

my $i = shift @{$x};

( $i * $_ ) % $k || $c++ for @{$x};

}

}

$c

}

~

## Performance

For the examples in the challenge the speed for the naïve version is only roughly 2% faster than the hash method, so the hashing overhead is not great;

But an example with a list of 20 numbers between 1 & 5 the hash method is about 110% faster;

An example with a list of 100 numbers between 1 & 9 the hash method is about 420% faster;

## About The Weekly Challenge

The weekly challenge was set up Mohammad Anwar approximately 5 years ago - each Monday two problems are set for the "team" to solve.

These are posted at: