Upload files to "java/base"
This commit is contained in:
138
java/base/Asserts.java
Normal file
138
java/base/Asserts.java
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
21
java/base/BaseChecker.java
Normal file
21
java/base/BaseChecker.java
Normal 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
114
java/base/Either.java
Normal 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);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
103
java/base/ExtendedRandom.java
Normal file
103
java/base/ExtendedRandom.java
Normal 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
138
java/base/Functional.java
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user