Upload files to "java/base"

This commit is contained in:
2026-04-13 10:38:03 +03:00
parent 9a225ab16a
commit b47fd19096
5 changed files with 514 additions and 0 deletions

138
java/base/Asserts.java Normal file
View File

@@ -0,0 +1,138 @@
package base;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
/**
* @author Georgiy Korneev (kgeorgiy@kgeorgiy.info)
*/
@SuppressWarnings("StaticMethodOnlyUsedInOneClass")
public final class Asserts {
static {
Locale.setDefault(Locale.US);
}
private Asserts() {}
public static void assertEquals(
final String message,
final Object expected,
final Object actual
) {
final String reason = String.format(
"%s:%n expected `%s`,%n actual `%s`",
message,
toString(expected),
toString(actual)
);
assertTrue(reason, Objects.deepEquals(expected, actual));
}
public static String toString(final Object value) {
if (value != null && value.getClass().isArray()) {
final String result = Arrays.deepToString(new Object[] { value });
return result.substring(1, result.length() - 1);
} else {
return Objects.toString(value);
}
}
public static <T> void assertEquals(
final String message,
final List<T> expected,
final List<T> actual
) {
for (int i = 0; i < Math.min(expected.size(), actual.size()); i++) {
assertEquals(
message + ":" + (i + 1),
expected.get(i),
actual.get(i)
);
}
assertEquals(
message + ": Number of items",
expected.size(),
actual.size()
);
}
public static void assertTrue(final String message, final boolean value) {
if (!value) {
throw error("%s", message);
}
}
public static void assertEquals(
final String message,
final double expected,
final double actual,
final double precision
) {
assertTrue(
String.format(
"%s: Expected %.12f, found %.12f",
message,
expected,
actual
),
isEqual(expected, actual, precision)
);
}
public static boolean isEqual(
final double expected,
final double actual,
final double precision
) {
final double error = Math.abs(actual - expected);
return (
error <= precision ||
error <= precision * Math.abs(expected) ||
!Double.isFinite(expected) ||
Math.abs(expected) > 1e100 ||
(Math.abs(expected) < precision && !Double.isFinite(actual))
);
}
public static void assertSame(
final String message,
final Object expected,
final Object actual
) {
assertTrue(
String.format(
"%s: expected same objects: %s and %s",
message,
expected,
actual
),
expected == actual
);
}
public static void checkAssert(final Class<?> c) {
if (!c.desiredAssertionStatus()) {
throw error(
"You should enable assertions by running 'java -ea %s'",
c.getName()
);
}
}
public static AssertionError error(
final String format,
final Object... args
) {
final String message = String.format(format, args);
return args.length > 0 && args[args.length - 1] instanceof Throwable
? new AssertionError(message, (Throwable) args[args.length - 1])
: new AssertionError(message);
}
public static void printStackTrace(final String message) {
new Exception(message).printStackTrace(System.out);
}
}

View File

@@ -0,0 +1,21 @@
package base;
/**
* @author Georgiy Korneev (kgeorgiy@kgeorgiy.info)
*/
public abstract class BaseChecker {
protected final TestCounter counter;
protected BaseChecker(final TestCounter counter) {
this.counter = counter;
}
public ExtendedRandom random() {
return counter.random();
}
public int mode() {
return counter.mode();
}
}

114
java/base/Either.java Normal file
View File

@@ -0,0 +1,114 @@
package base;
import java.util.function.Function;
/**
* @author Georgiy Korneev (kgeorgiy@kgeorgiy.info)
*/
public interface Either<L, R> {
<NR> Either<L, NR> mapRight(final Function<? super R, NR> f);
<NR> Either<L, NR> flatMapRight(
final Function<? super R, ? extends Either<L, NR>> f
);
<T> T either(
Function<? super L, ? extends T> lf,
Function<? super R, ? extends T> rf
);
boolean isRight();
L getLeft();
R getRight();
static <L, R> Either<L, R> right(final R value) {
return new Either<>() {
@Override
public <NR> Either<L, NR> mapRight(
final Function<? super R, NR> f
) {
return right(f.apply(value));
}
@Override
public <NR> Either<L, NR> flatMapRight(
final Function<? super R, ? extends Either<L, NR>> f
) {
return f.apply(value);
}
@Override
public <T> T either(
final Function<? super L, ? extends T> lf,
final Function<? super R, ? extends T> rf
) {
return rf.apply(value);
}
@Override
public boolean isRight() {
return true;
}
@Override
public L getLeft() {
return null;
}
@Override
public R getRight() {
return value;
}
@Override
public String toString() {
return String.format("Right(%s)", value);
}
};
}
static <L, R> Either<L, R> left(final L value) {
return new Either<>() {
@Override
public <NR> Either<L, NR> mapRight(
final Function<? super R, NR> f
) {
return left(value);
}
@Override
public <NR> Either<L, NR> flatMapRight(
final Function<? super R, ? extends Either<L, NR>> f
) {
return left(value);
}
@Override
public <T> T either(
final Function<? super L, ? extends T> lf,
final Function<? super R, ? extends T> rf
) {
return lf.apply(value);
}
@Override
public boolean isRight() {
return false;
}
@Override
public L getLeft() {
return value;
}
@Override
public R getRight() {
return null;
}
@Override
public String toString() {
return String.format("Left(%s)", value);
}
};
}
}

