#!/usr/bin/perl -w use strict qw(refs vars); our %s; my $bs= $ARGV[2]; foreach my $ab (qw(0 1)) { open F, "zcat $ARGV[$ab] |" or die $!; while () { chomp; my @l= split /\t/, $_, -1; @l == 6 or die "$#l"; if ($bs) { @l= ($l[0],$l[1],$l[4],$l[5]); } next unless length $l[2]; $l[3]='1001' if $l[3] eq '>1000'; $s{$l[1]}{$l[0]}[$ab*2]= $l[2]; $s{$l[1]}{$l[0]}[$ab*2+1]= $l[3]; } close F or die $!; } my $nextcommod=0; my %commodmap; sub alencodenum ($) { my ($val) = @_; my $res= ''; while ($val || !length($res)) { # allowing empty strings, reusing "0" for 62, doing base63, # saves 0.5% my $dig= $val % 62; $val= ($val-$dig) / 62; $res = chr($dig + ($dig<10 ? 48 : $dig<36 ? 97-10 : $dig<62 ? 65-36 : die $dig)) . $res; } return $res; } sub findcommod ($) { my ($cname) = @_; my $me= $commodmap{$cname}; return $me if defined $me; my $val= $nextcommod++; $commodmap{$cname}= $val; printf "%s:%s\n", alencodenum($val),$cname; return $val; } my $laststall=''; foreach my $stall (sort keys %s) { my $stallstuff= $s{$stall}; foreach my $commod (sort { findcommod($a) <=> findcommod($b) } keys %$stallstuff) { my @r= @{ $s{$stall}{$commod} }; my $eol= ''; my $prep= sub { return if $eol; $eol="\n"; if ($stall ne $laststall) { printf "\"%s\n", $stall; $laststall= $stall; } print alencodenum(findcommod($commod)); }; if (!defined($r[2])) { $prep->(); printf "\n"; # no "-" here saves 3.5% next; } # base62-encoding all these numbers saves about 8% my $qtydiff= $r[3] - ($r[1] || 0); if (!defined($r[0]) || $r[0] != $r[2]) { $prep->(); printf "\@%s",alencodenum($r[2]); } if ($qtydiff>0) { $prep->(); printf "+%s",alencodenum($qtydiff); } elsif ($qtydiff<0) { $prep->(); printf "-%s",alencodenum(-$qtydiff); } print $eol; }}