use strict; use warnings; my %A; # remembers pairing (x,y) as $A{x}{y} and $A{y}{x} my @order; # set output order here or trust auto-generated @order below # e.g. @order = qw(eel horse lion mule tiger); # autovivify interesting pairings while () { warn("Line $.: cannot understand: $_") , next unless /(\w+);(\w+)/; my ($row, $col) = ($1,$2); $A{$row}{$col}++; # ++ just triggers the autovivification (see: perlref) $A{$col}{$row}++; # uncomment line if relationship is not bidirectional # ... would break gimmick#1 } # Gimmick #1: auto-generated list-order when list-order was not given # assumption: symmetric relationship -> square matrix; # combinations never paired are filtered out - bug or feature? @order = sort keys %A unless @order; # create order unless given above # Gimmick #2: fixed auto-width for output (min. width: 2+3 ('###')) my $width = 2 + (sort { $a <=> $b } ( map { length $_ } (@order, '###' )) )[-1]; my $format = '%-' . $width . 's'; # printf()-format for fixed width columns # print header printf($format, $_) for ( " ", @order ); print "\n"; # print matrix A for my $row (@order) { printf($format, $row); for my $col (@order) { printf($format, exists $A{$row}{$col} ? "1" : "0"); # Idea for gimmick#3: $format = f( column ) } print "\n"; } __DATA__ horse;tiger lion;mule lion;tiger horse;mule