X: a b c j k g e h i Y: a b d e f h i Z: a z c d f g h i #### X: a b [c j k g e] h i Y: a b [d e f] h i x: a [b] c [j k] g [e] h i Z: a [z] c [d f] g [ ] h i #### X: a | b [c j k g e] h i Y: a | b [d e f] h i x: | [b] c [j k] g [e] h i Z: a | [z] c [d f] g [ ] h i #### X: a b | [c j k g e] h i Y: a b | [d e f] h i x: | c [j k] g [e] h i Z: a [z] | c [d f] g [ ] h i #### X: a b | c | [j k g e] h i Y: a b [d e f] | | h i x: | | [j k] g [e] h i Z: a [z] | c | [d f] g [ ] h i #### X: a b c | [j k g e] h i Y: a b [d e f] | h i x: | [j k] g [e] h i Z: a z c | [d f] g [ ] h i #### X: a b c j k | g [e] h i Y: a b [d e f] | h i x: | [e] h i Z: a z c [d f] | g [ ] h i #### X: a b c j k | g | [e] h i Y: a b [d e f] | | h i x: | | [e] h i Z: a z c [d f] | g | [ ] h i #### X: a b c j k g | [e] h i Y: a b d [[e] f] | h i x: | [e] h i Z: a z c d [ f] g | [ ] h i #### X: a b c j k g | [e] h i Y: a b d e f | h i x: | [e] h i Z: a z c d f g | [ ] h i #### X: a b c j k g e | h i Y: a b d e f | h i x: | h i Z: a z c d f g | h i #### X: a b c j k g e h i Y: a b d e f h i x: h i Z: a z c d f g h i #### my @seq= GetSequences(); # ( \@seq0, \@seq1, \@seq2, ... ); my @out= DiffMerge( 1, @seq ); sub DiffMerge { my( $finish, @seq )= @_; my @diff= map { DiffToMerge->new( $_, $seq[-1] ) } @seq[ 0 .. $#seq-1 ]; my @out; for my $i ( 0 .. $#{ $seq[-1] } ) { my @row; my $same= 0; my %sublists; my @flush; for my $d ( 0 .. $#diff ) { for( $diff[$d]->SubList() ) { $sublists{$d}= $_ if $_; } if( $diff[$d]->Same($i) ) { $same++; push @flush, $d if $sublists{$d}; push @row, $diff[$d]->Shift(); } else { push @row, undef; } } if( @flush ) { for my $row ( DiffMerge( 0, values %sublists ) ) { my @subrow; for my $d ( keys %sublist ) { $subrow[$d]= $diff[$d]->SublistOffset() + shift @$row; } push @out, \@subrow; } FlushSublist( \@out, $_, $diff[$_] ) for @flush; } if( $same ) { push @row, $i; push @out, \@row; } else { my @r; $r[@diff]= $i; push @out, \@r; } } if( $finish ) { FlushSublist( \@out, $_, $diff[$_] ) for 0 .. $#diff; } return @out; }