Peter’s blog ✴ Week 337 ✴ 1 September 2025

THE WEEKLY CHALLENGE
One and two dimensions

The Perl Camel

Task 2

Odd matrix

You are given $rows and $cols of a zero-filled matrix, and a list of (0-indexed) positions in the matrix. Write a script to perform the actions in the list below on each position in the list and find the total of the odd-valued cells.

For each position ($r, $c), do both of the following:

  1. Increment all the cells in row $r by 1
  2. Increment all the cells in column $c by 1

Examples


Example 1
Input: $row = 2, $col = 3, @locations = ([0,1],[1,1])
Output: 6
Initial:
[ 0 0 0 ]
[ 0 0 0 ]
Apply [0,1]:
Increment row 0:
Before     After
[ 0 0 0 ]  [ 1 1 1 ]
[ 0 0 0 ]  [ 0 0 0 ]
Increment col 1:
Before     After
[ 1 1 1 ]  [ 1 2 1 ]
[ 0 0 0 ]  [ 0 1 0 ]
Apply [1,1]:
Increment row 1:
Before     After
[ 1 2 1 ]  [ 1 2 1 ]
[ 0 1 0 ]  [ 1 2 1 ]
Increment col 1:
Before     After
[ 1 2 1 ]  [ 1 3 1 ]
[ 1 2 1 ]  [ 1 3 1 ]
Final:
[ 1 3 1 ]
[ 1 3 1 ]

Example 2
Input: $row = 2, $col = 2, @locations = ([1,1],[0,0])
Output: 0
Final:
[ 2 2 ]
[ 2 2 ]

Example 3
Input: $row = 3, $col = 3, @locations = ([0,0],[1,2],[2,
   1])
Output: 0
Final:
[ 2 2 2 ]
[ 2 2 2 ]
[ 2 2 2 ]

Example 4
Input: $row = 1, $col = 5, @locations = ([0,2],[0,4])
Output: 2
Final:
[ 2 2 3 2 3 ]

Example 5
Input: $row = 4, $col = 2, @locations = ([1,0],[3,1],[2,
   0],[0,1])
Output: 8
Final:
[ 3 3 ]
[ 3 3 ]
[ 3 3 ]
[ 3 3 ]

Analysis

I am always a bit discouraged from using Perl's slightly clunky representation of multi-dimensional data structures, such as $cells[$row][$col], and in this case I have used a simple array @cells to represent the matrix. So location [$r, $c] is held at $cells[$c + $r * $cols].

My algorithm is then to loop over the supplied positions, and for each to increment the members of the relevant row and column, like this:

$cells[$_ + $row * $cols] ++ for 0 .. $cols - 1;
$cells[$col + $_ * $cols] ++ for 0 .. $rows - 1;

After that's done, the required sum of the odd elements is simply:

$odds = scalar(grep { $_ & 1 == 1} @cells);

which is much tidier than it would be in a 2-dimensional representation.

Perl Weekly’s review

from PW issue 737

Solutions are clear, idiomatic Perl, well explained and great for educational/demo purposes. They emphasize readability and correctness over raw efficiency, which is often the right trade-off in The Weekly Challenge.

This review may cover either or both challenges for this week.

I am sorry that the 'Try it' feature is currently working very slowly or not at all owing to some issue with my web hosting provider.

Try it 

Try running the script with any input:



example: 4, 3



example: [0, 0], [3, 2], [2, 1], [3, 1]

Script


#!/usr/bin/perl

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

use v5.26;    # The Weekly Challenge - 2025-09-01
use utf8;     # Week 337 - task 2 - Odd matrix
use warnings; # Peter Campbell Smith
binmode STDOUT, ':utf8';
use Encode;

odd_matrix(2, 3, [[0, 1], [1, 1]]);
odd_matrix(2, 2, [[1, 1], [0, 0]]);
odd_matrix(3, 3, [[0, 0], [1, 2], [2, 1]]);
odd_matrix(1, 5, [[0, 2], [0, 4]]);
odd_matrix(4, 2, [[1, 0], [3, 1], [2, 0], [0, 1]]);

sub odd_matrix {
    
    my ($rows, $cols, $locations, @cells, $cell, $row, $col, $legend, $input, $odds);
    
    # initialise
    ($rows, $cols, $locations) = @_;    
    $cells[$_] = 0 for 0 .. $rows * $cols - 1;
    
    # loop over locations
    for $cell (@$locations) {
        ($row, $col) = @$cell;
        
        # increment row and col
        $cells[$_ + $row * $cols] ++ for 0 .. $cols - 1;
        $cells[$col + $_ * $cols] ++ for 0 .. $rows - 1;
        $input .= qq{[$row, $col], };
    }
    $odds = scalar(grep { $_ & 1 == 1} @cells);

    # report
    say qq{\nInput:  \$rows = $rows, \$cols = $cols, \@locations = [} .
        substr($input, 0, -2) . ']';
    say qq[Output: $odds odd value] . ($odds == 1 ? '' : 's');  
    for $row (0 .. $rows - 1) {
        print '        [ ';
        print $cells[$_ + $row * $cols] . ' ' for 0 .. $cols - 1;
        say ']';
    }           
}

17 lines of code

Output from script


Input:  $rows = 2, $cols = 3, @locations = [[0, 1], 
	[1, 1]]
Output: 6 odd values
        [ 1 3 1 ]
        [ 1 3 1 ]

Input:  $rows = 2, $cols = 2, @locations = [[1, 1], 
	[0, 0]]
Output: 0 odd values
        [ 2 2 ]
        [ 2 2 ]

Input:  $rows = 3, $cols = 3, @locations = [[0, 0], 
	[1, 2], [2, 1]]
Output: 0 odd values
        [ 2 2 2 ]
        [ 2 2 2 ]
        [ 2 2 2 ]

Input:  $rows = 1, $cols = 5, @locations = [[0, 2], 
	[0, 4]]
Output: 2 odd values
        [ 2 2 3 2 3 ]

Input:  $rows = 4, $cols = 2, @locations = [[1, 0], 
	[3, 1], [2, 0], [0, 1]]
Output: 8 odd values
        [ 3 3 ]
        [ 3 3 ]
        [ 3 3 ]
        [ 3 3 ]

Input:  $rows = 5, $cols = 5, @locations = [[0, 0], 
	[4, 4]]
Output: 12 odd values
        [ 2 1 1 1 2 ]
        [ 1 0 0 0 1 ]
        [ 1 0 0 0 1 ]
        [ 1 0 0 0 1 ]
        [ 2 1 1 1 2 ]

 

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