The George Score at Where's George is based on the following formula:
This Perl script calculates how many bills you need to enter or how many hits you need to get to increase the George Score by 1. It does that two ways: by using derivatives and by solving the George Score equation.
Example:
GS = 100 *
(sqrt(log(BillsEntered)) + log(TotalHits + 1)) *
(1 - DaysInactive / 90)
This Perl script calculates how many bills you need to enter or how many hits you need to get to increase the George Score by 1. It does that two ways: by using derivatives and by solving the George Score equation.
#!perl -w
use strict;
require 5.004;
# Calculate george score.
# be = bills entered, th = total hits, di = days of inactivity
sub gs {
my $be = shift;
my $th = shift;
my $di = shift;
100 * (sqrt(log($be)) + log($th + 1)) * (1 - $di / 90);
}
# Takes a function with one argument.
# Uses linear interpolation to find out how large the function's argument
# must be to raise the function's value by 1.
sub solve1gs {
my $fn = shift;
my $cur_gs = $fn->(0);
my $upper;
for ($upper = 1; $upper < 1e9; $upper *= 2) {
last if $fn->($upper) - $cur_gs >= 1;
}
my $a = 0;
my $b = $upper;
my $itercount = 0;
my $xold = $a;
for (;;) {
my $fa = $fn->($a) - $cur_gs - 1;
my $fb = $fn->($b) - $cur_gs - 1;
my $newx = $a - $fa * ($b - $a) / ($fb - $fa);
my $newfx = $fn->($newx) - $cur_gs - 1;
++$itercount;
print " $itercount: $newx $newfx\n";
return $newx if abs($newx - $xold) < 1e-10 * abs($newx);
$xold = $newx;
if ($fa * $newfx > 0) {
$a = $newx;
}
else {
$b = $newx;
}
}
}
@ARGV >= 2 or die "Usage: $0 bills-entered total-hits [days-inactive]\n";
my ($be, $th, $di) = @ARGV;
defined $di or $di = 0;
print "Bills Entered = $be\n";
print "Total Hits = $th\n";
print "Days Inactive = $di\n";
printf "George Score = %.3f\n", gs($be, $th, $di);
print "\n";
my $hitpred = ($th + 1) / 100;
my $billpred = $be * sqrt(log($be)) / 50;
printf "Hits needed for 1GS = %.0f\n", $hitpred;
printf "Bills needed for 1GS = %.0f\n", $billpred;
printf "Bill/Hit ratio = %.3f\n", $billpred / $hitpred;
print "\n";
$hitpred = solve1gs
sub {
my $incrhits = shift;
gs($be, $th + $incrhits, $di);
};
$billpred = solve1gs
sub {
my $incrbills = shift;
gs($be + $incrbills, $th, $di);
};
print "\n";
printf "Hits needed for 1GS = %.2f\n", $hitpred;
printf "Bills needed for 1GS = %.2f\n", $billpred;
printf "Bill/Hit ratio = %.3f\n", $billpred / $hitpred;
__END__
Example:
C:\temp>gs.pl Usage: C:\temp\gs.pl bills-entered total-hits [days-inactive] C:\temp>gs.pl 93460 26424 Bills Entered = 93460 Total Hits = 26424 Days Inactive = 0 George Score = 1356.515 Hits needed for 1GS = 264 Bills needed for 1GS = 6324 Bill/Hit ratio = 23.931 1: 266.801812199827 0.00459382687245125 2: 265.58177550269 2.28931100991758e-005 3: 265.57569564905 1.14084741653642e-007 4: 265.575665350918 5.68661562283523e-010 5: 265.575665199896 2.72848410531878e-012 6: 265.575665199171 0 1: 6609.01652641187 0.00832274145204792 2: 6554.46540548562 0.000287633121843101 3: 6552.58066625246 9.93870207821601e-006 4: 6552.51554275262 3.4341360333201e-007 5: 6552.51329253042 1.18661773740314e-008 6: 6552.51321477713 4.09954736824147e-010 7: 6552.5132120909 1.43245415529236e-011 8: 6552.51321199704 4.54747350886464e-013 Hits needed for 1GS = 265.58 Bills needed for 1GS = 6552.51 Bill/Hit ratio = 24.673 C:\temp>