Ejemplo n.º 1
0
	                 WHERE externalid IS NOT NULL AND enabled=1');
    while ($row = $teams->next()) {
        $totals = $DB->q('MAYBETUPLE SELECT points_restricted AS points,
		                                    totaltime_restricted AS totaltime
		                  FROM rankcache
		                  WHERE cid = %i AND teamid = %i', $cid, $row['teamid']);
        if ($totals === null) {
            $totals['points'] = $totals['totaltime'] = 0;
        }
        $rank = calcTeamRank($cdata, $row['teamid'], $totals, TRUE);
        $lastProblem = $DB->q('MAYBEVALUE SELECT MAX(solvetime_restricted) FROM scorecache
		                       WHERE teamid=%i AND cid=%i', $row['teamid'], $cid);
        if ($lastProblem === NULL) {
            $lastProblem = 0;
        } else {
            $lastProblem = scoretime($lastProblem);
        }
        $data .= '<Standing LastProblemTime="' . $lastProblem . '" ProblemsSolved="' . $totals['points'] . '" Rank="' . $rank . '" TeamID="' . $row['externalid'] . '" TotalTime="' . $totals['totaltime'] . '"/>';
    }
    $data .= '</icpc>';
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
}
$response = curl_exec($ch);
if ($response === FALSE) {
    error("Error while retrieving data from icpc.baylor.edu: " . curl_error($ch));
}
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($status == 401) {
    error("Access forbidden, is your token valid?");
}
if ($status < 200 || $status >= 300) {
Ejemplo n.º 2
0
/**
 * Scoreboard
 */
function scoreboard($args)
{
    global $DB, $api, $cdatas, $cids;
    if (isset($args['cid'])) {
        $cid = safe_int($args['cid']);
    } else {
        if (count($cids) == 1) {
            $cid = reset($cids);
        } else {
            $api->createError("No contest ID specified but active contest is ambiguous.");
        }
    }
    $filter = array();
    if (array_key_exists('category', $args)) {
        $filter['categoryid'] = array($args['category']);
    }
    if (array_key_exists('country', $args)) {
        $filter['country'] = array($args['country']);
    }
    if (array_key_exists('affiliation', $args)) {
        $filter['affilid'] = array($args['affiliation']);
    }
    $scoreboard = genScoreBoard($cdatas[$cid], !$args['public'], $filter);
    $prob2label = $DB->q('KEYVALUETABLE SELECT probid, shortname
	                      FROM contestproblem WHERE cid = %i', $cid);
    $res = array();
    foreach ($scoreboard['scores'] as $teamid => $data) {
        $row = array('rank' => $data['rank'], 'team' => $teamid);
        $row['score'] = array('num_solved' => safe_int($data['num_points']), 'total_time' => safe_int($data['total_time']));
        $row['problems'] = array();
        foreach ($scoreboard['matrix'][$teamid] as $probid => $pdata) {
            $prob = array('label' => $prob2label[$probid], 'num_judged' => safe_int($pdata['num_submissions']), 'num_pending' => safe_int($pdata['num_pending']), 'solved' => safe_bool($pdata['is_correct']));
            if ($prob['solved']) {
                $prob['time'] = scoretime($pdata['time']);
                $first = first_solved($pdata['time'], $scoreboard['summary']['problems'][$probid]['best_time_sort'][$data['sortorder']]);
                $prob['first_to_solve'] = safe_bool($first);
            }
            $row['problems'][] = $prob;
        }
        usort($row['problems'], 'cmp_prob_label');
        $res[] = $row;
    }
    return $res;
}
Ejemplo n.º 3
0
/**
 * Update tables used for efficiently computing team ranks
 *
 * Given a contestid and teamid (re)calculate the time
 * and solved problems for a team.
 *
 * Due to current transactions usage, this function MUST NOT contain
 * any START TRANSACTION or COMMIT statements.
 */
function updateRankCache($cid, $team)
{
    global $DB;
    logmsg(LOG_DEBUG, "updateRankCache '{$cid}' '{$team}'");
    $team_penalty = $DB->q("VALUE SELECT penalty FROM team WHERE teamid = %i", $team);
    // First acquire an advisory lock to prevent other calls to
    // calcScoreRow() from interfering with our update.
    $lockstr = "domjudge.{$cid}.{$team}";
    if ($DB->q("VALUE SELECT GET_LOCK('{$lockstr}',3)") != 1) {
        error("updateRankCache failed to obtain lock '{$lockstr}'");
    }
    // Fetch values from scoreboard cache per problem
    $scoredata = $DB->q("SELECT *, cp.points\n\t                     FROM scorecache\n\t                     LEFT JOIN contestproblem cp USING(probid,cid)\n\t                     WHERE cid = %i and teamid = %i", $cid, $team);
    $num_points = array('public' => 0, 'restricted' => 0);
    $total_time = array('public' => $team_penalty, 'restricted' => $team_penalty);
    while ($srow = $scoredata->next()) {
        // Only count solved problems
        foreach (array('public', 'restricted') as $variant) {
            if ($srow['is_correct_' . $variant]) {
                $penalty = calcPenaltyTime($srow['is_correct_' . $variant], $srow['submissions_' . $variant]);
                $num_points[$variant] += $srow['points'];
                $total_time[$variant] += scoretime($srow['solvetime_' . $variant]) + $penalty;
            }
        }
    }
    // Update the rank cache table
    $DB->q("REPLACE INTO rankcache (cid, teamid,\n\t        points_restricted, totaltime_restricted,\n\t        points_public, totaltime_public)\n\t        VALUES (%i,%i,%i,%i,%i,%i)", $cid, $team, $num_points['restricted'], $total_time['restricted'], $num_points['public'], $total_time['public']);
    // Release the lock
    if ($DB->q("VALUE SELECT RELEASE_LOCK('{$lockstr}')") != 1) {
        error("updateRankCache failed to release lock '{$lockstr}'");
    }
}
Ejemplo n.º 4
0
function tsv_results_get()
{
    // we'll here assume that the requested file will be of the current contest,
    // as all our scoreboard interfaces do
    // 1 	External ID 	24314 	integer
    // 2 	Rank in contest 	1 	integer
    // 3 	Award 	Gold Medal 	string
    // 4 	Number of problems the team has solved 	4 	integer
    // 5 	Total Time 	534 	integer
    // 6 	Time of the last submission 	233 	integer
    // 7 	Group Winner 	North American 	string
    global $cdata, $DB, $extid_to_name;
    $categs = $DB->q('COLUMN SELECT categoryid FROM team_category WHERE visible = 1');
    $sb = genScoreBoard($cdata, true, array('categoryid' => $categs));
    $extid_to_name = $DB->q('KEYVALUETABLE SELECT externalid, name FROM team ORDER BY externalid');
    $numteams = sizeof($sb['scores']);
    // determine number of problems solved by median team
    $cnt = 0;
    foreach ($sb['scores'] as $teamid => $srow) {
        $cnt++;
        $median = $srow['num_correct'];
        if ($cnt > $numteams / 2) {
            // XXX: lower or upper median?
            break;
        }
    }
    $ranks = array();
    $group_winners = array();
    $data = array();
    foreach ($sb['scores'] as $teamid => $srow) {
        $maxtime = -1;
        foreach ($sb['matrix'][$teamid] as $prob) {
            $maxtime = max($maxtime, scoretime($prob['time']));
        }
        $rank = $srow['rank'];
        $num_correct = $srow['num_correct'];
        if ($rank <= 4) {
            $awardstring = "Gold Medal";
        } else {
            if ($rank <= 8) {
                $awardstring = "Silver Medal";
            } else {
                if ($rank <= 12) {
                    $awardstring = "Bronze Medal";
                } else {
                    if ($num_correct >= $median) {
                        // teams with equally solved number of problems get the same rank
                        if (!isset($ranks[$num_correct])) {
                            $ranks[$num_correct] = $rank;
                        }
                        $rank = $ranks[$num_correct];
                        $awardstring = "Ranked";
                    } else {
                        $awardstring = "Honorable";
                        $rank = "";
                    }
                }
            }
        }
        $groupwinner = "";
        if (!isset($group_winners[$srow['categoryid']])) {
            $group_winners[$srow['categoryid']] = true;
            $groupwinner = $DB->q('VALUE SELECT name FROM team_category WHERE categoryid = %i', $srow['categoryid']);
        }
        $data[] = array(@$sb['teams'][$teamid]['externalid'], $rank, $awardstring, $srow['num_correct'], $srow['total_time'], $maxtime, $groupwinner);
    }
    // sort by rank/name
    uasort($data, 'cmp_extid_name');
    return $data;
}
Ejemplo n.º 5
0
/**
 * Calculate the rank for a single team based on the cache tables
 */
function calcTeamRank($cdata, $teamid, $teamtotals, $jury = FALSE)
{
    global $DB;
    if (empty($cdata)) {
        return;
    }
    $fdata = calcFreezeData($cdata);
    $cid = $cdata['cid'];
    // Use jury scoreboard when jury or final scoreboard should be displayed
    $variant = $jury || $fdata['showfinal'] ? 'restricted' : 'public';
    $points = isset($teamtotals['points']) ? $teamtotals['points'] : 0;
    $totaltime = isset($teamtotals['totaltime']) ? $teamtotals['totaltime'] : 0;
    $sortorder = $DB->q('VALUE SELECT sortorder
	                     FROM team_category
	                     LEFT JOIN team USING (categoryid)
	                     WHERE teamid = %i', $teamid);
    // Number of teams that definitely ranked higher
    $better = $DB->q("VALUE SELECT COUNT(team.teamid)\n\t                  FROM rankcache AS rc\n\t                  LEFT JOIN team USING (teamid)\n\t                  LEFT JOIN team_category USING (categoryid)\n\t                  WHERE cid = %i AND sortorder = %i AND enabled = 1\n\t                  AND (points_{$variant} > %i OR\n\t                  (points_{$variant} = %i AND totaltime_{$variant} < %i))", $cid, $sortorder, $points, $points, $totaltime);
    $rank = $better + 1;
    // Resolve ties based on latest correctness points, only necessary when we actually
    // solved at least one problem, so this list should usually be short
    if ($points > 0) {
        $tied = $DB->q("COLUMN SELECT team.teamid\n\t\t                FROM rankcache AS rc\n\t\t                LEFT JOIN team USING (teamid)\n\t\t                LEFT JOIN team_category USING (categoryid)\n\t\t                WHERE cid = %i AND sortorder = %i AND enabled = 1\n\t\t                AND points_{$variant} = %i AND totaltime_{$variant} = %i", $cid, $sortorder, $points, $totaltime);
        // All teams that are tied for this position, in most cases this will
        // only be the team we are finding the rank for, only retrieve rest of
        // the data when there are actual ties
        if (count($tied) > 1) {
            // initialize teamdata for each team
            $teamdata = array();
            foreach ($tied as $tiedid) {
                $teamdata[$tiedid]['solve_times'] = array();
            }
            // Get submission times for each of the teams
            $scoredata = $DB->q("SELECT teamid, solvetime_{$variant} AS solvetime\n\t\t\t                     FROM scorecache AS sc\n\t\t\t                     LEFT JOIN problem p USING (probid)\n\t\t\t                     LEFT JOIN contestproblem cp USING (probid, cid)\n\t\t\t                     WHERE sc.cid = %i AND is_correct_{$variant} = 1\n\t\t\t                     AND allow_submit = 1 AND teamid IN (%Ai)", $cid, $tied);
            while ($srow = $scoredata->next()) {
                $teamdata[$srow['teamid']]['solve_times'][] = scoretime($srow['solvetime']);
            }
            // Now check for each team if it is ranked higher than $teamid
            foreach ($tied as $tiedid) {
                if ($tiedid == $teamid) {
                    continue;
                }
                if (tiebreaker($teamdata[$tiedid], $teamdata[$teamid]) < 0) {
                    $rank++;
                }
            }
        }
    }
    return $rank;
}