chiark / gitweb /
stv: wip, delay transfer
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Mon, 1 Aug 2016 14:19:44 +0000 (15:19 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Mon, 1 Aug 2016 14:19:44 +0000 (15:19 +0100)
stv

diff --git a/stv b/stv
index 762da63..47984e8 100755 (executable)
--- a/stv
+++ b/stv
@@ -6,7 +6,9 @@
 use strict;
 use utf8;
 use autodie;
-use bigrat;
+#use bigrat;
+use Data::Dumper;
+use List::Util qw(sum);
 use List::MoreUtils qw(nsort_by);
 
 # vote is
@@ -20,6 +22,8 @@ our @allvotes;
 our $places = shift @ARGV;
 die unless $places eq ($places + 0);
 
+open DEBUG, ">.stv.log" or die $!;
+
 while (<>) {
     next if m/^\w+$/;
     m/^(\w+) ([A-Z]+)$/ or die "$_ ?";
@@ -60,7 +64,6 @@ our %sorted;
 # $sorted{$firstpref}{Votes} = [ $vote, ... ]
 # $sorted{$firstpref}{Cand} = $firstpref
 # $sorted{$firstpref}{Total} = $totalweight
-our @sorted; # values same as %sorted
 our @surpluses; # values same as %sorted
 
 our @exhausted; # votes
@@ -79,15 +82,48 @@ sub equalpiles ($@) {
     my $s = $sorted[0];
     my $eqtotal = $s->{Total};
     my $count = 0;
-    while ($count < @$sorted && $sorted[$count]{Total} == $eqtotal) {
+    while ($count < @sorted && $sorted[$count]{Total} == $eqtotal) {
        printf "%7s %10s\n", $how, $sorted[$count]{Cand};
        $count++;
     }
-    
+    return @sorted[ 0 .. $count-1 ];
+}
+
+sub historically_prefer ($@) {
+    my ($signum, @choices) = @_;
+
+    return $choices[0] if @choices < 2;
+
+    my $compare = sub {
+       foreach my $sr (@stagerecord) {
+           my $d = $sr->{ $a->{Cand} } <=> $sr->{ $b->{Cand} };
+           return $d * $signum if $d;
+       }
+       return 0;
+    };
+
+    @choices = sort $compare, @choices;
+    $a = $choices[0];
+    my $numequal = 0;
+    for (;;) {
+       last unless $numequal >= @choices;
+       $b = $choices[$numequal];
+       last if $compare->();
+    }
+
+    die 'random choice unimplemented' if $numequal > 1;
+    return $choices[0];
+}
 
 for (;;) {
     $stage++;
 
+    print DEBUG "#################### $stage ####################\n",
+       Data::Dumper->Dump(
+[ \@stagerecord, \@elected, \@unsorted, \%sorted, \@surpluses, \%continuing ],
+[qw( _@stagerecord _@elected _@unsorted _%sorted _@surpluses _%continuing )]
+          );
+
     while (my $vote = shift @unsorted) {
        my ($firstpref) = grep { $continuing{$_} } @{ $vote->{Prefs} };
        if (!defined $firstpref) {
@@ -158,11 +194,11 @@ for (;;) {
        printf "%7s %10s\n", 'derate', $s->{Cand}, pr $derate;
 
        foreach my $vote (@{ $s->{Votes} }) {
-           votelog $vote, "elected $s->{Cand}, derated $weightmult";
+           votelog $vote, "elected $s->{Cand}, derated $derate";
            $vote->{Weight} /= $derate;
        }
        push @surpluses, $s;
-       delete %sorted{ $s->{Cand} };
+       delete $sorted{ $s->{Cand} };
        delete $continuing{ $s->{Cand} };
 
        $sort_update->();
@@ -200,8 +236,8 @@ for (;;) {
            printf "%7s %10s\n", 'ELIM', $c;
            my $votes = $s->{Votes};
            votelog $_, "failed to stop $c elimination" foreach @$votes;
-           delete %continuing{$c};
-           delete %sorted{$c};
+           delete $continuing{$c};
+           delete $sorted{$c};
            push @unsorted, @$votes;
        }