-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCheckC.java
More file actions
114 lines (101 loc) · 4.04 KB
/
CheckC.java
File metadata and controls
114 lines (101 loc) · 4.04 KB
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import java.util.Arrays;
import java.util.Locale;
import java.util.function.Predicate;
import java.util.regex.Pattern;
import java.util.stream.Stream;
/**
* @author Georgiy Korneev (kgeorgiy@kgeorgiy.info)
*/
public class CheckC extends BaseCheck {
public static final String ALPHABET = " \tabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.+-";
private static final double EPS = 1e-10;
public static void main(String[] args) {
new CheckC().testAll();
}
@Override
protected void testAll() {
check("Single integer", " ", "1");
check("Single double", " ", "1.1");
check("Multiple integers", " ", "1", "+2", "-3");
check("Multiple doubles", " ", "1.1", "1e-3", "1e+3");
check("Integers and doubles", " ", "1", "1.1", "2", "1e-3");
check("Point as delimiter", ".", "1", "1.1", "2", "1e-3");
check("eE as delimiter", "eE", "1", "1.1", "2", "1e-3", "1E-3");
for (int n = 10; n <= 1_000_000; n *= 10) {
for (int m = 10; m <= 1_000_000; m *= 10) {
random(n, m);
}
}
}
public boolean isInteger(String s) {
try {
Integer.parseInt(s);
return true;
} catch (NumberFormatException e) {
return false;
}
}
private void random(int n, int m) {
final StringBuilder sb = new StringBuilder();
for (int i = 0; i < m; i++) {
sb.append(randomChar(ALPHABET));
}
if (sb.indexOf("-") >=0) {
sb.append("eE");
}
check(
String.format("Random values=%d", n),
sb.toString(),
Stream.generate(() -> random.nextBoolean() ? "" + random.nextInt() : "" + randomDouble()).limit(random.nextInt(n)).toArray(String[]::new)
);
}
private double randomDouble() {
return (random.nextDouble() * 2 - 1) * Math.pow(10, (double) (random.nextInt(200) - 100));
}
private void check(String description, String delims, String... values) {
test(description, () -> {
System.out.println(" delimiters: " + crop(delims, 30));
write(delims, values);
run(() -> C.main(new String[]{delims}));
final Pattern pattern = Pattern.compile("[" + (delims.contains("-") ? delims.replace("-", "") + "-" : delims) + "]");
final String[] parts = Arrays.stream(values).flatMap(z -> Arrays.stream(pattern.split(z))).filter(not(String::isEmpty)).toArray(String[]::new);
readAndCheck(
Arrays.stream(parts).filter(this::isInteger).mapToLong(Long::parseLong).sum(),
Arrays.stream(parts).filter(not(this::isInteger)).mapToDouble(Double::parseDouble).sum()
);
});
}
private static String crop(String s, int size) {
return s.length() <= 2 * size + 10 ? s : s.substring(0, size) + "<" + (s.length() - size * 2) + " chars>" + s.substring(s.length() - size);
}
static <T> Predicate<T> not(Predicate<T> p) {
return p.negate();
}
private void readAndCheck(long expectedValue, double expectedDouble) {
read(in -> {
in.useLocale(Locale.US);
assertEquals(expectedValue, in.nextLong());
double actualDouble = in.nextDouble();
double d = Math.abs(expectedDouble - actualDouble);
if (d >= EPS && d / actualDouble >= EPS) {
assertEquals(expectedDouble, actualDouble);
}
return null;
});
}
private void write(String delimiters, String[] values) {
write(writer -> {
boolean first = true;
for (String value : values) {
writer.write(first && random.nextBoolean() ? "" : randomWord(delimiters));
first = false;
writer.write(value);
}
if (random.nextBoolean()) {
writer.write(randomWord(delimiters));
}
writer.println();
return null;
});
}
}