/** * Output a team row from the scoreboard based on the cached data in * table 'scoreboard'. */ function putTeamRow($cdata, $teamids) { global $DB; if (empty($cdata)) { return; } $fdata = calcFreezeData($cdata); $displayrank = IS_JURY || !$fdata['showfrozen']; $cid = $cdata['cid']; if (!$fdata['cstarted']) { if (!IS_JURY) { global $teamdata; echo "<h2 id=\"teamwelcome\">welcome team <span id=\"teamwelcometeam\">" . htmlspecialchars($teamdata['name']) . "</span>!</h2>\n\n"; echo "<h3 id=\"contestnotstarted\">contest is " . printContestStart($cdata) . "</h3>\n\n"; } return; } // For computing team row, use smart trick when only a single team is requested such // that we don't need to compute the whole scoreboard. // This does not fully populate the summary, so the first correct problem per problem // is not computed and hence not shown in the individual team row. if (count($teamids) == 1) { $teams = getTeams(array("teams" => $teamids), true, $cdata); $probs = getProblems($cdata); $SCORES = initScores($teams); $SUMMARY = initSummary($probs); // Calculate rank, num points and total time from rank cache foreach ($teams as $teamid => $team) { $totals = $DB->q("MAYBETUPLE SELECT points, totaltime\n\t\t\t FROM rankcache_jury\n\t\t\t WHERE cid = %i\n\t\t\t AND teamid = %i", $cid, $teamid); if ($totals != null) { $SCORES[$teamid]['num_points'] = $totals['points']; $SCORES[$teamid]['total_time'] = $totals['totaltime']; } if ($displayrank) { $SCORES[$teamid]['rank'] = calcTeamRank($cdata, $teamid, $totals, true); } } // Get values for this team about problems from scoreboard cache $MATRIX = array(); $scoredata = $DB->q("SELECT * FROM scorecache_jury WHERE cid = %i AND teamid = %i", $cid, current($teamids)); // loop all info the scoreboard cache and put it in our own datastructure while ($srow = $scoredata->next()) { // skip this row if the problem is not known by us if (!array_key_exists($srow['probid'], $probs)) { continue; } $penalty = calcPenaltyTime($srow['is_correct'], $srow['submissions']); // fill our matrix with the scores from the database $MATRIX[$srow['teamid']][$srow['probid']] = array('is_correct' => (bool) $srow['is_correct'], 'num_submissions' => $srow['submissions'], 'num_pending' => $srow['pending'], 'time' => $srow['totaltime'], 'penalty' => $penalty); } // Fill in empty places in the matrix foreach (array_keys($teams) as $team) { foreach (array_keys($probs) as $prob) { // provide default scores when nothing submitted for this team,problem yet if (!isset($MATRIX[$team][$prob])) { $MATRIX[$team][$prob] = array('is_correct' => FALSE, 'num_submissions' => 0, 'num_pending' => 0, 'time' => 0, 'penalty' => 0); } } } // Combine into data as genScoreBoard returns it $sdata = array('matrix' => $MATRIX, 'scores' => $SCORES, 'summary' => $SUMMARY, 'teams' => $teams, 'problems' => $probs, 'categories' => null); } else { // Otherwise, calculate scoreboard as jury to display non-visible teams $sdata = genScoreBoard($cdata, TRUE); } // Render the row based on this info $myteamid = null; $static = FALSE; if (!IS_JURY) { echo "<div id=\"teamscoresummary\">\n"; } renderScoreBoardTable($sdata, $myteamid, $static, $teamids, $displayrank, TRUE, FALSE); if (!IS_JURY) { echo "</div>\n\n"; } return; }
/** * 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; }
/** * Scoreboard */ function scoreboard($args) { global $DB; checkargs($args, array('cid')); global $cdatas; $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[$args['cid']], !$args['public'], $filter); $prob2label = $DB->q('KEYVALUETABLE SELECT probid, shortname FROM contestproblem WHERE cid = %i', $args['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) { $row['problems'][] = array('problem' => safe_int($probid), 'label' => $prob2label[$probid], 'num_judged' => safe_int($pdata['num_submissions']), 'num_pending' => safe_int($pdata['num_pending']), 'time' => safe_int($pdata['time']), 'solved' => safe_bool($pdata['is_correct'])); } $res[] = $row; } return $res; }
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; }