📄 manage_test.cpp
字号:
char tmp[STRING_MAX_LEN]; if (!conf.read("general", "src", tmp, STRING_MAX_LEN)) { report_err("Failed to read the directory of source files.", __PRETTY_FUNCTION__, __LINE__); return; } string contestants_dir(tmp); Str_array contestants_names; if (!list_dir(contestants_dir.c_str(), contestants_names)) { report_err("Failed to list the contestants.", __PRETTY_FUNCTION__, __LINE__); return; } if (*contestants_dir.rbegin() != '/') contestants_dir.append("/"); for (Str_array::iterator i = contestants_names.begin(); i != contestants_names.end(); i ++) { Conf cont_result((contestants_dir + *i + "/result.cfg").c_str()); conr.push_back(Contestant_result()); Conr_array::iterator pos = conr.end() - 1; pos->name = *i; pos->result.resize(probnames.size()); pos->judged.resize(probnames.size(), false); pos->total_score = pos->total_time = 0; for (Str_array::size_type j = 0; j < probnames.size(); j ++) if (read_judge_result(pos->result[j], cont_result, "result", probnames[j].c_str())) { pos->judged[j] = true; for (Str_array::size_type k = 0; k < pos->result[j].score.size(); k ++) { pos->total_score += pos->result[j].score[k]; pos->total_time += pos->result[j].time[k]; } } } sort(conr.begin(), conr.end());}void show_contestant_detail(const Str_array &probnames, const Contestant_result &cre){ static const char *OPERATION_REMINDER = "Press UP (PAGE UP) and DOWN (PAGE DOWN) to scroll the screen, or any other key to return to the last menu."; int opr_nlines = get_str_nlines(OPERATION_REMINDER); Window main_win; main_win.printf(OPERATION_REMINDER); Window win_details(get_nlines() - opr_nlines, get_ncols(), opr_nlines, 0); ostringstream message; message << "Judge details for contestant \"" << cre.name << '\"' << endl; message << "Total score: " << cre.total_score << " total time: " << double(cre.total_time) / 1e6 << " sec." << endl << endl; for (Str_array::size_type i = 0; i < probnames.size(); i ++) { message << "Problem \"" << probnames[i] << "\" :" << endl; if (cre.judged[i]) output_problem_detail(message, cre.result[i]); else message << "This problem has not been judged." << endl; message << ' ' << string(win_details.get_ncols() - 2, '-') << endl; } update(); win_details.print_longmsg(message.str().c_str());}void output_problem_detail(ostream &outstr, const Judge_result &result){ if (!result.source_found) { outstr << "Source file has not been found!\n"; return; } if (!result.compile_successful) { outstr << "Failed to compile the source, detail: \n"; outstr << result.compiler_output << endl; return; } outstr << "[Point] [Score] [Time(s)] [Memory(kb)] " << endl; for (Str_array::size_type i = 0; i < result.score.size(); i ++) { outstr << left << setw(9) << i + 1; if (result.time[i] == 0 && result.memory[i] == 0) { outstr << "Failed to execute the contestant's program.(maybe main() returned a non-zero value.)\n"; continue; } outstr << setw(11) << fixed << setprecision(3) << result.score[i] << setw(13) << setprecision(6) << double(result.time[i]) / 1e6 << setw(15) << result.memory[i]; if (result.overtime[i]) outstr << "<Overtime>"; outstr << endl; }}bool save_html(const char *path, const Conr_array &result, const Conf &conf, const Str_array &probnames){ FILE *fout = fopen(path, "w"); if (fout == NULL) { report_err("Failed to create the file.", __PRETTY_FUNCTION__, __LINE__); return false; } char tmp[STRING_MAX_LEN + 1]; if (!conf.read("general", "name", tmp, STRING_MAX_LEN)) strcpy(tmp, "No Name"); fprintf(fout, "<html>\n"); fprintf(fout, "<title> Judge results for contest \"%s\"</title>\n", tmp); fprintf(fout, "<body><center>\n"); fprintf(fout, "<B><h1>Ranked Grades</h1></B>\n"); fprintf(fout, "<table border>\n"); fprintf(fout, "<tr><th>Rank</th><th>Name</th><th>Score</th><th>Time(sec.)</th></tr>\n"); for (Conr_array::size_type i = 0; i < result.size(); i ++) fprintf(fout, "<tr><td>%u</td><td><a href=\"#%u\">%s</a></td><td>%0.2lf</td><td>%0.3lf</td></tr>\n", (unsigned)i + 1, (unsigned)i, result[i].name.c_str(), result[i].total_score, double(result[i].total_time) * 1e-6); fprintf(fout, "</table>\n"); for (Conr_array::size_type i = 0; i < result.size(); i ++) { fprintf(fout, "<HR>\n"); fprintf(fout, "<a name=\"%u\"><B><h3>Judge results for contestant \"%s\"</h3></B></a>\n", (unsigned)i, result[i].name.c_str()); fprintf(fout, "<table border>\n"); fprintf(fout, "<tr><th>Problem</th><th>Point</th><th>Result</th><th>Score</th><th>Time(sec.)</th><th>Memory(KB)</th></tr>\n"); for (Str_array::size_type j = 0; j < probnames.size(); j ++) { if (!result[i].judged[j]) { fprintf(fout, "<tr><th>%s</th><td colspan=5>This problem has not been judged.</td></tr>\n", probnames[j].c_str()); continue; } Contestant_result::Jr_array::const_iterator ptr = result[i].result.begin() + j; if (!(ptr->source_found)) fprintf(fout, "<tr><th>%s</th><td colspan=5>Source file is not found.</td></tr>\n", probnames[j].c_str()); else if (!(ptr->compile_successful)) fprintf(fout, "<tr><th>%s</th><td colspan=5><pre>Failed to compile, details:\n%s</pre></td></tr>\n", probnames[j].c_str(), ptr->compiler_output.c_str()); else { fprintf(fout, "<tr><th rowspan=%u>%s</th>\n", (unsigned)ptr->score.size(), probnames[j].c_str()); for (Str_array::size_type k = 0; k < ptr->score.size(); k ++) { if (k > 0) fprintf(fout, "<tr>"); fprintf(fout, "<td>%u</td>", unsigned(k + 1)); if (ptr->time[k] == 0 && ptr->memory[k] == 0) fprintf(fout, "<td colspan=4>Failed to execute the program.</td>"); else { static const char *RESULTS[] = { "<font color=green>OK</font>", "<font color=red>Overtime</font>", "<font color=navy>Wrong answer</font>" }; int ch = 0; if (ptr->score[k] == 0) ch = (ptr->overtime[k] ? 1 : 2); fprintf(fout, "<td>%s</td><td>%0.2f</td><td>%0.6f</td><td>%lu</td>", RESULTS[ch], ptr->score[k], double(ptr->time[k]) * 1e-6, ptr->memory[k]); } fprintf(fout, "</tr>\n"); } } } fprintf(fout, "</table>"); } fprintf(fout, "</center><br /><br /><p ALIGN=RIGHT><small>created by %s</small></p></body>\n</html>\n", VERSION_INF); return fclose(fout) == 0;}void add_new_test_points(Test_point_array &tps, const char *probname){ char input_pattern[STRING_MAX_LEN], output_pattern[STRING_MAX_LEN], vars[STRING_MAX_LEN], tmp[STRING_MAX_LEN]; sprintf(tmp, "data/%s/%s%%.in", probname, probname); read_input("Please enter the pattern for standard input files: ", input_pattern, NULL, tmp); sprintf(tmp, "data/%s/%s%%.out", probname, probname); read_input("Please enter the pattern for standard output files: ", output_pattern, NULL, tmp); read_input("Please enter the values that are separated by a space to replace the '%' mark: ", vars, NULL, "1 2 3 4 5 6 7 8 9 10"); int time; double score; read_input("Please enter the time limit[s] for every point: ", tmp, "1"); if (sscanf(tmp, "%d", &time) == EOF) time = 1; read_input("Please enter the score for every point: ", tmp, "10"); if (sscanf(tmp, "%lf", &score) == EOF) score = 10; istringstream strin(vars); string val; while (strin >> val) { tps.push_back(Test_point()); tps.rbegin()->time = time; tps.rbegin()->score = score; string str(input_pattern); string::size_type pos; while ((pos = str.find('%', 0)) != string::npos) str.replace(pos, 1, val); strcpy(tps.rbegin()->input, str.c_str()); str = output_pattern; while ((pos = str.find('%', 0)) != string::npos) str.replace(pos, 1, val); strcpy(tps.rbegin()->output, str.c_str()); }}bool operator < (const Contestant_result &n1, const Contestant_result &n2){ return n1.total_score > n2.total_score || (n1.total_score == n2.total_score && n1.total_time < n2.total_time);}Problem_conf::Problem_conf(const Conf &conf, int prob_num){ char conf_item[STRING_MAX_LEN]; sprintf(conf_item, "problem_%d_name", prob_num); if (!conf.read("general", conf_item, name, STRING_MAX_LEN)) report_err("Fail to read the configuration file!\n", __PRETTY_FUNCTION__, __LINE__); char conf_section[STRING_MAX_LEN]; sprintf(conf_section, "%s.general", name); int npoints; if (!conf.read(conf_section, "points_num", npoints)) npoints = 0; if (!conf.read(conf_section, "input", input, STRING_MAX_LEN)) sprintf(input, "%s.in", name); if (!conf.read(conf_section, "output", output, STRING_MAX_LEN)) sprintf(output, "%s.out", name); if (!conf.read(conf_section, "source", source, STRING_MAX_LEN)) sprintf(source, "%s", name); sprintf(conf_section, "%s.points", name); points.resize(npoints); for (int i = 0; i < npoints; i ++) { sprintf(conf_item, "%d.time", i); if (!conf.read(conf_section, conf_item, points[i].time)) report_err("Fail to read @time.\n", __PRETTY_FUNCTION__, __LINE__); sprintf(conf_item, "%d.score", i); if (!conf.read(conf_section, conf_item, points[i].score)) report_err("Fail to read @score.\n", __PRETTY_FUNCTION__, __LINE__); sprintf(conf_item, "%d.input", i); if (!conf.read(conf_section, conf_item, points[i].input, STRING_MAX_LEN)) report_err("Fail to read @input.\n", __PRETTY_FUNCTION__, __LINE__); sprintf(conf_item, "%d.output", i); if (!conf.read(conf_section, conf_item, points[i].output, STRING_MAX_LEN)) report_err("Fail to read @output.\n", __PRETTY_FUNCTION__, __LINE__); }}Problem_conf::Problem_conf(const char *probname){ strcpy(name, probname); sprintf(input, "%s.in", name); sprintf(output, "%s.out", name); sprintf(source, "%s", name); points.clear();}void Problem_conf::write_conf(Conf &conf){ char conf_section[STRING_MAX_LEN]; sprintf(conf_section, "%s.general", name); conf.delsection(conf_section); conf.write(conf_section, "input", input); conf.write(conf_section, "output", output); conf.write(conf_section, "source", source); conf.write(conf_section, "points_num", int(points.size())); sprintf(conf_section, "%s.points", name); conf.delsection(conf_section); for (unsigned int i = 0; i < points.size(); i ++) { char conf_item[STRING_MAX_LEN]; sprintf(conf_item, "%d.time", i); conf.write(conf_section, conf_item, points[i].time); sprintf(conf_item, "%d.score", i); conf.write(conf_section, conf_item, points[i].score); sprintf(conf_item, "%d.input", i); conf.write(conf_section, conf_item, points[i].input); sprintf(conf_item, "%d.output", i); conf.write(conf_section, conf_item, points[i].output); }}void auto_conf_prob(Conf &conf){ conf.del_all(); Str_array probs; if (!list_dir(DEFAULT_DATA_DIR, probs)) { char msg[STRING_MAX_LEN]; sprintf(msg, "Sorry, failed to list the data directory [%s].", DEFAULT_DATA_DIR); message_box(msg); return; } int pnum = 0; char tmp[STRING_MAX_LEN]; for (Str_array::size_type i = 0; i < probs.size(); i ++) { Problem_conf pconf(probs[i].c_str()); sprintf(tmp, "Problem \"%s\" has been found.", probs[i].c_str()); message_box(tmp); if (auto_add_prob_points(pconf, conf.get_file_path())) { sprintf(tmp, "problem_%d_name", pnum ++); conf.write("general", tmp, probs[i].c_str()); pconf.write_conf(conf); } } conf.write("general", "problems_num", pnum);}bool auto_add_prob_points(Problem_conf &pconf, const char *conf_path){ char dir[STRING_MAX_LEN]; sprintf(dir, DEFAULT_DATA_DIR_S, pconf.name); Point_info_array result; if (auto_add_points(dir, result)) { char tmp[STRING_MAX_LEN]; Test_point tp; read_input("Please enter the time limit[s] for each test point: ", tmp, "1"); if (sscanf(tmp, "%d", &tp.time) == EOF) tp.time = 1000; char tmp1[STRING_MAX_LEN]; sprintf(tmp1, "%lf", 100.0 / double(result.size())); read_input("Please enter the score for each test point: ", tmp, tmp1); if (sscanf(tmp, "%lf", &tp.score) == EOF) tp.score = 10; pconf.points.resize(result.size()); for (Test_point_array::size_type i = 0; i < pconf.points.size(); i ++) { result[i].input.insert(0, dir); result[i].output.insert(0, dir); strcpy(pconf.points[i].input, result[i].input.c_str()); strcpy(pconf.points[i].output, result[i].output.c_str()); pconf.points[i].time = tp.time; pconf.points[i].score = tp.score; } return true; } else { char msg[STRING_MAX_LEN]; sprintf(msg, "Sorry, failed to automatically add test points. You should make sure that the data files are in directory data/%s , and there should not be any extra files.\n", pconf.name); message_box(msg); return false; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -