Peter’s blog ✴ Week 266 ✴ 22 April 2024

THE WEEKLY CHALLENGE
Solo words and a cross matrix

The Perl Camel

Task 2

X matrix

You are given a square matrix, $matrix. Write a script to find if the given matrix is an X Matrix. A square matrix is an X Matrix if all the elements on the main diagonal and antidiagonal are non-zero and everything else is zero.

Examples


Example 1
Input: $matrix = [ [1, 0, 0, 2],
                   [0, 3, 4, 0],
                   [0, 5, 6, 0],
                   [7, 0, 0, 1],
                 ]
Output: true

Example 2
Input: $matrix = [ [1, 2, 3],
                   [4, 5, 6],
                   [7, 8, 9],
                 ]
Output: false

Example 3
Input: $matrix = [ [1, 0, 2],
                   [0, 3, 0],
                   [4, 0, 5],
                 ]
Output: true

Analysis

I can't think of any way to do this other than to examine each element of the matrix in turn. If the element is not what is needed - non-zero for a diagonal element and zero for an off-diagonal element - we can immediately give up and say 'false'.

Otherwise, once we've examined every element and found no problems we can answer 'true'.

A few weeks ago I wrote a subroutine to print a matrix nicely, and it has come in useful once more.

Perl Weekly’s review

from PW issue 666

Love the simplicity in the solution. No gimmicks, pure solution. Get to try as well, really cool. Thanks for sharing.

Try it 

Try running the script with any input:



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

Script


#!/usr/bin/perl

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

use v5.26;    # The Weekly Challenge - 2024-04-22
use utf8;     # Week 266 - task 2 - X matrix
use warnings; # Peter Campbell Smith
binmode STDOUT, ':utf8';

x_matrix([ [1, 0, 0, 2],
           [0, 3, 4, 0],
           [0, 5, 6, 0],
           [7, 0, 0, 1] ]);
           
x_matrix([ [0, 2, 0],
           [4, 0, 6],
           [0, 8, 0] ]);
           
x_matrix([ [1, 0, 0, 0, 1],
           [0, 2, 0, 2, 0],
           [0, 0, 3, 0, 0],
           [0, 4, 0, 4, 0],
           [5, 0, 0, 0, 0] ]);
           
x_matrix([ [1, 0, 2],
           [0, 3, 0],
           [4, 0, 5] ]);
                 
sub x_matrix {
    
    my ($matrix, $dimension, $x, $y);
    
    # initialise
    $matrix = shift;
    $dimension = scalar @$matrix - 1;
    print_matrix(qq[Input: ], $matrix);
    
    # loop over matrix elements
    for $x (0 .. $dimension) {
        for $y (0 .. $dimension) {
            
            # conditions that must be met
            next if ($x == $y or $x == $dimension - $y) ?
                $matrix->[$x]->[$y] != 0 : $matrix->[$x]->[$y] == 0;
            
            # ... but they are not
            say qq[Output: false (∵ matrix[$x, $y] == $matrix->[$x]->[$y])];
            return;
        }
    }
    
    # all values are good
    say qq[Output: true];
}

sub print_matrix {
    
    my ($legend, $matrix, $j);

    # format rows of matrix
    ($legend, $matrix) = @_;
    say '';
    for $j (0 .. @$matrix - 1) {
        say qq{$legend [} . join(', ', @{$matrix->[$j]}) . qq(]);
        $legend = ' ' x length($legend);
    }
}

19 lines of code

Output from script


Input:  [1, 0, 0, 2]
        [0, 3, 4, 0]
        [0, 5, 6, 0]
        [7, 0, 0, 1]
Output: true

Input:  [0, 2, 0]
        [4, 0, 6]
        [0, 8, 0]
Output: false (∵ matrix[0, 0] == 0)

Input:  [1, 0, 0, 0, 1]
        [0, 2, 0, 2, 0]
        [0, 0, 3, 0, 0]
        [0, 4, 0, 4, 0]
        [5, 0, 0, 0, 0]
Output: false (∵ matrix[4, 4] == 0)

Input:  [1, 0, 2]
        [0, 3, 0]
        [4, 0, 5]
Output: true

 

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