I'm currently trying to sort by values in a multi dimensional hash and I'm coming up a bit stumped.
I've done this on a single level as follows:
my %exampleHash = ();
$exampleHash{1}{value} = 10;
$exampleHash{2}{value} = 30;
$exampleHash{3}{value} = 0;
$exampleHash{4}{value} = 20;
foreach my $key ( reverse sort {$exampleHash{$a}{value} <=> $exampleHash{$b}{value}} keys %exampleHash )
{
printf( "%s => %d\n", $key, $exampleHash{$key}{value} );
}
This produces the following output, sorted on the value as expected:
2 => 30
4 => 20
1 => 10
3 => 0
I've then tried the following to do the same thing but with an extra key:
my %exampleHashTwo = ();
$exampleHashTwo{1}{"One"}{value} = 10;
$exampleHashTwo{2}{"Two"}{value} = 30;
$exampleHashTwo{3}{"Three"}{value} = 0;
$exampleHashTwo{4}{"Four"}{value} = 20;
foreach my $intKey ( keys %exampleHashTwo )
{
foreach my $stringKey ( reverse sort {$exampleHashTwo{$intKey}{$a}{value} <=> $exampleHashTwo{$intKey}{$b}{value}} keys %{$exampleHashTwo{$intKey}} )
{
printf( "{%d} - {%5s} => %d\n", $intKey, $stringKey, $exampleHashTwo{$intKey}{$stringKey}{value} );
}
}
However this seems to sort the string key's in alphabetical order. So I'm assuming I'm on the right lines, but I've misplaced something perhaps?
{4} - { Four} => 20
{1} - { One} => 10
{3} - {Three} => 0
{2} - { Two} => 30
Any ideas?
Your outer loop, which loops over the integer keys in somewhat random order, is dictating the order of your output. The inner loop is sorting but only given one value each time.
To sort all the values for all combinations of both keys, you need a single loop and to sort over a generated list of such combinations:
use strict;
use warnings;
my %exampleHashTwo = ();
$exampleHashTwo{1}{"One"}{value} = 10;
$exampleHashTwo{2}{"Two"}{value} = 20;
$exampleHashTwo{2}{"TwoB"}{value} = 5;
$exampleHashTwo{3}{"Three"}{value} = 0;
$exampleHashTwo{4}{"Two"}{value} = 15;
for my $keypair (
sort { $exampleHashTwo{$b->[0]}{$b->[1]}{value} <=> $exampleHashTwo{$a->[0]}{$a->[1]}{value} }
map { my $intKey=$_; map [$intKey, $_], keys %{$exampleHashTwo{$intKey}} } keys %exampleHashTwo
) {
printf( "{%d} - {%5s} => %d\n", $keypair->[0], $keypair->[1], $exampleHashTwo{$keypair->[0]}{$keypair->[1]}{value} );
}
Output:
{2} - { Two} => 20
{4} - { Two} => 15
{1} - { One} => 10
{2} - { TwoB} => 5
{3} - {Three} => 0
(Replaced reverse with switching order of $a and $b.)
Related
I have array #hon_data. If any elements of the array are one of a known list of values, I return zero.
for my $hon_field (#hon_data) {
if($hon_field ne 'B' and $hon_field ne 'S' and $hon_field ne 'G' and
$hon_field ne 'D' and $hon_field ne 'L') {
return 0;
}
}
The number of values to check is growing, so this approach is getting complicated to manage. Is there a way to do this with the values in an array?
my #results =("B","G","S","D","N","L");
my #results2 = ("A","G","S","D","N","L");
sub uniq {
my %seen;
grep { !$seen{$_}++ } #_;
}
my #unique = uniq(#results, #results2);
In result2 A is unique value and it should return A only But this code is not working.
You're asking how to replace the hardcoded loop with a dynamic one. The following is one way this could be done:
for my $hon_field ( #hon_data ) {
for my $ok (qw( B S G D L )) {
if ( $hon_field ne $ok ) {
return 0;
}
}
}
That is a lot better. But if the elements are strings, the inner loop can be replaced with a hash lookup.
my %ok = map { $_ => 1 } qw( B S G D L );
for my $hon_field ( #hon_data ) {
if ( !$ok{ $hon_field } ) {
return 0;
}
}
This can also be written as follows:
use List::Util qw( any );
my %ok = map { $_ => 1 } qw( B S G D L );
return 0 if any { !$ok{$_} } #hon_data;
A similar approach can be used to find the difference of sets.
my %ok = map { $_ => 1 } qw( B S G D L );;
my #diff = grep { !$ok{ $_ } } #hon_data; # diff = hon_data - { B, S, G, D, L }
The data are stock options. I want to make a 2D array based on days till expiration (int) & normalized distance out of the money (float), with the values being a list of normalized bid and ask prices. If the desired element is not in the array, I want to be able to interpolate between the nearest elements present.
I see 3 possible data structures:
A sparse 2D array, maybe 10000 elements, maybe 1/3 full.
A 2D linked list, ie: 4 listpointers for each data element (so 3000 elements becomes 15000)
A 2D hash (maybe 3000 elements), with 2 sorted lists of the keys (maybe 100 elements each) in each dimension.
The main problem is efficient retrieval when interpolation is required.
Retrieval of existing elements is relatively straight-forward with any method.
I'm currently using choice 3, but retrieval is a bit of a kloodge, since I have to scan along the keylists of each dimension till I find occupied elements, and then do a 2- or 4-way interpolation.
I use moreUtils::firstindx($_ > $desiredKey) to find the keys. The linked lists (choice 2) would spare me the search of the keylist arrays.
Choice 1 would also require scanning, wouldn't need the initial step of keylist lookup, but might need to look at more empty cells. And insertion would be a real hassle.
I would be doing many more searches than insertions.
Does any one have any suggestions for the most efficient data structure.
Since you predominantly perform lookups by lifespan and lookups by distance, and few inserts, I'd use sorted arrays to lookup the records by binary search.
Locating an existing element: O(log N)
Locating the box of a missing element: O(log N)
Inserting: O(N)
Given,
my #data = (
[ $lifespan0, $distance0, $bid0, $ask0 ],
[ $lifespan1, $distance1, $bid1, $ask1 ],
...
);
my $lifespan_search_cmp = sub { $a <=> $data[$b][0] };
my $distance_search_cmp = sub { $a <=> $data[$b][1] };
First, create indexes:
my #by_lifespan = sort { $data[$a][0] <=> $data[$b][0] } 0..$#data;
my #by_distance = sort { $data[$a][1] <=> $data[$b][1] } 0..$#data;
To lookup:
my $i = binsearch_first \&$lifespan_search_cmp, $lifespan, #by_lifespan;
my $j = binsearch_first \&$distance_search_cmp, $distance, #by_distance;
my #lifespan_matching_idxs = get_run_forward \&$lifespan_search_cmp, $lifespan, $i, #by_lifespan;
my #distance_matching_idxs = get_run_forward \&$distance_search_cmp, $distance, $j, #by_distance;
my #cross_match_idxs = do {
my %lifespan_matching_idxs = map { $_ => 1 } #lifespan_matching_idxs;
grep { $lifespan_matching_idxs{$_} }
#distance_matching_idxs
};
if (#cross_match_idxs) {
# Exact match(es) found.
...
} else {
my $lifespan_lowerbracket;
my $lifespan_upperbracket;
if ($i >= 0) {
$lifespan_lowerbracket = $lifespan;
$lifespan_upperbracket = $lifespan;
} else {
die "Can't interpolate" if ~$i == 0 || ~$i >= #by_lifespan;
$lifespan_lowerbracket = $data[~$i ][0];
$lifespan_lowerbracket = $data[~$i - 1][0];
}
my $distance_lowerbracket;
my $distance_upperbracket;
if ($i >= 0) {
$distance_lowerbracket = $distance;
$distance_upperbracket = $distance;
} else {
die "Can't interpolate" if ~$j == 0 || ~$j >= #by_distance;
$distance_lowerbracket = $data[~$j ][1];
$distance_upperbracket = $data[~$j - 1][1];
}
...
}
To insert:
my $i = binsearch_first \&$lifespan_search_cmp, $lifespan, #by_lifespan;
my $j = binsearch_first \&$distance_search_cmp, $distance, #by_distance;
push #data, [ $lifespan, $distance , $bid, $ask ];
splice(#by_lifespan, $i >= 0 ? $i : ~$i, 0, $#data);
splice(#by_distance, $j >= 0 ? $j : ~$j, 0, $#data);
Subs:
sub binsearch_first(&$\#) {
my $compare = $_[0];
#my $value = $_[1];
my $array = $_[2];
my $min = 0;
my $max = $#$array;
return -1 if $max == -1;
my $ap = do { no strict 'refs'; \*{caller().'::a'} }; local *$ap;
my $bp = do { no strict 'refs'; \*{caller().'::b'} }; local *$bp;
*$ap = \($_[1]);
while ($min <= $max) {
my $mid = int(($min+$max)/2);
*$bp = \($array->[$mid]);
my $cmp = $compare->();
if ($cmp < 0) {
$max = $mid - 1;
}
elsif ($cmp > 0) {
$min = $mid + 1;
}
else {
return $mid if $mid == $min;
$max = $mid;
}
}
# Converts unsigned int to signed int.
return unpack('j', pack('J', ~$min));
}
sub get_run_forward(&$\#) {
my $compare = $_[0];
#my $value = $_[1];
my $start = $_[2];
my $array = $_[3];
return if $start < 0;
my $ap = do { no strict 'refs'; \*{caller().'::a'} }; local *$ap;
my $bp = do { no strict 'refs'; \*{caller().'::b'} }; local *$bp;
*$ap = \($_[1]);
my $i = $start;
while ($i <= $#$array) {
*$bp = \($array->[$i]);
my $cmp = $compare->()
and last;
++$i;
}
return wantarray ? ($start..$i-1) : $i-1;
}
You might want to use a tolerance in the floating-point comparions (i.e. in $distance_search_cmp).
I have several pairs of numbers and want to check whether the first one falls into a given interval. If so, I want to increment one of two counters for that interval, depending on whether the second number of the pair is higher or lower than the first.
The intervals are simple and look like 1-10,11-20,21-30 etc. The pairs of numbers look like (5,15),(24,13) etc. But I have several thousand of each. The exact format of input does not matter so much.
The desired outcome looks like this
1-10: higher=1, lower=0
11-20: higher=0,lower=0
21-30: higher=0,lower=1
My idea was to create a hash with the interval start as key and store the two counters in the value.
for(my $i = $start;$i<=$end;$i = ($i+$intervalsize)){
my $counter1 = 0;
my $counter2 = 0;
#{$hash{$i}} = ($counter1,$counter2);
but now I don't know how to compare the numbers with the keys and how to address the counters.
Thank you for any help!
Something like this maybe?
#!/usr/bin/env perl
use strict;
use warnings;
use List::MoreUtils qw( first_index );
sub interval_to_key { sprintf '(%d,%d)', #{ $_[0] } }
my #intervals = (
[ 1, 10 ],
[ 11, 20 ],
[ 21, 30 ],
);
my #upper_bounds = map $_->[0], #intervals;
my #pairs = (
[ 5, 15 ],
[ 24, 13 ],
);
my #keys = qw( ascending descending );
my %counts;
for my $interval ( #intervals ) {
#{ $counts{ interval_to_key($interval) } }{ #keys } = (0) x #keys;
}
for my $pair ( #pairs ) {
my $is_ascending = ($pair->[0] <= $pair->[1]);
my $i = first_index { $pair->[0] <= $_ } #upper_bounds;
++ $counts{ interval_to_key( $intervals[$i]) }{ $keys[1 - $is_ascending] };
}
use Data::Dumper;
print Dumper \%counts;
If the counters are to be kept for each interval we can record them in a data structure of choice. For example, store counters for each interval in a hash with the key being the interval index and low-high counters being in a two-element refarray as its value.
use warnings 'all';
use strict;
my #intervals = ( [1,10], [11,20], [21,30] );
my #pairs = ( [5,15], [24, 13] );
my %counter = map { $_ => [0,0] } (0..$#intervals); # initialize
foreach my $i (0..$#intervals)
{
foreach my $pair (#pairs)
{
my ($beg, $end) = #{$intervals[$i]};
my ($pl, $pr) = #$pair;
if ($pl >= $beg and $pl <= $end)
{
if ($pr > $pl) { ++$counter{$i}[1] }
else { ++$counter{$i}[0] }
}
}
}
print "$_ => #{$counter{$_}}\n" for sort keys %counter;
This is still rudimentary, in order to be easier to adjust. For one thing, since the hash uses the index of #intervals array it may well be an array (with arrayrefs) itself. Another possibility is to use a hash with keys like low and high for counters instead of a two-element array.
In order to use start of interval as a key
my %counter = map { $_->[0] => [0,0] } #intervals; # initialize
for my $inter (#intervals) {
for my $pair (#pairs) {
my ($beg, $end) = #$inter;
my ($pl, $pr) = #$pair;
if ($pl >= $beg and $pr <= $end)
{
if ($pr > $pl) { ++$counter{$beg}[1] }
else { ++$counter{$end}[0] }
}
}
}
printf("%3d => #{$counter{$_}}\n", $_) for sort keys %counter;
I have a set of hashes (with preserved key sequence using Tie::IxHash), and I'd like to compare their values for each key. The number of hashes can vary. For example, I'd like to count how many times the key "1" is assigned the values "1" and "0". I know there should be a nice fast way to count the value matches if I put the hashes in an array of hashes and then loop through them, but I'm stuck and can't figure it out on my own.
%hash1 = ( 1 => '1',
2 => '1',
3 => '0',
4 => '0',
);
%hash2 = ( 1 => '1',
2 => '1',
3 => '1',
4 => '0',
);
%hash3 = ( 1 => '1',
2 => '1',
3 => '0',
4 => '1',
);
%hash4 = ( 1 => '1',
2 => '0',
3 => '0',
4 => '1',
);
The intended result for the above is:
$key1: $agr1 = 4; $agr0 = 0;
$key2: $agr1 = 3; $agr0 = 1;
$key3: $agr1 = 1; $agr0 = 3;
$key4: $agr1 = 2; $agr0 = 2;
Right now what I ended up doing is looping through the keys of the first hash and then subsequently comparing them to each of the other hashes, which is tedious and stupid for obvious reasons.
Thanks for your help!
Correction: I'm using hashes, not hash-refs. Edited the above code accordingly.
This allows a bit of flexibility in your result as you can put any desired values in #wanted. Assumes your hashes are actually hash references (ambiguous in your sample):
my #hashes = ($hash1,$hash2,$hash3,$hash4);
my %count;
for my $hash (#hashes) {
$count{ $_ }{ $hash->{$_} }++ for keys %$hash;
}
my #wanted = (1,0);
for my $key (sort { $a <=> $b } keys %count) {
my #result = map { "agr$_ = " . ($count{$key}{$_} || 0) . ';' } #wanted;
print "key $key: #result\n";
}
Output:
key 1: agr1 = 4; agr0 = 0;
key 2: agr1 = 3; agr0 = 1;
key 3: agr1 = 1; agr0 = 3;
key 4: agr1 = 2; agr0 = 2;
Pseudoperl:
# Build a list of refs to your hashes
#a = { \%hash1, \%hash2, ... }
# A container to hold the keys and counts
$keys = {}
# Initialize the key container
for my $h in #a
for my $k in %$h
$keys->{$k} = {0 => 0, 1 => 0} unless exists $keys->{$k}
# Iterate once over all the keys and count occurrences
# assumes input hash values can be only 0 or 1
for my $k in %$keys
for my $h in #a
$keys->{$k}->{$h->{$k}}++ if exists $h->{$k};
First, your hash examples are wrong. %hash = {}.
If you use the % sigil you want (). If you want a hash-ref, it would be $hash = {}.
Back to your question. You could do something like this.
Which is commonly referred to as a "seen" hash.
# appending your example above....
my #arr = (\%hash1, \%hash2, \%hash3, \%hash4);
my $seen = {};
# iterate over each hash
for my $hash (#arr) {
# iterate over each key in hash
for my $k (keys %$hash) {
my $val = $hash->{$k};
# check $val and increment
if ($val) {
$seen->{$k}{1}++;
} else {
$seen->{$k}{0}++;
}
}
}
for my $k ( sort keys %$seen ) {
# in case any value is 0/undef
print "$k: 1 = "
. ( $seen->{$k}->{0} ? $seen->{$k}->{0} : 0 ) . " 0 = "
. ( $seen->{$k}->{0} ? $seen->{$k}->{0} : 0 ) . "\n";
}
Which OUTPUTS:
$ perl test.pl
1: 1 = 0 0 = 0
2: 1 = 1 0 = 1
3: 1 = 3 0 = 3
4: 1 = 2 0 = 2
I am beginning to delve deeper into Perl, but am having trouble writing "Perl-ly" code instead of writing C in Perl. How can I change the following code to use more Perl idioms, and how should I go about learning the idioms?
Just an explanation of what it is doing: This routine is part of a module that aligns DNA or amino acid sequences(using Needelman-Wunch if you care about such things). It creates two 2d arrays, one to store a score for each position in the two sequences, and one to keep track of the path so the highest-scoring alignment can be recreated later. It works fine, but I know I am not doing things very concisely and clearly.
edit: This was for an assignment. I completed it, but want to clean up my code a bit. The details on implementing the algorithm can be found on the class website if any of you are interested.
sub create_matrix {
my $self = shift;
#empty array reference
my $matrix = $self->{score_matrix};
#empty array ref
my $path_matrix = $self->{path_matrix};
#$seq1 and $seq2 are strings set previously
my $num_of_rows = length($self->{seq1}) + 1;
my $num_of_columns = length($self->{seq2}) + 1;
#create the 2d array of scores
for (my $i = 0; $i < $num_of_rows; $i++) {
push(#$matrix, []);
push(#$path_matrix, []);
$$matrix[$i][0] = $i * $self->{gap_cost};
$$path_matrix[$i][0] = 1;
}
#fill out the first row
for (my $i = 0; $i < $num_of_columns; $i++) {
$$matrix[0][$i] = $i * $self->{gap_cost};
$$path_matrix[0][$i] = -1;
}
#flag to signal end of traceback
$$path_matrix[0][0] = 2;
#double for loop to fill out each row
for (my $row = 1; $row < $num_of_rows; $row++) {
for (my $column = 1; $column < $num_of_columns; $column++) {
my $seq1_gap = $$matrix[$row-1][$column] + $self->{gap_cost};
my $seq2_gap = $$matrix[$row][$column-1] + $self->{gap_cost};
my $match_mismatch = $$matrix[$row-1][$column-1] + $self->get_match_score(substr($self->{seq1}, $row-1, 1), substr($self->{seq2}, $column-1, 1));
$$matrix[$row][$column] = max($seq1_gap, $seq2_gap, $match_mismatch);
#set the path matrix
#if it was a gap in seq1, -1, if was a (mis)match 0 if was a gap in seq2 1
if ($$matrix[$row][$column] == $seq1_gap) {
$$path_matrix[$row][$column] = -1;
}
elsif ($$matrix[$row][$column] == $match_mismatch) {
$$path_matrix[$row][$column] = 0;
}
elsif ($$matrix[$row][$column] == $seq2_gap) {
$$path_matrix[$row][$column] = 1;
}
}
}
}
You're getting several suggestions regarding syntax, but I would also suggest a more modular approach, if for no other reason that code readability. It's much easier to come up to speed on code if you can perceive the big picture before worrying about low-level details.
Your primary method might look like this.
sub create_matrix {
my $self = shift;
$self->create_2d_array_of_scores;
$self->fill_out_first_row;
$self->fill_out_other_rows;
}
And you would also have several smaller methods like this:
n_of_rows
n_of_cols
create_2d_array_of_scores
fill_out_first_row
fill_out_other_rows
And you might take it even further by defining even smaller methods -- getters, setters, and so forth. At that point, your middle-level methods like create_2d_array_of_scores would not directly touch the underlying data structure at all.
sub matrix { shift->{score_matrix} }
sub gap_cost { shift->{gap_cost} }
sub set_matrix_value {
my ($self, $r, $c, $val) = #_;
$self->matrix->[$r][$c] = $val;
}
# Etc.
One simple change is to use for loops like this:
for my $i (0 .. $num_of_rows){
# Do stuff.
}
For more info, see the Perl documentation on foreach loops and the range operator.
I have some other comments as well, but here is the first observation:
my $num_of_rows = length($self->{seq1}) + 1;
my $num_of_columns = length($self->{seq2}) + 1;
So $self->{seq1} and $self->{seq2} are strings and you keep accessing individual elements using substr. I would prefer to store them as arrays of characters:
$self->{seq1} = [ split //, $seq1 ];
Here is how I would have written it:
sub create_matrix {
my $self = shift;
my $matrix = $self->{score_matrix};
my $path_matrix = $self->{path_matrix};
my $rows = #{ $self->{seq1} };
my $cols = #{ $self->{seq2} };
for my $row (0 .. $rows) {
$matrix->[$row]->[0] = $row * $self->{gap_cost};
$path_matrix->[$row]->[0] = 1;
}
my $gap_cost = $self->{gap_cost};
$matrix->[0] = [ map { $_ * $gap_cost } 0 .. $cols ];
$path_matrix->[0] = [ (-1) x ($cols + 1) ];
$path_matrix->[0]->[0] = 2;
for my $row (1 .. $rows) {
for my $col (1 .. $cols) {
my $gap1 = $matrix->[$row - 1]->[$col] + $gap_cost;
my $gap2 = $matrix->[$row]->[$col - 1] + $gap_cost;
my $match_mismatch =
$matrix->[$row - 1]->[$col - 1] +
$self->get_match_score(
$self->{seq1}->[$row - 1],
$self->{seq2}->[$col - 1]
);
my $max = $matrix->[$row]->[$col] =
max($gap1, $gap2, $match_mismatch);
$path_matrix->[$row]->[$col] = $max == $gap1
? -1
: $max == $gap2
? 1
: 0;
}
}
}
Instead of dereferencing your two-dimensional arrays like this:
$$path_matrix[0][0] = 2;
do this:
$path_matrix->[0][0] = 2;
Also, you're doing a lot of if/then/else statements to match against particular subsequences: this could be better written as given statements (perl5.10's equivalent of C's switch). Read about it at perldoc perlsyn:
given ($matrix->[$row][$column])
{
when ($seq1_gap) { $path_matrix->[$row][$column] = -1; }
when ($match_mismatch) { $path_matrix->[$row][$column] = 0; }
when ($seq2_gap) { $path_matrix->[$row][$column] = 1; }
}
The majority of your code is manipulating 2D arrays. I think the biggest improvement would be switching to using PDL if you want to do much stuff with arrays, particularly if efficiency is a concern. It's a Perl module which provides excellent array support. The underlying routines are implemented in C for efficiency so it's fast too.
I would always advise to look at CPAN for previous solutions or examples of how to do things in Perl. Have you looked at Algorithm::NeedlemanWunsch?
The documentation to this module includes an example for matching DNA sequences. Here is an example using the similarity matrix from wikipedia.
#!/usr/bin/perl -w
use strict;
use warnings;
use Inline::Files; #multiple virtual files inside code
use Algorithm::NeedlemanWunsch; # refer CPAN - good style guide
# Read DNA sequences
my #a = read_DNA_seq("DNA_SEQ_A");
my #b = read_DNA_seq("DNA_SEQ_B");
# Read Similarity Matrix (held as a Hash of Hashes)
my %SM = read_Sim_Matrix();
# Define scoring based on "Similarity Matrix" %SM
sub score_sub {
if ( !#_ ) {
return -3; # gap penalty same as wikipedia)
}
return $SM{ $_[0] }{ $_[1] }; # Similarity Value matrix
}
my $matcher = Algorithm::NeedlemanWunsch->new( \&score_sub, -3 );
my $score = $matcher->align( \#a, \#b, { align => \&check_align, } );
print "\nThe maximum score is $score\n";
sub check_align {
my ( $i, $j ) = #_; # #a[i], #b[j]
print "seqA pos: $i, seqB pos: $j\t base \'$a[$i]\'\n";
}
sub read_DNA_seq {
my $source = shift;
my #data;
while (<$source>) {
push #data, /[ACGT-]{1}/g;
}
return #data;
}
sub read_Sim_Matrix {
#Read DNA similarity matrix (scores per Wikipedia)
my ( #AoA, %HoH );
while (<SIMILARITY_MATRIX>) {
push #AoA, [/(\S+)+/g];
}
for ( my $row = 1 ; $row < 5 ; $row++ ) {
for ( my $col = 1 ; $col < 5 ; $col++ ) {
$HoH{ $AoA[0][$col] }{ $AoA[$row][0] } = $AoA[$row][$col];
}
}
return %HoH;
}
__DNA_SEQ_A__
A T G T A G T G T A T A G T
A C A T G C A
__DNA_SEQ_B__
A T G T A G T A C A T G C A
__SIMILARITY_MATRIX__
- A G C T
A 10 -1 -3 -4
G -1 7 -5 -3
C -3 -5 9 0
T -4 -3 0 8
And here is some sample output:
seqA pos: 7, seqB pos: 2 base 'G'
seqA pos: 6, seqB pos: 1 base 'T'
seqA pos: 4, seqB pos: 0 base 'A'
The maximum score is 100