From b47fd19096a75af7f92093c7b6d6ef595da712ce Mon Sep 17 00:00:00 2001 From: codejava Date: Mon, 13 Apr 2026 10:38:03 +0300 Subject: [PATCH] Upload files to "java/base" --- java/base/Asserts.java | 138 ++++++++++++++++++++++++++++++++++ java/base/BaseChecker.java | 21 ++++++ java/base/Either.java | 114 ++++++++++++++++++++++++++++ java/base/ExtendedRandom.java | 103 +++++++++++++++++++++++++ java/base/Functional.java | 138 ++++++++++++++++++++++++++++++++++ 5 files changed, 514 insertions(+) create mode 100644 java/base/Asserts.java create mode 100644 java/base/BaseChecker.java create mode 100644 java/base/Either.java create mode 100644 java/base/ExtendedRandom.java create mode 100644 java/base/Functional.java diff --git a/java/base/Asserts.java b/java/base/Asserts.java new file mode 100644 index 0000000..f45545e --- /dev/null +++ b/java/base/Asserts.java @@ -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 void assertEquals( + final String message, + final List expected, + final List 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); + } +} diff --git a/java/base/BaseChecker.java b/java/base/BaseChecker.java new file mode 100644 index 0000000..6bd7753 --- /dev/null +++ b/java/base/BaseChecker.java @@ -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(); + } +} diff --git a/java/base/Either.java b/java/base/Either.java new file mode 100644 index 0000000..aa10621 --- /dev/null +++ b/java/base/Either.java @@ -0,0 +1,114 @@ +package base; + +import java.util.function.Function; + +/** + * @author Georgiy Korneev (kgeorgiy@kgeorgiy.info) + */ +public interface Either { + Either mapRight(final Function f); + Either flatMapRight( + final Function> f + ); + T either( + Function lf, + Function rf + ); + + boolean isRight(); + + L getLeft(); + R getRight(); + + static Either right(final R value) { + return new Either<>() { + @Override + public Either mapRight( + final Function f + ) { + return right(f.apply(value)); + } + + @Override + public Either flatMapRight( + final Function> f + ) { + return f.apply(value); + } + + @Override + public T either( + final Function lf, + final Function 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 Either left(final L value) { + return new Either<>() { + @Override + public Either mapRight( + final Function f + ) { + return left(value); + } + + @Override + public Either flatMapRight( + final Function> f + ) { + return left(value); + } + + @Override + public T either( + final Function lf, + final Function 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); + } + }; + } +} diff --git a/java/base/ExtendedRandom.java b/java/base/ExtendedRandom.java new file mode 100644 index 0000000..bdf8936 --- /dev/null +++ b/java/base/ExtendedRandom.java @@ -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 randomItem(final T... items) { + return items[nextInt(items.length)]; + } + + public T randomItem(final List items) { + return items.get(nextInt(items.size())); + } + + public Random getRandom() { + return random; + } + + public List random( + final int list, + final Function generator + ) { + return Stream.generate(() -> generator.apply(this)) + .limit(list) + .toList(); + } + + public double nextDouble() { + return random.nextDouble(); + } + + public void shuffle(final List all) { + Collections.shuffle(all, random); + } +} diff --git a/java/base/Functional.java b/java/base/Functional.java new file mode 100644 index 0000000..f6a6971 --- /dev/null +++ b/java/base/Functional.java @@ -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 List map( + final Collection items, + final Function f + ) { + return items.stream().map(f).collect(Collectors.toUnmodifiableList()); + } + + public static List map( + final List items, + final BiFunction f + ) { + return IntStream.range(0, items.size()) + .mapToObj(i -> f.apply(i, items.get(i))) + .collect(Collectors.toUnmodifiableList()); + } + + public static Map mapValues( + final Map map, + final Function f + ) { + return map + .entrySet() + .stream() + .collect( + Collectors.toMap(Map.Entry::getKey, e -> f.apply(e.getValue())) + ); + } + + @SafeVarargs + public static Map mergeMaps(final Map... 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 List concat(final Collection... items) { + final List result = new ArrayList<>(); + for (final Collection item : items) { + result.addAll(item); + } + return result; + } + + public static List append( + final Collection collection, + final T item + ) { + final List list = new ArrayList<>(collection); + list.add(item); + return list; + } + + public static List> allValues( + final List 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 V get(final Map 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 values, + final int d, + final int c + ) { + for (int i = -d; i <= d; i++) { + values.add(c + i); + } + } + + public static void forEachPair( + final T[] items, + final BiConsumer 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 List> 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(); + } +}