From: Marius Gavrilescu Date: Thu, 18 Jun 2015 16:26:31 +0000 (+0300) Subject: Also simplify standings X-Git-Tag: 5999.000_014~15 X-Git-Url: http://git.ieval.ro/?a=commitdiff_plain;h=01fcdebe1ca1a0ca404f717fdb5b95014f4efaa3;p=gruntmaster-data.git Also simplify standings --- diff --git a/lib/Gruntmaster/Data.pm b/lib/Gruntmaster/Data.pm index 559ae62..1558e46 100644 --- a/lib/Gruntmaster/Data.pm +++ b/lib/Gruntmaster/Data.pm @@ -27,13 +27,11 @@ my %statements = ( contest_list_sth => 'SELECT * FROM contest_entry', contest_entry_sth => 'SELECT * FROM contest_entry WHERE id = ?', - contest_problems_sth => 'SELECT problem FROM contest_problems JOIN problems pb ON problem=pb.id WHERE contest = ? ORDER BY pb.value', contest_has_problem_sth => 'SELECT EXISTS(SELECT 1 FROM contest_problems WHERE contest = ? AND problem = ?)', opens_sth => 'SELECT problem,owner,time FROM opens WHERE contest = ?', problem_entry_sth => 'SELECT ' . (join ',', @{PROBLEM_PUBLIC_COLUMNS()}, 'statement', 'solution') . ' FROM problems WHERE id = ?', limits_sth => 'SELECT format,timeout FROM limits WHERE problem = ?', - problem_values_sth => 'SELECT id,value FROM problems', job_entry_sth => 'SELECT * FROM job_entry WHERE id = ?', @@ -170,7 +168,7 @@ sub create_job { scalar $db->insert('jobs', \%args, {returning => 'id'})->list } -sub calc_score { +sub _calc_score { my ($mxscore, $time, $tries, $totaltime) = @_; my $score = $mxscore; $time = 300 if $time > $totaltime; # uncoverable branch true does not happen anymore (only possible if opens are broken) @@ -182,12 +180,10 @@ sub calc_score { sub standings { my ($ct) = @_; + my @problems = sort { $a->{value} <=> $b->{value} } @{problem_list contest => $ct}; + my %values = map { $_->{id} => $_->{value} } @problems; $ct = contest_entry $ct; - my @problems = query(contest_problems_sth => $ct->{id})->flat; - my $pblist = problem_list; - my %values = query('problem_values_sth')->map; - my (%scores, %tries, %opens); my $opens = query(opens_sth => $ct->{id}); while ($opens->into(my ($problem, $owner, $time))) { @@ -203,7 +199,7 @@ sub standings { my $value = $values{$job->{problem}}; my $factor = $job->{result} ? 0 : 1; $factor = $1 / 100 if $job->{result_text} =~ /^(\d+ )/s; - $scores{$job->{owner}}{$job->{problem}} = int ($factor * calc_score ($value, $time, $tries{$job->{owner}}{$job->{problem}}++, $ct->{stop} - $ct->{start})); + $scores{$job->{owner}}{$job->{problem}} = int ($factor * _calc_score ($value, $time, $tries{$job->{owner}}{$job->{problem}}++, $ct->{stop} - $ct->{start})); } my @st = sort { $b->{score} <=> $a->{score} or $a->{user} cmp $b->{user} } map { ## no critic (ProhibitReverseSortBlock) @@ -212,16 +208,14 @@ sub standings { user => $user, user_name => object_name(users => $user), score => sum (values %{$scores{$user}}), - scores => [map { $scores{$user}{$_} // '-'} @problems], + scores => [map { $scores{$user}{$_->{id}} // '-'} @problems], } } keys %scores; $st[0]->{rank} = 1 if @st; $st[$_]->{rank} = $st[$_ - 1]->{rank} + ($st[$_]->{score} < $st[$_ - 1]->{score}) for 1 .. $#st; - +{ - st => \@st, - problems => [map { [ $_, object_name(problems => $_)] } @problems], - } + + \@st } sub update_status { @@ -236,7 +230,7 @@ sub update_status { my @contest_statuses = map { my $ct = $_; - map { [$ct, $_->{user}, $_->{score}, $_->{rank}] } @{standings($ct)->{st}} + map { [$ct, $_->{user}, $_->{score}, $_->{rank}] } @{standings $ct} } $db->select('contests', 'id')->flat; $db->begin; diff --git a/t/Gruntmaster-Data.t b/t/Gruntmaster-Data.t index 38c2330..6d381ea 100644 --- a/t/Gruntmaster-Data.t +++ b/t/Gruntmaster-Data.t @@ -102,10 +102,7 @@ $x = job_entry 7; ok !defined $x->{result}, 'job_entry 7 has NULL result'; $x = standings 'fc'; -is_deeply $x, { - problems => [[fca => 'FC problem A']], - st => [ - {rank => 1, user => 'MGV', user_name => undef, score => 50, scores => [50]}, - {rank => 2, user => 'nobody', user_name => undef, score => 40, scores => [40]}, - ] -}, 'standings fc'; +is_deeply $x, [ + {rank => 1, user => 'MGV', user_name => undef, score => 50, scores => [50]}, + {rank => 2, user => 'nobody', user_name => undef, score => 40, scores => [40]}, +], 'standings fc';