vis1982 has asked for the wisdom of the Perl Monks concerning the following question:

Suppose u have One file one row and one column
A1 A2 A3 A4 A1 A2 A3 A4
And another Second file shows pairing
A1;A4 A2;A3 A2;A4 A1;A3
Want the output to be like based on the pairing .. As seen from the second fileThose who are paired will get one A1 A4 will get one same with A1 A3 will get one A1 A2 willw get zero The output shud be like that
A1 A2 A3 A4 A1 0 0 1 1 A2 0 0 1 1 A3 1 1 0 0 A4 1 1 0 0
The code is
#!/usr/bin/perl $data_file="aa1"; open(DAT, $data_file) || die("Could not open file!"); @raw_data=<DAT>; close(DAT); #print $raw_data[0]; $data_file2="aa2"; open(THAT, $data_file2) || die("Could not open file!"); @raw2_data=<THAT>; close(THAT); foreach $data (@raw2_data) { @siv =split(";",$data); if (($siv[0])== ($siv[1])) { print "1"; } else { print "0"; } }
But i didn't get how to create a matrix with that one?

Replies are listed 'Best First'.
Re: create a matrix for print 0 or 1 from pairing
by moritz (Cardinal) on Oct 28, 2009 at 11:38 UTC
    What I would do is:
    • Create a mapping from colum/row name to number. A hash can be very helpful here.
    • Create an emtpy array or arrays
    • For each pair that you read, split it into two names, and use the mapping from the first step to turn it into two column/row numbers. Use that to access the array of arrays, and set the value to 1
    • Print the result
    Perl 6 - links to (nearly) everything that is Perl 6.
Re: create a matrix for print 0 or 1 from pairing
by Perlbotics (Archbishop) on Oct 28, 2009 at 12:21 UTC

    TIMTOWTDI, with a HoH... to get you started... though you might get problems with extremely large numbers of Ax;Ay relationships. Then, try to use bitmaps or a DB.
    HTH

    use strict; use warnings; my %A; my ($max_row, $max_col) = (4,4); # autovivify interesting rows/cols of %A while (<DATA>) { warn("Line $.: cannot understand: $_") , next unless /A(\d+);A(\d+)/ +; my ($row, $col) = ($1,$2); $A{$row}{$col}++; $A{$col}{$row}++; # uncomment if relationship is not bidirectional } # print col. header print " "; printf("A%-3d",$_) for (1..$max_col); print "\n"; #print matrix A for my $row (1 .. $max_row) { printf("A%-3d", $row); for my $col (1 .. $max_col) { printf(" %-3d", exists $A{$row}{$col} ? "1" : "0" ); } print "\n"; } __DATA__ A1;A4 A2;A3 A2;A4 A1;A3
    Output:
    A1 A2 A3 A4 A1 0 0 1 1 A2 0 0 1 1 A3 1 1 0 0 A4 1 1 0 0
    Update: After OP clarified, that A1..A# are actually strings, here are some suggestions to modify the code above:
    • create an array to define output order, e.g. my @order = sort keys %A; / assumption: symmetric matrix
    • replace the (1 .. $max_...) parts by (@order)
    • update the printf(...) lines to cope with wider output and string- instead of int-type where necessary
    Update2: Example plus annotations added.
      Thanks vey much
      If u have horse instead of A1 lion instead of A2 mule instead of A3 tiger instead of A4
      __DATA__ horse;tiger lion;mule lion;tiger horse;mule
      Then in respone to that code tried to modify.
      use strict; use warnings; my %A; my ($max_row, $max_col) = (4,4); # autovivify interesting rows/cols of %A while (<DATA>) { warn("Line $.: cannot understand: $_") , next unless /(\w+);(\w+)/ +; my ($row, $col) = ($1,$2); $A{$row}{$col}++; $A{$col}{$row}++; # uncomment if relationship is not bidirectional } # print col. header print " "; printf("%-3d",$_) for (1..$max_col); print "\n"; #print matrix A for my $row (1 .. $max_row) { printf("%-3d", $row); for my $col (1 .. $max_col) { printf(" %-3d", exists $A{$row}{$col} ? "1" : "0" ); } print "\n"; }
      printing as 1 2 3 4 1 0 0 0 0 2 0 0 0 0 3 0 0 0 0 4 0 0 0 0
      output shud be like
      horse lion mule tiger horse 0 0 1 1 lion 0 0 1 1 mule 1 1 0 0 tiger 1 1 0 0
        Thanks

        I have tried using that as per suggestions by Perlbotics /p>

        #use strict; use warnings; my %A = (horse=> 'a',lion=>'b' ,mule=>'c',tiger =>'d'); my @order= sort keys %A; while (<DATA>) { warn("Line $.: cannot understand: $_") , next unless /(\w+);(\w+)/; my ($row, $col) = ($1,$2); $A {$row}{$col}++; $A{$col}{$row}++; } # print col. header print " "; printf(" %2s",$_) for (@order); print "\n"; #print matrix A for my $row (@order) { printf(" %2s", $row); for my $col (@order) { printf(" %3d", exists $A{$row}{$col} ? "1" : "0" ); } print "\n"; } __DATA__ horse;tiger lion;mule lion;tiger horse;mule
        I have got ouput horse lion mule tiger horse 0 0 1 1 lion 0 0 1 1 mule 1 1 0 0 tiger 1 1 0 0
        However If u see in the code i have not use strict command; if using strict command in the first line error displayed will be Can't use string ("a") as a HASH ref while "strict refs" in use at work_matrix.pl line 12, <DATA> line 1.

        What can be possible solution if using strict command?