use v5.32; use HTML::TableExtract; use File::Slurp; use Data::Dumper; use Text::SimpleTable::AutoWidth; use WWW::Mechanize (); use List::AllUtils qw/ sum pairmap /; use List::UtilsBy qw/ nsort_by /; 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; return extract_first_table($html_string); } sub extract_first_table($html) { $html =~ s/\n//g; my $te = HTML::TableExtract->new( depth => 0, count => 2 ); $te->parse($html); 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 $days = $cell->[4] =~ s/\s//gr; my $ghz_days = $cell->[6] =~ s/\s//gr; 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 = pairmap { my $mean = sum( @$b ) / @$b; my $rounded = int( $mean + 0.5 ); $a => $rounded; } %$list; # sort hash by the average and print to screen my $tbl = Text::SimpleTable::AutoWidth->new( captions => [qw/ Computer GHZDaysPerDay /] ); $tbl->row( @$_ ) for reverse nsort_by { $_->[1] } pairmap { [$a,$b] } %ranks; return $tbl; }