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];
}
}
|