-
Notifications
You must be signed in to change notification settings - Fork 0
/
06 Match lines.php
100 lines (86 loc) · 2.97 KB
/
06 Match lines.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
<?php
/**
* Test case judge "Match lines" for Sphere Engine Problems
*
*
* The judge iterates over lines of the test case output file and compares them
* with corresponding lines from the program's output file.
*
* A submission is considered as correct (i.e. "accepted") if there is at least
* a single pair of identical corresponding lines.
*
* The score is calculated as a rounded percentage value of matched lines.
*
* EXAMPLE
* Test case output file: Program's output
* 1 1
* 2 4
* 3 3
* 4 2
* 5 5
*
* Status: accepted
* Score: 60 (out of 100)
*
* @copyright Copyright (c) 2018 Sphere Research Labs (http://sphere-engine.com)
*/
// file descriptors
const TEST_CASE_INPUT_FD = 0;
const TEST_CASE_OUTPUT_FD = 4;
const PROGRAM_SOURCE_FD = 5;
const PROGRAM_OUTPUT_FD = 3;
const PROGRAM_INPUT_FD = 8; // interactive only
const SCORE_FD = 1;
const DEBUG_FD = 6;
// statuses
const ACCEPTED = 0;
const WRONG_ANSWER = 1;
// streams
$streams = [
// reading
'test_case_input' => fopen('php://fd/' . TEST_CASE_INPUT_FD , "r"),
'test_case_output' => fopen('php://fd/' . TEST_CASE_OUTPUT_FD , "r"),
'program_source' => fopen('php://fd/' . PROGRAM_SOURCE_FD , "r"),
'program_output' => fopen('php://fd/' . PROGRAM_OUTPUT_FD , "r"),
// writing
'program_input' => fopen('php://fd/' . PROGRAM_INPUT_FD , "w"), // interactive only
'score' => fopen('php://fd/' . SCORE_FD , "w"),
'debug' => fopen('php://fd/' . DEBUG_FD , "w"),
];
function close_streams() {
global $streams;
foreach ($streams as $s) {
fclose($s);
}
}
////////////////////////////////////////////////////////////////////////////////
$number_of_lines = 0;
$number_of_correct_lines = 0;
while (($test_case_output_line = fgets($streams['test_case_output'])) !== false) {
$test_case_output_line = rtrim($test_case_output_line, "\n");
$program_output_line = fgets($streams['program_output']);
$number_of_lines++;
if ($program_output_line === false) {
fprintf($streams['debug'],
"Outputs differ on line %d. Expected \"%s\" but program's output has ended before.\n",
$number_of_lines, $test_case_output_line);
continue;
}
$program_output_line = rtrim($program_output_line, "\n");
if ($test_case_output_line == $program_output_line) {
$number_of_correct_lines++;
} else {
fprintf($streams['debug'],
"Outputs differ on line %d. Expected \"%s\" but was \"%s\".\n",
$number_of_lines, $test_case_output_line, $program_output_line);
}
}
// determine result (i.e. score and status)
$score = ($number_of_lines == 0) ? 100 : intval(100 * $number_of_correct_lines / $number_of_lines);
$status = ($score > 0) ? ACCEPTED : WRONG_ANSWER;
// set score
fwrite($streams['score'], $score);
// close streams
close_streams();
// exit with suitable status
exit($status);