Positively Equal
with Raku

by Arne Sommer

Positively Equal with Raku

[282] Published 26. March 2024.

This is my response to The Weekly Challenge #262.

Challenge #262.1: Max Positive Negative

You are given an array of integers, @ints.

Example 1:
Input: @ints = (-3, 1, 2, -1, 3, -2, 4)
Output: 4

Count of positive integers: 4
Count of negative integers: 3
Maximum of count of positive and negative integers: 4
Example 2:
Input: @ints = (-1, -2, -3, 1)
Output: 3

Count of positive integers: 1
Count of negative integers: 3
Maximum of count of positive and negative integers: 3
Example 3:
Input: @ints = (1,2)
Output: 2

Count of positive integers: 2
Count of negative integers: 0
Maximum of count of positive and negative integers: 2

Note that zero is neither negative nor positive. It is neutral, so to speak.

File: max-positive-negative
#! /usr/bin/env raku

unit sub MAIN (*@ints where all(@ints) ~~ Int && @ints.elems > 0,  # [1]
               :v(:$verbose));

my $positive = (@ints.grep: * >  0).elems;                         # [2P]
my $negative = (@ints.grep: * <  0).elems;                         # [2N]
my $zero     = (@ints.grep: * == 0).elems;                         # [2Z]

if $verbose
{
  say ": Count of positive integers: $positive";
  say ": Count of negative integers: $negative";
  say ": Count of zeroes: $zero";
}

($positive, $negative).max.say;                                    # [3]

[1] All of the values, of which there must be at least one, must be integers.

[2] Use grep to get the positive [2P], negative [2N] and zero [2Z] values, and elems to count them.

See docs.raku.org/routine/grep for more information about grep.

See docs.raku.org/routine/elems for more information about elems.

[3] Print the highest count.

Running it:

$ ./max-positive-negative -- -3 1 2 -1 3 -2 4
4

$ ./max-positive-negative -- -1 -2 -3 1
3

$ ./max-positive-negative 1 2
2

Looking good.

With verbose mode:

$ ./max-positive-negative -v -- -3 1 2 -1 3 -2 4
: Count of positive integers: 4
: Count of negative integers: 3
: Count of zeroes: 0
4

$ ./max-positive-negative -v -- -1 -2 -3 1
: Count of positive integers: 1
: Count of negative integers: 3
: Count of zeroes: 0
3

$ ./max-positive-negative -v 1 2
: Count of positive integers: 2
: Count of negative integers: 0
: Count of zeroes: 0
2

With zeroes:

$ ./max-positive-negative -v -- 1 2 -1 -2 0 0 0 0 0 0 0 0 0 0
: Count of positive integers: 2
: Count of negative integers: 2
: Count of zeroes: 10
2

Challenge #262.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
  1. 0 <= i < j < size of @ints
  2. ints[i] == ints[j]
  3. i x j is divisible by k
Example 1:
nput: @ints = (3,1,2,2,2,1,3) and $k = 2
Output: 4

(0, 6) => ints[0] == ints[6] and 0 x 6 is divisible by 2
(2, 3) => ints[2] == ints[3] and 2 x 3 is divisible by 2
(2, 4) => ints[2] == ints[4] and 2 x 4 is divisible by 2
(3, 4) => ints[3] == ints[4] and 3 x 4 is divisible by 2
Example 2:
Input: @ints = (1,2,3) and $k = 1
Output: 0

File: count-equal-divisible
#! /usr/bin/env raku

unit sub MAIN (Int $k,                                             # {1] 
               *@ints where all(@ints) ~~ Int && @ints.elems > 0,  # [1a]
               :v(:$verbose));

my $count = 0;                                                     # [2]

for 0 .. @ints.elems -2 -> $i                                      # [3]
{
  for $i +1 .. @ints.elems -1 -> $j                                # [4]
  {
    next unless @ints[$i] == @ints[$j];                            # [5]
    next unless $i * $j %% $k;                                     # [6]

    $count++;                                                      # [7] 

    say ": ($i, $j) => ints[$i] == ints[$j] == @ints[$j] and \
      $i x $j = { $i * $j} is divisible by $k" if $verbose;
  }
}

say $count;                                                        # [8]

[1] First the «k» value, followed by the array.

[2] The count will end up here.

[3] Iterate over the indices of the left (or «i») value of the pairs.

[4] Iterate over the indices of the right (or «j») value of the pairs.

[5] The values at the given positions must be equal. If not, skip the pair.

[6] The indices multiplied together must be divisible by «k». If not, skip the pair.

[7] We have a match, count it.

[8] Print the result.

Running it:

$ ./count-equal-divisible 2 3 1 2 2 2 1 3
4

$ ./count-equal-divisible 1 1 2 3
0

Looking good.

With verbose mode:

$ ./count-equal-divisible -v 2 3 1 2 2 2 1 3
: (0, 6) => ints[0] == ints[6] == 3 and 0 x 6 = 0 is divisible by 2
: (2, 3) => ints[2] == ints[3] == 2 and 2 x 3 = 6 is divisible by 2
: (2, 4) => ints[2] == ints[4] == 2 and 2 x 4 = 8 is divisible by 2
: (3, 4) => ints[3] == ints[4] == 2 and 3 x 4 = 12 is divisible by 2
4

$ ./count-equal-divisible -v 1 1 2 3
0

And that's it.