+sub equalpiles ($@) {
+ my ($how, @sorted) = @_;
+ return () unless @sorted;
+ my $s = $sorted[0];
+ my $eqtotal = $s->{Total};
+ my $count = 0/1;
+ while ($count < @sorted && $sorted[$count]{Total} == $eqtotal) {
+ printf "%7s %10s %s\n", $how, $sorted[$count]{Cand},
+ pr $sorted[$count]{Total};
+ $count++;
+ }
+ return @sorted[ 0 .. $count-1 ];
+}
+
+sub historically_prefer ($@) {
+ my ($signum, @choices) = @_;
+ # $signum==+1 means choose candidates with more early preferences
+
+ return $choices[0] if @choices < 2;
+
+ my $compare = sub {
+ foreach my $sr (@stagerecord) {
+ my $d = ($sr->{ $a->{Cand} }//0) <=> ($sr->{ $b->{Cand} }//0);
+ return -$d * $signum if $d;
+ }
+ return 0;
+ };
+
+ @choices = sort $compare @choices;
+
+ print DEBUG "historically_prefer\n",
+ Data::Dumper->Dump([\@choices, \@stagerecord],
+ [qw(_@choices _@stagerecord)]);
+
+ foreach my $s (@choices) {
+ my $c = $s->{Cand};
+ printf " %6s %10s |", 'tiebrk', $c;
+ foreach my $sr (@stagerecord) {
+ my $p = pr($sr->{$c} // 0);
+ $p =~ s/\.0+\b//g;
+ $p =~ s/ //g;
+ print "$p|";
+ }
+ print "\n";
+ }
+
+ $a = $choices[0];
+ my $numequal = 1;
+ for (;;) {
+ last if $numequal >= @choices;
+ $b = $choices[$numequal];
+ last if $compare->();
+ $numequal++;
+ }
+
+ if ($numequal > 1) {
+ my $how = $signum > 0 ? 'winner' : 'loser';
+ my @all = sort map { $_->{Cand} } @choices[ 0 .. $numequal-1 ];
+ my $hower = $tiebreak{$how}{"@all"};
+ if (defined $hower) {
+ printf "%7.7s %10s !!!!!!!!!!\n", "TIE".(uc $how), $hower;
+ return grep { $_->{Cand} eq $hower } @choices;
+ }
+ die "need tie break for $how between @all\n";
+ }
+
+ return $choices[0];
+}
+
+foreach my $c (keys %continuing) {
+ $sorted{$c} = {
+ Cand => $c,
+ Votes => [],
+ };
+}
+