private static function getScoreboardFromRuns($runs, $raw_contest_users, $problem_mapping, $contest_penalty, $scoreboard_time_limit, $contest, $showAllRuns, $sortByName, $withRunDetails = false, $auth_token = null) { $test_only = array(); $no_runs = array(); $users_info = array(); $problems = array(); foreach ($problem_mapping as $problem) { array_push($problems, $problem); } // Calculate score for each contestant x problem foreach ($raw_contest_users as $contestant) { $user_problems = array(); $test_only[$contestant->getUserId()] = true; $no_runs[$contestant->getUserId()] = true; foreach ($problem_mapping as $id => $problem) { array_push($user_problems, array('points' => 0, 'percent' => 0, 'penalty' => 0, 'runs' => 0)); } // Add the problems' information $users_info[$contestant->getUserId()] = array('problems' => $user_problems, 'username' => $contestant->getUsername(), 'name' => $contestant->getName() ? $contestant->getName() : $contestant->getUsername(), 'total' => null, 'country' => $contestant->getCountryId()); } foreach ($runs as $run) { $user_id = $run->user_id; $problem_id = $run->problem_id; $contest_score = $run->contest_score; $score = $run->score; $is_test = $run->test != 0; $problem =& $users_info[$user_id]['problems'][$problem_mapping[$problem_id]['order']]; if (!array_key_exists($user_id, $test_only)) { // // Hay un usuario en la lista de Runs, // que no fue regresado por RunsDAO::GetAllRelevantUsers() // continue; } $test_only[$user_id] &= $is_test; $no_runs[$user_id] = false; if (!$showAllRuns) { if ($is_test) { continue; } if (!is_null($scoreboard_time_limit) && strtotime($run->getTime()) >= $scoreboard_time_limit) { $problem['runs']++; $problem['pending'] = true; continue; } } $totalPenalty = $run->penalty + $problem['runs'] * $contest_penalty; $rounded_score = round($contest_score, 2); if ($problem['points'] < $rounded_score || $problem['points'] == $rounded_score && $problem['penalty'] > $totalPenalty) { $problem['points'] = $rounded_score; $problem['percent'] = round($score * 100, 2); $problem['penalty'] = $totalPenalty; if ($withRunDetails === true) { $runDetails = array(); $runDetailsRequest = new Request(array('run_alias' => $run->guid, 'auth_token' => $auth_token)); $runDetails = RunController::apiDetails($runDetailsRequest); unset($runDetails['source']); $problem['run_details'] = $runDetails; } } $problem['runs']++; } $result = array(); foreach ($raw_contest_users as $contestant) { $user_id = $contestant->getUserId(); // Add contestant results to scoreboard data if (!$showAllRuns && $test_only[$user_id] && !$no_runs[$user_id]) { continue; } $info = $users_info[$user_id]; if ($info == null) { continue; } $info[self::TOTAL_COLUMN] = Scoreboard::getTotalScore($info['problems']); array_push($result, $info); } Scoreboard::sortScoreboard($result, $sortByName); usort($problems, array('Scoreboard', 'compareOrder')); return array('problems' => $problems, 'ranking' => $result, 'start_time' => strtotime($contest->start_time), 'finish_time' => strtotime($contest->finish_time), 'title' => $contest->title, 'time' => time() * 1000); }