Change how batch scoring works

This commit is contained in:
cuom1999 2022-11-19 21:41:43 -06:00
parent 65dea68be3
commit 01c0365208
5 changed files with 89 additions and 51 deletions

View file

@ -500,8 +500,8 @@ class JudgeHandler(ZlibPacketHandler):
total += case.total total += case.total
else: else:
if case.batch in batches: if case.batch in batches:
batches[case.batch][0] = min(batches[case.batch][0], case.points) batches[case.batch][0] += case.points
batches[case.batch][1] = max(batches[case.batch][1], case.total) batches[case.batch][1] += case.total
else: else:
batches[case.batch] = [case.points, case.total] batches[case.batch] = [case.points, case.total]
memory = max(memory, case.memory) memory = max(memory, case.memory)
@ -513,8 +513,8 @@ class JudgeHandler(ZlibPacketHandler):
points += batches[i][0] points += batches[i][0]
total += batches[i][1] total += batches[i][1]
points = round(points, 1) points = points
total = round(total, 1) total = total
submission.case_points = points submission.case_points = points
submission.case_total = total submission.case_total = total

View file

@ -122,7 +122,8 @@ class ProblemDataCompiler(object):
if case.type == "C": if case.type == "C":
data = {} data = {}
if batch: if batch:
case.points = None if case.points is None:
case.points = 0
case.is_pretest = batch["is_pretest"] case.is_pretest = batch["is_pretest"]
else: else:
if case.points is None: if case.points is None:

View file

@ -161,8 +161,8 @@ class SubmissionSource(SubmissionDetailBase):
def make_batch(batch, cases): def make_batch(batch, cases):
result = {"id": batch, "cases": cases} result = {"id": batch, "cases": cases}
if batch: if batch:
result["points"] = min(map(attrgetter("points"), cases)) result["points"] = sum(map(attrgetter("points"), cases))
result["total"] = max(map(attrgetter("total"), cases)) result["total"] = sum(map(attrgetter("total"), cases))
return result return result

View file

