How to print an array in a matrix format

Viewed 90

I am creating a cypher program. I want to transcript the key (given in $ARGV[1]) to a matrix of numbers.

But, I have some troubles figuring out how to print the array as a matrix without getting warnings/errors.

use strict;
use warnings;
use POSIX;
my @characters = split //, $ARGV[1];
@characters = map {ord($_)} 0 .. $#characters;
my $col_nb = ceil(sqrt($#characters));
for my $i (1 .. ($col_nb**2 - $#characters - 1)) { push @characters , 0; }
foreach my $i (0 .. $col_nb - 1) {
    printf "%.0f\t" x $col_nb, @characters[$col_nb * $i ..  $col_nb * ($i + 1)];
    printf("\n");
}

I am triyng to get an output like this : (key = "abcd")

48 49
50 51

But, I get these errors on the output :

Redundant argument in printf at test.perl line 9.
48      49
Redundant argument in printf at test.perl line 9.
50      51
2 Answers

You are off by one. Your array slice contains 3 numbers, but you only want 2. Change:

printf "%.0f\t" x $col_nb, @characters[$col_nb * $i ..  $col_nb * ($i + 1)];

to:

printf "%.0f\t" x $col_nb, @characters[$col_nb * $i ..  ($col_nb * ($i + 1) - 1)];

You can add use diagnostics; to get a more verbose warning message:

(W redundant) You called a function with more arguments than other
arguments you supplied indicated would be needed.  Currently only
emitted when a printf-type format required fewer arguments than were
supplied, but might be used in the future for e.g. "pack" in perlfunc.

Only use printf when you are doing formatting. Change:

printf("\n");

to:

print "\n";

Check the edge cases and off-by-one errors.

Also, you want the square root of the number of characters, not the number - 1.

Moreover, you don't need to create another array to hold the numbers, you can map the characters to them on the fly when printing.

#!/usr/bin/perl
use strict;
use warnings;
use POSIX qw{ ceil };
my @characters = split //, $ARGV[1];
my $col_nb = ceil(sqrt @characters);
for my $i (0 .. $col_nb - 1) {
    printf "%d\t" x $col_nb,
        map defined ? ord : 0,
        @characters[$col_nb * $i ..  $col_nb * ($i + 1) - 1];
    print "\n";
}
Related