#!/usr/bin/perl -w use strict 'vars'; $::gVersion = '1.001'; $::gMaxRounds = 50; # very simple binary search sub search { local(*sub) = shift @_; my($low, $high) = @_; my $mid; while ($high - $low > 1) { $mid = int(($low+$high)/2); if (&sub($mid) < 0) { $low = $mid; } else { $high = $mid; } } $mid; } sub lint { $::gVersion = 1; @::gOldRs = (); &lint; } { # parse input my ($i, @lines); # read input, joining continuation lines @lines = (''); while (<>) { chomp; s/\s*#.*//; next unless /\S/; if (s/\s*\\\s*$//) { $lines[-1] .= "$_ "; } else { $lines[-1] .= $_; push(@lines, ''); } } pop(@lines) unless $lines[-1] =~ /\S/; # parse each line $i = 1; for $_ (@lines) { /^([^\d]+\S)\s+(\d+)\s+([\d\s]+);\s*([-\d\s]+)$/ || die "Can't parse: $_\n"; $::gNames[$i] = $1; $::gOldRs[$i] = $2; my $opps = $3; my $scores = $4; $::gOpps[$i] = [split(/\s+/, $opps)]; $::gScores[$i] = [split(/\s+/, $scores)]; $i++; } } { # calculate stats my ($i, $maxRounds); $maxRounds = $::gMaxRounds-1 < $#{$::gOpps[1]} ? $::gMaxRounds-1 : $#{$::gOpps[1]}; for $i (1..$#::gNames) { my ($cum, $j, $opp, $opps, $scores, $sub, $wins); $cum = $wins = 0; $opps = $::gOpps[$i]; $scores = $::gScores[$i]; $sub = "sub it$i {"; for $j (0..$maxRounds) { my $spread = $scores->[$j] - $::gScores[$opps->[$j]]->[$j]; $wins += (1+($spread<=>0))/2; $cum += $spread; $sub .= "\$::gLogit[\$_[0]-\$::gCurrR[$opps->[$j]]]+"; } $::gCums[$i] = $cum; $::gWins[$i] = $wins; $sub .= "-$wins;}"; eval $sub; die "eval failed: $@" if length($@); } } { # calculate logit table my $i; $#::gLogit = 5000; print STDERR "Calculating logit table..."; for $i (-2000..2000) { $::gLogit[$i] = 1/(1+exp(-$i/172)); } print STDERR " done.\n"; } { # calculate logit performance ratings my ($done, $i); for $i (1..$#::gNames) { $::gCurrR[$i] = 1800; } for ($done=0; !$done; ) { for $i (1..$#::gNames) { $::gNewR[$i] = &search("it$i", 0, 3000); } $done = 1; for $i (1..$#::gNames) { if ($::gNewR[$i] != $::gCurrR[$i]) { $done = 0; } } for $i (1..$#::gNames) { $::gCurrR[$i] = $::gNewR[$i]; } } } if (1) { my ($i, $j, $offset); $j=1; for $i (sort { $::gWins[$b]<=>$::gWins[$a] || $::gCums[$b]<=>$::gCums[$a] } (1..$#::gNames)) { $::gWLRank[$i] = $j++; } $j=1; # for $i (sort { $::gWins[$b]<=>$::gWins[$a] || $::gCums[$b]<=>$::gCums[$a] } for $i (sort { $::gCurrR[$b] <=> $::gCurrR[$a] } (1..$#::gNames)) { $offset = 2200-$::gCurrR[$i] unless $offset; printf "%3d %3d %3d %22s %4d %4.1f %+5d\n", $j, $::gWLRank[$i], $i, $::gNames[$i], $::gCurrR[$i]+$offset, $::gWins[$i], $::gCums[$i]; $j++; } }