• Status: Solved
• Priority: Medium
• Security: Public
• Views: 163

# Creating diagonal array but retaining first n columns.

This is sort of a continuation of  question I previously asked, which was:

http://www.experts-exchange.com/Programming/Programming_Languages/Perl/Q_21857321.html

An Expert provided this code:

for( \@ary1, \@ary2, \@ary3 ){
my \$right=@{\$_->[0]};
my \$left=@combinedary&&@{\$combinedary[0]};
push @\$_,(0)x\$right for @combinedary;
push @combinedary,[(0)x\$left, @\$_] for @\$_;
}

The idea is to combined multiple arrays and create a "diagonal" of values and fill with zeros everywhere else, which is exactly what the above code accomplishes.  But for this question, I would like to retain the first n columns.  Please see below for a detailed description.  This example only combines two arrays but the solution should apply to two or more arrays.

@ary1 = (
[1,2,3,4]
);

@ary2 = (
[10,9,8]
);

If n==2, then the final array would be:
@final = (
[1,2,3,4,0],
[10,9,0,0,8]
),

if n==1, then the final array would be:
@final = (
[1,2,3,4,0,0],
[10,0,0,0,9,8]
);

Another way to think of this would be to add @ary1 and @ary2:

@combined = (
[1,2,3,4],
[10,9,8]
);

Then split after n columns:
n==2:
@left = (
[1,2],
[10,9]
);

@right = (
[3,4],
[8]
);

Apply the above zero padding method to @right but leave @left alone:
@right_result = (
[3,4,0],
[0,0,8]
);

Finally, put @left and @right_result together:
@rightleft = (
[1,2,3,4,0]
[10,9,0,0,8]
);
0
mock5c
• 3
1 Solution

Commented:
For the zero padding, You want the first array to have all padding to the right, the each array after that to have padding to the left such that it's 3rd (if n=2) element is 1 column after the last elemnt of the previous array?

0

Commented:
Building on the code from before:

#!/usr/bin/perl
use strict;
use Data::Dumper;

my @ary1 = (
[1,2,3,4]
);

my @ary2 = (
[10,9,8]
);

#Combine arrays.  First argument is number of elements to keep, remaining arguments are pointers to arrays
my @arrfinal=Combine(2,\@ary1, \@ary2);
print Dumper(\@arrfinal);

#This subroutine will combine all arrays passed to it
sub Combine {
my (\$NumToKeep,@ArrPtr)=@_;
my (@left,@combinedary);

#Create left, the remaining is right
foreach my \$arr (@ArrPtr){
#push @left, [];
foreach my \$row (@{\$arr}){
push @left, [];
#push @{\$left[-1]}, [];
#push @{\${\$left[-1]}[-1]}, shift @{\$row} for (1..\$NumToKeep);
push @{\$left[-1]}, shift @{\$row} for (1..\$NumToKeep);
}
}

#This is the same code from before
for( @ArrPtr ){
my \$right=@{\$_->[0]};
my \$left=@combinedary&&@{\$combinedary[0]};
push @\$_,(0)x\$right for @combinedary;
push @combinedary,[(0)x\$left, @\$_] for @\$_;
}

#Combine the two arrays
foreach my \$row (@left){
my \$combrow=shift @combinedary;
push @\$row, shift @{\$combrow} while \$#{\$combrow}>=0;
}
return @left;
}

0

Commented:
Some lines are commented out... you can delete those - they were there for debugging
0

Commented:
\$n=2;
@combinedary=();
for( \@ary1, \@ary2, \@ary3 ){
my @right=(0)x(@{\$_->[0]}-\$n);
my @middle=(0)x((@combinedary&&@{\$combinedary[0]})-\$n);
push @\$_,@right for @combinedary;
push @combinedary,[@\$_[0..\$n-1],@middle, @\$_[\$n..\$#\$_]] for @\$_;
}
0

## Featured Post

• 3
Tackle projects and never again get stuck behind a technical roadblock.