Files
prog-intro-2025/java/wordStat/WordStatChecker.java
2026-01-29 23:20:12 +05:00

128 lines
4.9 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package wordStat;
import base.*;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
/**
* @author Georgiy Korneev (kgeorgiy@kgeorgiy.info)
*/
public final class WordStatChecker extends BaseChecker {
public static final String DASH = "-֊־‒–—―⸗⸚⸺〰゠︱︲﹘﹣-'";
public static final String SIMPLE_DELIMITERS = " \t";
public static final String ADVANCED_DELIMITERS = " \t!\"#%&()*+,./:;<=>?@[\\]^`{|}~ ¡¦§¨©«¬\u00AD®¯°±²³´¶·¸¹»¼½¾¿×÷˂˃˄˅˒˓˔˕˖˗˘˙˚˛˜˝";
public static final String ALL = ExtendedRandom.RUSSIAN + ExtendedRandom.ENGLISH + ExtendedRandom.GREEK + DASH;
private static final Pattern PATTERN = Pattern.compile("[^\\p{IsLetter}'\\p{Pd}]+");
public static final Runner.Packages RUNNER = Runner.packages("", "wordstat", "wspp");
private final Function<String[][], ? extends List<? extends Pair<?, ?>>> processor;
private final MainChecker main;
private WordStatChecker(
final String className,
final Function<String[][], ? extends List<? extends Pair<?, ?>>> processor,
final TestCounter counter
) {
super(counter);
main = new MainChecker(RUNNER.files(className));
this.processor = processor;
}
public static void test(
final TestCounter counter,
final String className,
final Function<String[][], ? extends List<? extends Pair<?, ?>>> processor,
final Consumer<WordStatChecker> tests
) {
tests.accept(new WordStatChecker(className, processor, counter));
}
public void test(final String... lines) {
test(PATTERN, lines);
}
public void test(final Pattern pattern, final String... lines) {
final String[][] data = Arrays.stream(lines)
.map(line -> Arrays.stream(pattern.split(line)).filter(Predicate.not(String::isEmpty)).toArray(String[]::new))
.toArray(String[][]::new);
test(lines, processor.apply(data));
}
private void randomTest(
final int wordLength,
final int totalWords,
final int wordsPerLine,
final int lines,
final String chars,
final String delimiters,
final Function<String[][], List<? extends Pair<?, ?>>> processor
) {
final String[] words = generateWords(wordLength, totalWords, chars);
final String[][] text = generateTest(lines, words, wordsPerLine);
test(input(text, delimiters), processor.apply(text));
}
public void randomTest(
final int wordLength,
final int totalWords,
final int wordsPerLine,
final int lines,
final String chars,
final String delimiters
) {
randomTest(wordLength, totalWords, wordsPerLine, lines, chars, delimiters, processor::apply);
}
private void test(final String[] text, final List<? extends Pair<?, ?>> expected) {
final List<String> expectedList = expected.stream()
.map(p -> p.first() + " " + p.second())
.collect(Collectors.toList());
main.testEquals(counter, Arrays.asList(text), expectedList);
}
public void test(final String[][] text, final String delimiters, final List<Pair<String, Integer>> answer) {
test(input(text, delimiters), answer);
}
private String[] generateWords(final int wordLength, final int totalWords, final String chars) {
final String allChars = chars.chars().anyMatch(Character::isUpperCase)
? chars : chars + chars.toUpperCase(Locale.ROOT);
return IntStream.range(0, totalWords)
.mapToObj(i -> random().randomString(allChars, wordLength / 2, wordLength))
.toArray(String[]::new);
}
private String[][] generateTest(final int lines, final String[] words, final int wordsPerLine) {
final String[][] text = new String[lines][];
for (int i = 0; i < text.length; i++) {
text[i] = new String[random().nextInt(wordsPerLine / 2, wordsPerLine)];
for (int j = 0; j < text[i].length; j++) {
text[i][j] = random().randomItem(words);
}
}
return text;
}
private String[] input(final String[][] text, final String delimiters) {
final String[] input = new String[text.length];
for (int i = 0; i < text.length; i++) {
final String[] line = text[i];
final StringBuilder sb = new StringBuilder(random().randomString(delimiters));
for (final String word : line) {
sb.append(word).append(random().randomString(delimiters));
}
input[i] = sb.toString();
}
return input;
}
}