use v5.32; use HTML::TableExtract; use File::Slurp; use Data::Dumper; use List::Util qw(sum); use Text::SimpleTable::AutoWidth; use WWW::Mechanize (); use experimental qw/ signatures /; unless(caller) { my $ts = get_mersenne_results(); generate_output_table($ts)->draw; } sub get_mersenne_results() { # log in to Mersenne.org and get results for the last year # excluding everything but PHP and DD results my $mech = WWW::Mechanize->new; my $url = 'https://www.mersenne.org/results/?extf=1&exp1=1&execm=1&excert=1&exp_lo=2&exp_hi=&limit=10000'; $mech->get($url); $mech->submit_form( form_number => 1, fields => { user_login => $ENV{'MERSENNE_USER'}, user_password => $ENV{'MERSENNE_PASSWORD'}, } ); # load the results into a table object my $html_string = $mech->content; $html_string =~ s/\n//g; my $te = HTML::TableExtract->new( depth => 0, count => 2 ); $te->parse($html_string); return $te->first_table_found; } sub generate_output_table ($ts) { # group GHZ Days results by computer, compute GHZ Days per Day (GHZ Days / Days) my $list; foreach my $row ( $ts->rows ) { foreach my $cell ($row) { my $machine = @$cell[0]; my $ghz_days = @$cell[6]; $ghz_days =~ s/\s//g; my $days = @$cell[4]; $days =~ s/\s//g; if ( $days > 0 ) { my $perf = $ghz_days / $days; push( @{ $list->{$machine} }, $perf ); } } } # create hash with each comptuer and its average GHz Days per day my %ranks; foreach my $key ( keys %$list ) { my $mean = sum( @{ $list->{$key} } ) / @{ $list->{$key} }; my $rounded = int( $mean + 0.5 ); $ranks{$key} = $rounded; } # sort hash by the average and print to screen return Text::SimpleTable::AutoWidth->new( captions => [qw/ Computer GHZDaysPerDay /] ); foreach my $key ( reverse sort { $ranks{$a} <=> $ranks{$b} } keys(%ranks) ) { $tbl->row( $key, $ranks{$key} ); } }