The output should look like:['A','B','C'], ['A','B','D']
In order to achieve that "simple" version, I wrote the script which I attach below. It takes the first array and aligns the second and takes the second and aligns the first and outputs the version with the minimum amount of holes.A A B B C D
The script outputs (6 holes):['A','B','C'], ['A','D','C'], ['A','B','C']
An "intelligent" person would find instead: (3holes)A A A B B C C D C
I wonder if there is a way to achieve that. Actually, I'd need a code that "looks forward" which rows come and align either the right or the left side ... mhm.A A A B B D C C C
#!/usr/bin/perl -w use strict; #use Data::Dumper; my $hash; #$hash->{'Vector1'} = ['A','B','D','H','J']; #$hash->{'Vector2'} = ['A','B','C','D']; #$hash->{'Vector4'} = ['H','K']; $hash->{'Vector3'} = ['A','B','C']; $hash->{'Vector4'} = ['A','D','C']; $hash->{'Vector5'} = ['A','B','C']; #print Dumper($hash); my $count_total = scalar (keys %{$hash}); my @keys = keys %{$hash}; my $aligned; my $minimum; my $key_count=0; for (0 .. $#keys) { my $test = shift(@keys); push(@keys,$test); # # push first into results matrix # to start with # my @result; foreach (@{$hash->{$keys[0]}}) { push(@result,[$_]); } # # compare # my $count_processed=0; my @vector; foreach (keys %{$hash}) { if (($count_processed+2)>$count_total) { last; } @vector = @{$hash->{$keys[$count_processed+1]}}; my $i=0; while ($i <= $#vector) { my $entry = $vector[$i]; if (defined(${$result[$i]}[0])) { # print "1)Is "; # print $entry; # print " in "; # print join(',',@{$result[$i]}); # print " ?"; if (grep $_ eq $entry,@{$result[$i]}) { # print " => yes\n"; push(@{$result[$i]},$entry); } else { # print " => no\n"; splice(@vector,$i,0,''); my @space; for (0 .. ($count_processed-$#{$result[$i]})) { push(@space,''); } push(@{$result[$i]},@space); } ; } else { # print "undefined => shift\n"; my @space; for (0 .. $count_processed) { push(@space,''); } push(@{$result[$i]},@space,$entry); } $i++; } # # the latest column might have missing ''s at the end. This needs +to be # filled up # my $p=0; foreach (@result) { if ($#{$result[$p]} < $#{$result[0]} ) { push(@{$result[$p]},''); } $p++; } $count_processed++; } # # count the number of holes # my $n=0; foreach (@result) { foreach (@$_) { # print "$_ \t"; if ($_ eq '') { $n++; } } } # print "\n"; if($key_count == 0){ $minimum = $n; $aligned = { 'matrix' => [@result], 'n' => $n }; }else{ if($n < $minimum){ $minimum = $n; $aligned = { 'matrix' => [@result], 'n' => $n }; } } $key_count++; } print "minimal configuration ($aligned->{'n'} holes):\n"; foreach (@{$aligned->{'matrix'}}) { foreach (@$_) { print "$_ \t"; } print "\n"; }
In reply to Converting Arrays into Matrix by janDD
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |