An interesting solution to an interesting problem.
I noticed you didn't use warnings; putting them in gives this:
Use of uninitialized value in concatenation (.) or string at x.pl line
+ 47.
Use of uninitialized value in concatenation (.) or string at x.pl line
+ 47.
...
But you can fix it as easily as changing the line:
$w_columns{$w_col_ix} = "$w_columns{$w_col_ix}${w_pad}${w_char}";
to:
$w_columns{$w_col_ix} .= "${w_pad}${w_char}";
Then, for fun, I tried golfing it. Assuming the second parameter will almost always be spaces, I changed it from a string to the number of spaces (but left the default at 2).
Here's my result:
use strict;
use warnings;
my $a_rows = [qw[one two three four five six seven eight nine ten]];
my $npad = 4;
my $justify = 1;
rows_to_cols($a_rows, $npad, $justify);
sub rows_to_cols {
my ($x, $p, $j) = @_;
my $m = 0; map { $m = length $_ if $m < length $_ } @$x;
($j||0) && map { $_ = sprintf "%*s", $m, $_ } @$x;
@_ = map { ($")x($p||2),$_ } @$x;
map { map { print substr($_, 0, 1, "") || $" } @_; print $/ } 1..$
+m
}
And here's what's happening:
sub rows_to_cols {
my ($x, $p, $j) = @_;
my $m = 0; map { $m = length $_ if $m < length $_ } @$x;
##
# Assigns to $m the maximum length of any word
($j||0) && map { $_ = sprintf "%*s", $m, $_ } @$x;
##
# If bottom-justifying, converts every word to the
# right-justified version of the same. Thus:
#
# [ [
# 'one', ' one',
# 'two', ' two',
# 'three', 'three',
# 'four', ' four',
# 'five', => becomes => ' five',
# 'six', ' six',
# 'seven', 'seven',
# 'eight', 'eight',
# 'nine', ' nine',
# 'ten' ' ten',
# ] ]
@_ = map { ($")x($p||2),$_ } @$x;
##
# Creates (in @_) vertical padding between each word.
# For example:
# [
# ' ',
# ' ',
# ' ',
# ' ',
# ' one',
# ' ',
# ' ',
# ' ',
# ' ',
# ' two',
# ' ',
# ' ',
# ' ',
# ' ',
# 'three',
# ' ',
# ' ',
# ...
# ' ',
# ' ten'
# ]
# Note that the data is now in a horizontal format that,
# if converted to the vertical equivalent, would be the
# the desired result.
map { map { print substr($_, 0, 1, "") || $" } @_; print $/ } 1..$
+m
##
# This does the magic horizontal to vertical conversion
}
s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/