View File

@@ -0,0 +1,103 @@
package base;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import java.util.function.Function;
import java.util.stream.Stream;
/**
* @author Georgiy Korneev (kgeorgiy@kgeorgiy.info)
*/
public final class ExtendedRandom {
public static final String ENGLISH = "abcdefghijklmnopqrstuvwxyz";
public static final String RUSSIAN = "абвгдеежзийклмнопрстуфхцчшщъыьэюя";
public static final String GREEK = "αβγŋδεζηθικλμνξοπρτυφχψω";
@SuppressWarnings("StaticMethodOnlyUsedInOneClass")
public static final String SPACES = " \t\n\u000B\u2029\f";
private final Random random;
public ExtendedRandom(final Random random) {
this.random = random;
}
public ExtendedRandom(final Class<?> owner) {
this(new Random(7912736473497634913L + owner.getName().hashCode()));
}
public String randomString(final String chars) {
return (
randomChar(chars) +
(random.nextBoolean() ? "" : randomString(chars))
);
}
public char randomChar(final String chars) {
return chars.charAt(nextInt(chars.length()));
}
public String randomString(final String chars, final int length) {
final StringBuilder string = new StringBuilder();
for (int i = 0; i < length; i++) {
string.append(randomChar(chars));
}
return string.toString();
}
public String randomString(
final String chars,
final int minLength,
final int maxLength
) {
return randomString(chars, nextInt(minLength, maxLength));
}
public boolean nextBoolean() {
return random.nextBoolean();
}
public int nextInt() {
return random.nextInt();
}
public int nextInt(final int min, final int max) {
return nextInt(max - min + 1) + min;
}
public int nextInt(final int n) {
return random.nextInt(n);
}
@SafeVarargs
public final <T> T randomItem(final T... items) {
return items[nextInt(items.length)];
}
public <T> T randomItem(final List<T> items) {
return items.get(nextInt(items.size()));
}
public Random getRandom() {
return random;
}
public <T> List<T> random(
final int list,
final Function<ExtendedRandom, T> generator
) {
return Stream.generate(() -> generator.apply(this))
.limit(list)
.toList();
}
public double nextDouble() {
return random.nextDouble();
}
public <E> void shuffle(final List<E> all) {
Collections.shuffle(all, random);
}
}

138
java/base/Functional.java Normal file
View File

@@ -0,0 +1,138 @@
package base;
import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
/**
* @author Georgiy Korneev (kgeorgiy@kgeorgiy.info)
*/
public final class Functional {
private Functional() {}
public static <T, R> List<R> map(
final Collection<T> items,
final Function<? super T, ? extends R> f
) {
return items.stream().map(f).collect(Collectors.toUnmodifiableList());
}
public static <T, R> List<R> map(
final List<T> items,
final BiFunction<? super Integer, ? super T, ? extends R> f
) {
return IntStream.range(0, items.size())
.mapToObj(i -> f.apply(i, items.get(i)))
.collect(Collectors.toUnmodifiableList());
}
public static <K, T, R> Map<K, R> mapValues(
final Map<K, T> map,
final Function<T, R> f
) {
return map
.entrySet()
.stream()
.collect(
Collectors.toMap(Map.Entry::getKey, e -> f.apply(e.getValue()))
);
}
@SafeVarargs
public static <K, T> Map<K, T> mergeMaps(final Map<K, T>... maps) {
return Stream.of(maps)
.flatMap(m -> m.entrySet().stream())
.collect(
Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(a, b) -> a
)
);
}
@SafeVarargs
public static <T> List<T> concat(final Collection<? extends T>... items) {
final List<T> result = new ArrayList<>();
for (final Collection<? extends T> item : items) {
result.addAll(item);
}
return result;
}
public static <T> List<T> append(
final Collection<T> collection,
final T item
) {
final List<T> list = new ArrayList<>(collection);
list.add(item);
return list;
}
public static <T> List<List<T>> allValues(
final List<T> vals,
final int length
) {
return Stream.generate(() -> vals)
.limit(length)
.reduce(
List.of(List.of()),
(prev, next) ->
next
.stream()
.flatMap(value ->
prev.stream().map(list -> append(list, value))
)
.toList(),
(prev, next) ->
next
.stream()
.flatMap(suffix ->
prev.stream().map(prefix -> concat(prefix, suffix))
)
.toList()
);
}
public static <K, V> V get(final Map<K, V> map, final K key) {
final V result = map.get(key);
if (result == null) {
throw new NullPointerException(
key.toString() + " in " + map(map.keySet(), Objects::toString)
);
}
return result;
}
public static void addRange(
final List<Integer> values,
final int d,
final int c
) {
for (int i = -d; i <= d; i++) {
values.add(c + i);
}
}
public static <T> void forEachPair(
final T[] items,
final BiConsumer<? super T, ? super T> consumer
) {
assert items.length % 2 == 0;
IntStream.range(0, items.length / 2).forEach(i ->
consumer.accept(items[i * 2], items[i * 2 + 1])
);
}
public static <T> List<Pair<T, T>> toPairs(final T[] items) {
assert items.length % 2 == 0;
return IntStream.range(0, items.length / 2)
.mapToObj(i -> Pair.of(items[i * 2], items[i * 2 + 1]))
.toList();
}
}