@ -82,7 +82,7 @@
$table.find('tbody:first tr').each(function () { $table.find('tbody:first tr').each(function () {
switch ($(this).attr('data-type')) { switch ($(this).attr('data-type')) {
case 'C': case 'C':
$(this).find('input[id$=points], input[id$=pretest]').toggle(!in_batch); $(this).find('input[id$=pretest]').toggle(!in_batch);
break; break;
case 'S': case 'S':
in_batch = true; in_batch = true;
@ -169,7 +169,7 @@
var $opts = $tr.find('input').slice(2, 6); var $opts = $tr.find('input').slice(2, 6);
var $files = $tr.find('select').slice(1, 3); var $files = $tr.find('select').slice(1, 3);
var $checker = $files.end().last(); var $delete = $files.end().last();
$tr.find('select[id$=type]').change(function () { $tr.find('select[id$=type]').change(function () {
var $this = $(this), val = $this.val(), disabled; var $this = $(this), val = $this.val(), disabled;
switch (val) { switch (val) {
@ -178,18 +178,18 @@
disabled = val == 'S'; disabled = val == 'S';
$opts.toggle(val == 'S'); $opts.toggle(val == 'S');
$files.siblings('.select2').hide(); $files.siblings('.select2').hide();
$checker.toggle(val == 'S'); $delete.toggle(val == 'S');
break; break;
default: default:
$opts.toggle(val == 'C'); $opts.toggle(val == 'C');
$files.siblings('.select2').toggle(val == 'C'); $files.siblings('.select2').toggle(val == 'C');
$checker.toggle(val == 'C'); $delete.toggle(val == 'C');
var $prevs = $tr.prevAll('tr[data-type=S], tr[data-type=E]'); var $prevs = $tr.prevAll('tr[data-type=S], tr[data-type=E]');
disabled = $prevs.length && $prevs.get(0).getAttribute('data-type') == 'S'; disabled = $prevs.length && $prevs.get(0).getAttribute('data-type') == 'S';
$tr.find('input[id$=points], input[id$=pretest]').toggle(val == 'C' && !disabled); $tr.find('input[id$=pretest]').toggle(val == 'C' && !disabled);
} }
$tr.attr('data-type', val).nextUntil('tr[data-type=S], tr[data-type=E], tr[data-type=""]') $tr.attr('data-type', val).nextUntil('tr[data-type=S], tr[data-type=E], tr[data-type=""]')
.find('input[id$=points], input[id$=pretest]').toggle(!disabled); .find('input[id$=pretest]').toggle(!disabled);
}).change(); }).change();
var tooltip_classes = 'tooltipped tooltipped-s'; var tooltip_classes = 'tooltipped tooltipped-s';
@ -278,7 +278,8 @@
return false; return false;
} }
$('a#fill-testcases').click(function () { $('a#fill-testcases').click(function (e) {
e.preventDefault();
var inFiles = [], outFiles = []; var inFiles = [], outFiles = [];
for (let file of window.valid_files) { for (let file of window.valid_files) {
if (isInpFile(file)) { if (isInpFile(file)) {
@ -305,30 +306,46 @@
window.big_input = true; window.big_input = true;
} }
// add boxes var batch_starts = $('#batch_starts').val();
while ($total.val() < inFiles.length) { batch_starts = batch_starts.split(',');
batch_starts = batch_starts.filter(e => {
return e.length && e == +e;
});
batch_starts = new Set(batch_starts.map(x => Math.min(Math.max(1, parseInt(x)), inFiles.length - 1)));
batch_starts.add(inFiles.length + 1);
var numRows = inFiles.length + 2 * batch_starts.size - 2;
while ($total.val() < numRows) {
$('a#add-case-row').click(); $('a#add-case-row').click();
} }
// fill cases
for (var i = 0; i < inFiles.length; i++) {
var $select = $("#id_cases-" + i + "-input_file");
$select.select2('destroy').empty().select2({ data: [inFiles[i]] });
$select.val(inFiles[i]).change();
}
for (var i = 0; i < outFiles.length; i++) {
var $select = $("#id_cases-" + i + "-output_file");
$select.select2('destroy').empty().select2({ data: [outFiles[i]] });
$select.val(outFiles[i]).change();
}
// add points // fill cases
if ($('#problem-type').val() == "ICPC") { var row = 0;
$('#case-table tbody tr td').find('input[id$=points]').val('0').change(); for (var i = 0; i < inFiles.length; i++) {
$('#case-table tbody tr td').find('input[id$=points]:visible') if (batch_starts.has(i + 1)) {
.last().val('100').change(); $("#id_cases-"+row+"-type").val('S').change();
} row += 1;
else { }
$('#case-table tbody tr td').find('input[id$=points]').val('1').change() var $input = $("#id_cases-"+row+"-input_file");
$input.select2('destroy').empty().select2({ data: [inFiles[i]] });
$input.val(inFiles[i]).change();
var $output = $("#id_cases-"+row+"-input_file");
$output.select2('destroy').empty().select2({ data: [outFiles[i]] });
$output.val(outFiles[i]).change();
if ($("#problem-type").val() == "ICPC") {
$("#id_cases-"+row+"-points").val('0').change();
}
else {
$("#id_cases-"+row+"-points").val('1').change();
}
row += 1;
if (batch_starts.has(i + 2)) {
$("#id_cases-"+(row-1)+"-points").val('1').change();
$("#id_cases-"+row+"-type").val('E').change();
row += 1;
}
} }
return false; return false;
}); });
@ -374,6 +391,23 @@
// Change to OI if the first row point > 0 // Change to OI if the first row point > 0
if($("#id_cases-0-points").val() != '0') $('#problem-type').val('OI'); if($("#id_cases-0-points").val() != '0') $('#problem-type').val('OI');
// Change batch_starts based on current tests
function update_batch_starts() {
var numBatches = 0;
var batchStarts = [];
$("#case-table tbody:first tr").each(function(idx) {
$select = $('#id_cases-' + idx + '-type');
if ($select.val() == 'S') {
batchStarts.push(idx + 1 - 2 * numBatches);
numBatches++;
}
});
if (batchStarts) {
$("#batch_starts").val(batchStarts.join(', '));
}
}
update_batch_starts();
}).change(); }).change();
</script> </script>
{% include 'fine_uploader/script.html' %} {% include 'fine_uploader/script.html' %}
@ -453,15 +487,24 @@
<label>{{_('Autofill testcases')}}:</label> <label>{{_('Autofill testcases')}}:</label>
</th> </th>
<td> <td>
{{_('Problem type')}}: <div>
<select id="problem-type"> {{_('Problem type')}}:
<option value="ICPC">ICPC</option> <select id="problem-type">
<option value="OI">OI</option> <option value="ICPC">ICPC</option>
</select> <option value="OI">OI</option>
<a id="fill-testcases" href="#"> </select>
<i class="fa fa-circle"></i> <a id="fill-testcases" href="#">
{{_('Fill testcases')}} <i class="fa fa-circle"></i>
</a> {{_('Fill testcases')}}
</a>
</div>
<div style="margin-top: 1em;">
{{_("Batch start positions")}}:
<input id="batch_starts">
</div>
<div>
{{_("Leave empty if not use batch. If you want to divide to three batches [1, 4], [5, 8], [9, 10], enter: 1, 5, 9")}}
</div>
</td> </td>
</table> </table>
<input type="submit" value="{{ _('Apply!') }}" class="button" id="submit-button"> <input type="submit" value="{{ _('Apply!') }}" class="button" id="submit-button">

View file

@ -127,14 +127,8 @@
</td> </td>
<td><span class="col-title">{{_('Point')}}: </span> <td><span class="col-title">{{_('Point')}}: </span>
{% if not batch.id %} {{ case.points|floatformat }}/{{ case.total|floatformat }}
{{ case.points|floatformat }}/{{ case.total|floatformat(0) }}
{% else %}
-
{% endif %}
</td> </td>
<td> <td>
{%- if case.status != 'SC' -%} {%- if case.status != 'SC' -%}
{%- if case.status == 'TLE' -%} {%- if case.status == 'TLE' -%}