Perl Weekly Challenge 262: Count Equal Divisible

These are some answers to the Week 262, Task 2, of the Perl Weekly Challenge organized by Mohammad S. Anwar.

Spoiler Alert: This weekly challenge deadline is due in a few days from now (on March 31, 2024 at 23:59). This blog post provides some solutions to this challenge. Please don’t read on if you intend to complete the challenge on your own.

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

a) 0 <= i < j < size of @ints

b) ints[i] == ints[j]

c) i x j is divisible by k

Example 1

Input: @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

Note that we need to make sure that the input integer $k is not zero.

Count Equal Divisible in Raku

We need two nested loops to manage (i, j) pairs. Property (a) is guaranteed by a proper choice of the ranges for the loop variables. The rest of the program is straight forward.

sub count-equal-div ($divisor where * != 0, @in) {
    my $count = 0;
    for 0..^@in.end -> $i {
        for $i^..@in.end -> $j {
            next if @in[$i] != @in[$j];
            $count++ if $i * $j %% $divisor;
        }
    }
    return $count;
}

my @tests = (2, (3,1,2,2,2,1,3)), (1, (1,2,3));
for @tests -> @test {
    printf "%d - %-15s => ", @test[0], "@test[1]";
    say count-equal-div @test[0], @test[1];
}

This program displays the following output:

$ raku ./count-equal-divisible.raku
2 - 3 1 2 2 2 1 3   => 4
1 - 1 2 3           => 0

Count Equal Divisible in Perl

This is a port to Perl of the above Raku program.

use strict;
use warnings;
use feature 'say';

sub count_equal_div {
    my $divisor = shift;
    die "$divisor cannot be 0" if $divisor == 0;
    my @in = @_;
    my $count = 0;
    for my $i (0 .. $#in - 1) {
        for my $j ($i+1 .. $#in) {
            next if $in[$i] != $in[$j];
            $count++ if $i * $j % $divisor == 0;
        }
    }
    return $count;
}

my @tests = ( [2, [3,1,2,2,2,1,3]], [1, [1,2,3]] );
for my $test (@tests) {
    printf "%d - %-15s => ", $test->[0], "@{$test->[1]}";
    say count_equal_div  @$test[0], @{$test->[1]};
}

This program displays the following output:

$ perl ./count-equal-divisible.pl
2 - 3 1 2 2 2 1 3   => 4
1 - 1 2 3           => 0

Wrapping up

The next week Perl Weekly Challenge will start soon. If you want to participate in this challenge, please check https://perlweeklychallenge.org/ and make sure you answer the challenge before 23:59 BST (British summer time) on April 7, 2024. And, please, also spread the word about the Perl Weekly Challenge if you can.

Leave a comment

About laurent_r

user-pic I am the author of the "Think Perl 6" book (O'Reilly, 2017) and I blog about the Perl 5 and Raku programming languages.