Browse Source

Add Special Judge support

pull/6/head
Menci 8 years ago
parent
commit
383cad25b0
  1. 12
      static/style.css
  2. 41
      utility.js
  3. 9
      views/judge_detail_item.ejs
  4. 9
      views/upload_testdata.ejs
  5. 4
      views/util.ejs

12
static/style.css

@ -79,6 +79,18 @@ th {
color: #6cf; color: #6cf;
} }
:not(.status_detail).status.partially_correct,
.title:hover .status_detail.status.partially_correct,
.title.active .status_detail.status.partially_correct {
color: #01bab2;
}
:not(.status_detail).status.judgement_failed,
.title:hover .status_detail.status.judgement_failed,
.title.active .status_detail.status.judgement_failed {
color: #78909C;
}
:not(.status_detail).status.compiling { :not(.status_detail).status.compiling {
color: #00b5ad; color: #00b5ad;
} }

41
utility.js

@ -144,20 +144,20 @@ module.exports = {
parseTestData(filename) { parseTestData(filename) {
let zip = new AdmZip(filename); let zip = new AdmZip(filename);
let list = zip.getEntries().filter(e => !e.isDirectory).map(e => e.entryName); let list = zip.getEntries().filter(e => !e.isDirectory).map(e => e.entryName);
let res = [];
if (!list.includes('data_rule.txt')) { if (!list.includes('data_rule.txt')) {
let testcases = [];
for (let file of list) { for (let file of list) {
let parsedName = path.parse(file); let parsedName = path.parse(file);
if (parsedName.ext === '.in') { if (parsedName.ext === '.in') {
if (list.includes(`${parsedName.name}.out`)) { if (list.includes(`${parsedName.name}.out`)) {
testcases.push({ res.push({
input: file, input: file,
output: `${parsedName.name}.out` output: `${parsedName.name}.out`
}); });
} }
if (list.includes(`${parsedName.name}.ans`)) { if (list.includes(`${parsedName.name}.ans`)) {
testcases.push({ res.push({
input: file, input: file,
output: `${parsedName.name}.ans` output: `${parsedName.name}.ans`
}); });
@ -165,7 +165,7 @@ module.exports = {
} }
} }
testcases.sort((a, b) => { res.sort((a, b) => {
function getLastInteger(s) { function getLastInteger(s) {
let re = /(\d+)\D*$/; let re = /(\d+)\D*$/;
let x = re.exec(s); let x = re.exec(s);
@ -175,28 +175,29 @@ module.exports = {
return getLastInteger(a.input) - getLastInteger(b.input); return getLastInteger(a.input) - getLastInteger(b.input);
}); });
} else {
let lines = zip.readAsText('data_rule.txt').split('\r').join('').split('\n');
return testcases; if (lines.length < 3) throw 'Invalid data_rule.txt';
}
let lines = zip.readAsText('data_rule.txt').split('\r').join('').split('\n');
if (lines.length < 3) throw 'Invalid data_rule.txt'; let numbers = lines[0].split(' ').filter(x => x);
let input = lines[1];
let output = lines[2];
let numbers = lines[0].split(' ').filter(x => x); for (let i of numbers) {
let input = lines[1]; res[i] = {};
let output = lines[2]; res[i].input = input.replace('#', i);
res[i].output = output.replace('#', i);
let res = []; if (!list.includes(res[i].input)) throw `Can't find file ${res[i].input}`;
for (let i of numbers) { if (!list.includes(res[i].output)) throw `Can't find file ${res[i].output}`;
res[i] = {}; }
res[i].input = input.replace('#', i);
res[i].output = output.replace('#', i);
if (!list.includes(res[i].input)) throw `Can't find file ${res[i].input}`; res = res.filter(x => x);
if (!list.includes(res[i].output)) throw `Can't find file ${res[i].output}`;
} }
return res.filter(x => x); res.spj = list.includes('spj.js');
return res;
}, },
ansiToHTML(s) { ansiToHTML(s) {
let Convert = require('ansi-to-html'); let Convert = require('ansi-to-html');

9
views/judge_detail_item.ejs

@ -69,8 +69,9 @@
<i class="<%= icon[getStatusMeta(testcase.status)] || 'remove' %> icon"></i> <i class="<%= icon[getStatusMeta(testcase.status)] || 'remove' %> icon"></i>
<%= testcase.status %></div> <%= testcase.status %></div>
<% if (!pending) { %> <% if (!pending) { %>
<div class="four wide column">用时:<span style="font-weight: normal; "><%= testcase.time_used %> ms</span></div> <div class="three wide column">得分:<span style="font-weight: normal; "><%= parseFloat((testcase.score / judge.result.case_num).toFixed(2)).toString() %></span></div>
<div class="four wide column">内存:<span style="font-weight: normal; "><%= testcase.memory_used %> KiB</span></div> <div class="three wide column">用时:<span style="font-weight: normal; "><%= testcase.time_used %> ms</span></div>
<div class="three wide column">内存:<span style="font-weight: normal; "><%= testcase.memory_used %> KiB</span></div>
<% } %> <% } %>
</div> </div>
</div> </div>
@ -83,6 +84,10 @@
<div class="ui existing segment"><pre style="margin-top: 0; margin-bottom: 0; "><code><%= testcase.answer %></code></pre></div> <div class="ui existing segment"><pre style="margin-top: 0; margin-bottom: 0; "><code><%= testcase.answer %></code></pre></div>
<strong>你的输出</strong> <strong>你的输出</strong>
<div class="ui existing segment"><pre style="margin-top: 0; margin-bottom: 0; "><code><%= testcase.user_out %></code></pre></div> <div class="ui existing segment"><pre style="margin-top: 0; margin-bottom: 0; "><code><%= testcase.user_out %></code></pre></div>
<% if (testcase.spj_message) { %>
<strong>Special Judge 信息</strong>
<div class="ui existing segment"><pre style="margin-top: 0; margin-bottom: 0; "><code><%= testcase.spj_message %></code></pre></div>
<% } %>
</p> </p>
<% } %> <% } %>
</div> </div>

9
views/upload_testdata.ejs

@ -10,6 +10,11 @@
try { try {
let list = syzoj.utils.parseTestData(problem.testdata.getPath()); let list = syzoj.utils.parseTestData(problem.testdata.getPath());
%> %>
<% if (list.spj) { %>
<p>评测方式:Special Judge</p>
<% } else { %>
<p>评测方式:文本比较</p>
<% } %>
<table class="ui very basic table"> <table class="ui very basic table">
<thead> <thead>
<tr> <tr>
@ -59,7 +64,7 @@
<input name="io_method" value="file-io" id="file-io" type="radio" onclick="goEnable()"> <input name="io_method" value="file-io" id="file-io" type="radio" onclick="goEnable()">
<label for="file-io">文件 IO</label> <label for="file-io">文件 IO</label>
</div> </div>
</div> </div>
</div> </div>
<div class="two fields"> <div class="two fields">
<div class="field"> <div class="field">
@ -85,7 +90,7 @@
<input name="io_method" value="file-io" id="file-io" type="radio" onclick="goEnable()" checked> <input name="io_method" value="file-io" id="file-io" type="radio" onclick="goEnable()" checked>
<label for="file-io">文件 IO</label> <label for="file-io">文件 IO</label>
</div> </div>
</div> </div>
</div> </div>
<div class="two fields"> <div class="two fields">
<div class="field"> <div class="field">

4
views/util.ejs

@ -26,6 +26,8 @@ this.icon = {
'Compiling': 'spinner', 'Compiling': 'spinner',
'Compile Error': 'code', 'Compile Error': 'code',
'System Error': 'server', 'System Error': 'server',
'No Testdata': 'folder open outline' 'No Testdata': 'folder open outline',
'Partially Correct': 'minus',
'Judgement Failed': 'ban'
} }
%> %>

Loading…
Cancel
Save