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
|
import org.hyperskill.hstest.stage.StageTest;
import org.hyperskill.hstest.testcase.CheckResult;
import org.hyperskill.hstest.testcase.TestCase;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class PhoneBookTest extends StageTest {
private long timeOnTestStart;
private static String outputFirstTest;
@Override
public List<TestCase> generate() {
timeOnTestStart = System.currentTimeMillis();
return Arrays.asList(
new TestCase<>().setTimeLimit(30 * 60 * 1000),
new TestCase<>().setTimeLimit(30 * 60 * 1000).setCheckFunc((reply, attach) -> {
if (reply.equals(outputFirstTest)) {
return CheckResult.wrong(
"Your program output is exactly the same during different runs. " +
"Does your program just output a string?"
);
}
return CheckResult.correct();
})
);
}
private CheckResult checkPhrases(String reply, String... phrases) {
reply = reply.toLowerCase();
for (String phrase : phrases) {
if (!reply.contains(phrase.toLowerCase())) {
return CheckResult.wrong("Not found the part `" + phrase + "` in your output.");
}
}
return CheckResult.correct();
}
private Pattern timePattern = Pattern.compile(".*(\\d+)\\s*min.*?(\\d+)\\s*sec.*?(\\d+)\\s*ms.*", Pattern.DOTALL);
// returns -1 if not matches.
private long getUserEstimatedTime(String reply) {
Matcher matcher = timePattern.matcher(reply);
if (!matcher.matches()) {
return -1;
}
int min = Integer.parseInt(matcher.group(1));
int sec = Integer.parseInt(matcher.group(2));
int ms = Integer.parseInt(matcher.group(3));
return ms + sec * 1000 + min * 1000 * 60;
}
@Override
public CheckResult check(String reply, Object clue) {
outputFirstTest = reply;
long realTime = System.currentTimeMillis() - timeOnTestStart;
timeOnTestStart = System.currentTimeMillis();
// System.out.println("Time delta: " + realTime);
if (!reply.contains("500 / 500") && !reply.contains("500/500")) {
return CheckResult.wrong("Your output should contain `500 / 500` fragment.");
}
CheckResult res = checkPhrases(reply, "start searching", "found",
"min.", "sec.", "ms.");
if (!res.isCorrect()) {
return res;
}
long estimatedTime = getUserEstimatedTime(reply);
if (estimatedTime == -1) {
return CheckResult.wrong("Your output format doesn't contain numbers before min, sec, ms words.");
}
if (realTime < 1000) {
return CheckResult.wrong("Your program completes too fast. Faster than a second!");
}
double ratio = estimatedTime / (realTime + 0.0);
if (ratio < 0.5 || ratio > 1.5) {
return CheckResult.wrong("Too large difference between the real working time and your output. " +
"Real program working time was " + realTime + " ms, and your output contained " + estimatedTime + "ms in total.");
}
return CheckResult.correct();
}
}
|