1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
|
#!/usr/bin/perl
use warnings;
use strict;
my $n = 0;
my $q;
my $max = 0;
my (@char, @count);
if (!defined $ARGV[0]) {
while (<STDIN>) {
($char[$n], $count[$n]) = split /\s+/, $_, 2;
if ($max < $count[$n]) {
$max = $count[$n];
}
$n++;
}
for ($q = 1; $max/$q >= 6000; $q++) { }
for (my $i = 0; $i < $n; $i++) {
printf "%s %u\n", $char[$i], $count[$i]/$q;
}
}
else {
my @err;
my $sum = 0;
open FH, "<".$ARGV[0];
while (<FH>) {
my ($char, $count) = split /\s+/, $_, 2;
$sum += $count;
}
close FH;
my $sum2 = 0;
while (<STDIN>) {
($char[$n], $count[$n]) = split /\s+/, $_, 2;
$sum2 += $count[$n];
$n++;
}
for (my $i = 0; $i < $n; $i++) {
my $x = $count[$i]*$sum/$sum2;
$count[$i] = int $x;
$err[$i] = $count[$i] - $x;
}
$sum2 = 0;
for (my $i = 0; $i < $n; $i++) {
$sum2 += $count[$i];
}
while ($sum2 != $sum) {
$max = 0;
for (my $i = 0; $i < $n; $i++) {
if ($err[$i]*($sum - $sum2) > $err[$max]*($sum - $sum2)) {
$max = $i;
}
}
$count[$max] += $sum2 > $sum ? -1 : 1;
$err[$max] -= $sum2 > $sum ? -1 : 1;
$sum2 += $sum2 > $sum ? -1 : 1;
}
for (my $i = 0; $i < $n; $i++) {
printf "%s %u\n", $char[$i], $count[$i];
}
}
|