summaryrefslogtreecommitdiff
path: root/Phone Book/task/test/PhoneBookTest.java
blob: 919c0eadb1a52f35c8b57fd1f7ab67b2657bb523 (plain)
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();
    }
}