diff --git a/java/.idea/.gitignore b/java/.idea/.gitignore new file mode 100644 index 0000000..ab1f416 --- /dev/null +++ b/java/.idea/.gitignore @@ -0,0 +1,10 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Ignored default folder with query files +/queries/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/java/expression/BigDecimalListExpression.java b/java/expression/BigDecimalListExpression.java deleted file mode 100644 index 67841c3..0000000 --- a/java/expression/BigDecimalListExpression.java +++ /dev/null @@ -1,202 +0,0 @@ -package expression; - -import base.Asserts; -import base.Pair; -import base.TestCounter; -import expression.common.ExpressionKind; -import expression.common.Type; - -import java.math.BigDecimal; -import java.util.List; -import java.util.stream.IntStream; - -/** - * One-argument arithmetic expression over {@link BigDecimal}s. - * - * @author Georgiy Korneev (kgeorgiy@kgeorgiy.info) - */ -@FunctionalInterface -@SuppressWarnings("ClassReferencesSubclass") -public interface BigDecimalListExpression extends ToMiniString { - BigDecimal evaluateBd(List variables); - - // Tests follow. You may temporarily remove everything til the end. - - Add EXAMPLE = new Add( - new Subtract(new Variable(0), new Const(BigDecimal.ONE)), - new Multiply(new Variable(1), new Const(BigDecimal.TEN)) - ); - - Type TYPE = new Type<>( - v -> new BigDecimal(v + ".000"), - random -> BigDecimal.valueOf(random.getRandom().nextGaussian()), - BigDecimal.class - ); - ExpressionKind KIND = new ExpressionKind<>( - TYPE, - BigDecimalListExpression.class, - (r, c) -> IntStream.range(0, c) - .mapToObj(name -> Pair.of("$" + name, new Variable(name))) - .toList(), - (expr, variables, values) -> expr.evaluateBd(values) - ); - - @SuppressWarnings("BigDecimalMethodWithoutRoundingCalled") - static ExpressionTester tester(final TestCounter counter) { - Asserts.assertEquals("Example toString()", "(($0 - 1) + ($1 * 10))", EXAMPLE.toString()); - Asserts.assertEquals( - EXAMPLE + " at (2, 3)", - BigDecimal.valueOf(31), - EXAMPLE.evaluateBd(List.of(BigDecimal.valueOf(2), BigDecimal.valueOf(3))) - ); - - final Variable vx = new Variable(0); - final Variable vy = new Variable(1); - - return new ExpressionTester<>( - counter, KIND, c -> v -> c, - (op, a, b) -> v -> op.apply(a.evaluateBd(v), b.evaluateBd(v)), - BigDecimal::add, BigDecimal::subtract, BigDecimal::multiply, BigDecimal::divide - ) - .basic("10", "10", v -> v(10), c(10)) - .basic("$x", "$x", BigDecimalListExpression::x, vx) - .basic("$y", "$y", BigDecimalListExpression::y, vy) - .basic("($x + $y)", "$x + $y", v -> x(v).add(y(v)), new Add(vx, vy)) - .basic("($x + 2)", "$x + 2", v -> x(v).add(v(2)), new Add(vx, c(2))) - .basic("(2 - $x)", "2 - $x", v -> v(2).subtract(x(v)), new Subtract(c(2), vx)) - .basic("(3 * $x)", "3 * $x", v -> v(3).multiply(x(v)), new Multiply(c(3), vx)) - .basic("($x + $x)", "$x + $x", v -> x(v).add(x(v)), new Add(vx, vx)) - .basic("($x / -2)", "$x / -2", v -> x(v).divide(v(-2)), new Divide(vx, c(-2))) - .basic("(2 + $x)", "2 + $x", v -> v(2).add(x(v)), new Add(c(2), vx)) - .basic("((1 + 2) + 3)", "1 + 2 + 3", v -> v(6), new Add(new Add(c(1), c(2)), c(3))) - .basic("(1 + (2 * 3))", "1 + 2 * 3", v -> v(7), new Add(c(1), new Multiply(c(2), c(3)))) - .basic("(1 - (2 * 3))", "1 - 2 * 3", v -> v(-5), new Subtract(c(1), new Multiply(c(2), c(3)))) - .basic("(1 + (2 + 3))", "1 + 2 + 3", v -> v(6), new Add(c(1), new Add(c(2), c(3)))) - .basic("((1 - 2) - 3)", "1 - 2 - 3", v -> v(-4), new Subtract(new Subtract(c(1), c(2)), c(3))) - .basic("(1 - (2 - 3))", "1 - (2 - 3)", v -> v(2), new Subtract(c(1), new Subtract(c(2), c(3)))) - .basic("((1 * 2) * 3)", "1 * 2 * 3", v -> v(6), new Multiply(new Multiply(c(1), c(2)), c(3))) - .basic("(1 * (2 * 3))", "1 * 2 * 3", v -> v(6), new Multiply(c(1), new Multiply(c(2), c(3)))) - .basic("((10 / 2) / 3)", "10 / 2 / 3", v -> v(10).divide(v(2)).divide(v(3)), new Divide(new Divide(c(10), c(2)), c(3))) - .basic("(10 / (3 / 2))", "10 / (3 / 2)", v -> v(10).divide(v(3).divide(v(2))), new Divide(c(10), new Divide(c(3), c(2)))) - .basic("(($x * $x) + (($x - 1) / 10))", - "$x * $x + ($x - 1) / 10", - v -> x(v).multiply(x(v)).add(x(v).subtract(v(1)).divide(v(10))), - new Add(new Multiply(vx, vx), new Divide(new Subtract(vx, c(1)), c(10))) - ) - .basic("($x * -1000000000)", "$x * -1000000000", v -> x(v).multiply(v(-1_000_000_000)), new Multiply(vx, c(-1_000_000_000))) - .basic("($x * -1000000000000000)", "$x * -1000000000000000", v -> x(v).multiply(v(-1_000_000_000_000_000L)), new Multiply(vx, c(-1_000_000_000_000_000L))) - .basic("(10 / $x)", "10 / $x", v -> v(10).divide(x(v)), new Divide(c(10), vx)) - .basic("($x / $x)", "$x / $x", v -> x(v).divide(x(v)), new Divide(vx, vx)) - - .advanced("(2 + 1)", "2 + 1", v -> v(2 + 1), new Add(c(2), c(1))) - .advanced("($x - 1)", "$x - 1", v -> x(v).subtract(v(1)), new Subtract(vx, c(1))) - .advanced("(1 * 2)", "1 * 2", v -> v(1 * 2), new Multiply(c(1), c(2))) - .advanced("($x / 1)", "$x / 1", v -> x(v).divide(v(1)), new Divide(vx, c(1))) - .advanced("(1 + (2 + 1))", "1 + 2 + 1", v -> v(1 + 2 + 1), new Add(c(1), new Add(c(2), c(1)))) - .advanced("($x - ($x - 1))", "$x - ($x - 1)", v -> x(v).subtract(x(v).subtract(v(1))), new Subtract(vx, new Subtract(vx, c(1)))) - .advanced("(2 * ($x / 1))", "2 * ($x / 1)", v -> v(2).multiply(x(v).divide(v(1))), new Multiply(c(2), new Divide(vx, c(1)))) - .advanced("(2 / ($x - 1))", "2 / ($x - 1)", v -> v(2).divide(x(v).subtract(v(1))), new Divide(c(2), new Subtract(vx, c(1)))) - .advanced("((1 * 2) + $x)", "1 * 2 + $x", v -> v(1 * 2).add(x(v)), new Add(new Multiply(c(1), c(2)), vx)) - .advanced("(($x - 1) - 2)", "$x - 1 - 2", v -> x(v).subtract(v(3)), new Subtract(new Subtract(vx, c(1)), c(2))) - .advanced("(($x / 1) * 2)", "$x / 1 * 2", v -> x(v).multiply(v(2)), new Multiply(new Divide(vx, c(1)), c(2))) - .advanced("((2 + 1) / 1)", "(2 + 1) / 1", v -> v(3), new Divide(new Add(c(2), c(1)), c(1))) - .advanced( - "(1 + (1 + (2 + 1)))", - "1 + 1 + 2 + 1", - v -> v(1 + 1 + 2 + 1), - new Add(c(1), new Add(c(1), new Add(c(2), c(1)))) - ) - .advanced( - "($x - ((1 * 2) + $x))", - "$x - (1 * 2 + $x)", - v -> x(v).subtract(v(1 * 2).add(x(v))), - new Subtract(vx, new Add(new Multiply(c(1), c(2)), vx)) - ) - .advanced( - "($x * (2 / ($x - 1)))", - "$x * (2 / ($x - 1))", - v -> x(v).multiply(v(2).divide(x(v).subtract(v(1)))), - new Multiply(vx, new Divide(c(2), new Subtract(vx, c(1)))) - ) - .advanced( - "($x / (1 + (2 + 1)))", - "$x / (1 + 2 + 1)", - v -> x(v).divide(v(1 + 2 + 1)), - new Divide(vx, new Add(c(1), new Add(c(2), c(1)))) - ) - .advanced( - "((1 * 2) + (2 + 1))", - "1 * 2 + 2 + 1", - v -> v(1 * 2 + 2 + 1), - new Add(new Multiply(c(1), c(2)), new Add(c(2), c(1))) - ) - .advanced( - "((2 + 1) - (2 + 1))", - "2 + 1 - (2 + 1)", - v -> v(2 + 1 - (2 + 1)), - new Subtract(new Add(c(2), c(1)), new Add(c(2), c(1))) - ) - .advanced( - "(($x - 1) * ($x / 1))", - "($x - 1) * ($x / 1)", - v -> x(v).subtract(v(1)).multiply(x(v).divide(v(1))), - new Multiply(new Subtract(vx, c(1)), new Divide(vx, c(1))) - ) - .advanced( - "(($x - 1) / (1 * 2))", - "($x - 1) / (1 * 2)", - v -> x(v).subtract(v(1)).divide(v(2)), - new Divide(new Subtract(vx, c(1)), new Multiply(c(1), c(2))) - ) - .advanced( - "((($x - 1) - 2) + $x)", - "$x - 1 - 2 + $x", - v -> x(v).subtract(v(3)).add(x(v)), - new Add(new Subtract(new Subtract(vx, c(1)), c(2)), vx) - ) - .advanced( - "(((1 * 2) + $x) - 1)", - "1 * 2 + $x - 1", - v -> v(1).add(x(v)), - new Subtract(new Add(new Multiply(c(1), c(2)), vx), c(1)) - ) - .advanced( - "(((2 + 1) / 1) * $x)", - "(2 + 1) / 1 * $x", - v -> v(3).multiply(x(v)), - new Multiply(new Divide(new Add(c(2), c(1)), c(1)), vx) - ) - .advanced( - "((2 / ($x - 1)) / 2)", - "2 / ($x - 1) / 2", - v -> v(2).divide(x(v).subtract(v(1))).divide(v(2)), - new Divide(new Divide(c(2), new Subtract(vx, c(1))), c(2)) - ); - } - - private static BigDecimal x(final List vars) { - return vars.get(0); - } - - private static BigDecimal y(final List vars) { - return vars.get(1); - } - - private static Const c(final BigDecimal v) { - return TYPE.constant(v); - } - - private static Const c(final long v) { - return TYPE.constant(v(v)); - } - - private static BigDecimal v(final long v) { - return BigDecimal.valueOf(v); - } - - static void main(final String... args) { - TripleExpression.SELECTOR - .variant("BigDecimalList", ExpressionTest.v(BigDecimalListExpression::tester)) - .main(args); - } -} diff --git a/java/expression/BigIntegerListExpression.java b/java/expression/BigIntegerListExpression.java deleted file mode 100644 index 4f74521..0000000 --- a/java/expression/BigIntegerListExpression.java +++ /dev/null @@ -1,192 +0,0 @@ -package expression; - -import base.Asserts; -import base.Pair; -import base.TestCounter; -import expression.common.ExpressionKind; -import expression.common.Type; - -import java.math.BigInteger; -import java.util.List; -import java.util.stream.IntStream; - -/** - * @author Georgiy Korneev (kgeorgiy@kgeorgiy.info) - */ -@FunctionalInterface -@SuppressWarnings("ClassReferencesSubclass") -public interface BigIntegerListExpression extends ToMiniString { - BigInteger evaluateBi(List variables); - - // Tests follow. You may temporarily remove everything til the end. - - Add EXAMPLE = new Add( - new Subtract(new Variable(0), new Const(BigInteger.ONE)), - new Multiply(new Variable(1), new Const(BigInteger.TEN)) - ); - - Type TYPE = new Type<>(BigInteger::valueOf, random -> v(random.getRandom().nextLong()), BigInteger.class); - ExpressionKind KIND = new ExpressionKind<>( - TYPE, - BigIntegerListExpression.class, - (r, c) -> IntStream.range(0, c) - .mapToObj(name -> Pair.of("$" + name, new Variable(name))) - .toList(), - (expr, variables, values) -> expr.evaluateBi(values) - ); - - @SuppressWarnings("PointlessArithmeticExpression") - static ExpressionTester tester(final TestCounter counter) { - Asserts.assertEquals("Example toString()", "(($0 - 1) + ($1 * 10))", EXAMPLE.toString()); - Asserts.assertEquals( - EXAMPLE + " at (2, 3)", - BigInteger.valueOf(31), - EXAMPLE.evaluateBi(List.of(BigInteger.valueOf(2), BigInteger.valueOf(3))) - ); - - final Variable vx = new Variable(0); - final Variable vy = new Variable(1); - - return new ExpressionTester<>( - counter, KIND, c -> v -> c, - (op, a, b) -> v -> op.apply(a.evaluateBi(v), b.evaluateBi(v)), - BigInteger::add, BigInteger::subtract, BigInteger::multiply, BigInteger::divide - ) - .basic("10", "10", v -> v(10), c(10)) - .basic("$x", "$x", BigIntegerListExpression::x, vx) - .basic("$y", "$y", BigIntegerListExpression::y, vy) - .basic("($x + $y)", "$x + $y", v -> x(v).add(y(v)), new Add(vx, vy)) - .basic("($x + 2)", "$x + 2", v -> x(v).add(v(2)), new Add(vx, c(2))) - .basic("(2 - $x)", "2 - $x", v -> v(2).subtract(x(v)), new Subtract(c(2), vx)) - .basic("(3 * $x)", "3 * $x", v -> v(3).multiply(x(v)), new Multiply(c(3), vx)) - .basic("($x + $x)", "$x + $x", v -> x(v).add(x(v)), new Add(vx, vx)) - .basic("($x / -2)", "$x / -2", v -> x(v).divide(v(-2)), new Divide(vx, c(-2))) - .basic("(2 + $x)", "2 + $x", v -> v(2).add(x(v)), new Add(c(2), vx)) - .basic("((1 + 2) + 3)", "1 + 2 + 3", v -> v(6), new Add(new Add(c(1), c(2)), c(3))) - .basic("(1 + (2 * 3))", "1 + 2 * 3", v -> v(7), new Add(c(1), new Multiply(c(2), c(3)))) - .basic("(1 - (2 * 3))", "1 - 2 * 3", v -> v(-5), new Subtract(c(1), new Multiply(c(2), c(3)))) - .basic("(1 + (2 + 3))", "1 + 2 + 3", v -> v(6), new Add(c(1), new Add(c(2), c(3)))) - .basic("((1 - 2) - 3)", "1 - 2 - 3", v -> v(-4), new Subtract(new Subtract(c(1), c(2)), c(3))) - .basic("(1 - (2 - 3))", "1 - (2 - 3)", v -> v(2), new Subtract(c(1), new Subtract(c(2), c(3)))) - .basic("((1 * 2) * 3)", "1 * 2 * 3", v -> v(6), new Multiply(new Multiply(c(1), c(2)), c(3))) - .basic("(1 * (2 * 3))", "1 * 2 * 3", v -> v(6), new Multiply(c(1), new Multiply(c(2), c(3)))) - .basic("((10 / 2) / 3)", "10 / 2 / 3", v -> v(10 / 2 / 3), new Divide(new Divide(c(10), c(2)), c(3))) - .basic("(10 / (3 / 2))", "10 / (3 / 2)", v -> v(10 / (3 / 2)), new Divide(c(10), new Divide(c(3), c(2)))) - .basic("(($x * $x) + (($x - 1) / 10))", - "$x * $x + ($x - 1) / 10", - v -> x(v).multiply(x(v)).add(x(v).subtract(v(1)).divide(v(10))), - new Add(new Multiply(vx, vx), new Divide(new Subtract(vx, c(1)), c(10))) - ) - .basic("($x * -1000000000)", "$x * -1000000000", v -> x(v).multiply(v(-1_000_000_000)), new Multiply(vx, c(-1_000_000_000))) - .basic("($x * -1000000000000000)", "$x * -1000000000000000", v -> x(v).multiply(v(-1_000_000_000_000_000L)), new Multiply(vx, c(-1_000_000_000_000_000L))) - .basic("(10 / $x)", "10 / $x", v -> v(10).divide(x(v)), new Divide(c(10), vx)) - .basic("($x / $x)", "$x / $x", v -> x(v).divide(x(v)), new Divide(vx, vx)) - - .advanced("(2 + 1)", "2 + 1", v -> v(2 + 1), new Add(c(2), c(1))) - .advanced("($x - 1)", "$x - 1", v -> x(v).subtract(v(1)), new Subtract(vx, c(1))) - .advanced("(1 * 2)", "1 * 2", v -> v(1 * 2), new Multiply(c(1), c(2))) - .advanced("($x / 1)", "$x / 1", v -> x(v).divide(v(1)), new Divide(vx, c(1))) - .advanced("(1 + (2 + 1))", "1 + 2 + 1", v -> v(1 + 2 + 1), new Add(c(1), new Add(c(2), c(1)))) - .advanced("($x - ($x - 1))", "$x - ($x - 1)", v -> x(v).subtract(x(v).subtract(v(1))), new Subtract(vx, new Subtract(vx, c(1)))) - .advanced("(2 * ($x / 1))", "2 * ($x / 1)", v -> v(2).multiply(x(v).divide(v(1))), new Multiply(c(2), new Divide(vx, c(1)))) - .advanced("(2 / ($x - 1))", "2 / ($x - 1)", v -> v(2).divide(x(v).subtract(v(1))), new Divide(c(2), new Subtract(vx, c(1)))) - .advanced("((1 * 2) + $x)", "1 * 2 + $x", v -> v(1 * 2).add(x(v)), new Add(new Multiply(c(1), c(2)), vx)) - .advanced("(($x - 1) - 2)", "$x - 1 - 2", v -> x(v).subtract(v(3)), new Subtract(new Subtract(vx, c(1)), c(2))) - .advanced("(($x / 1) * 2)", "$x / 1 * 2", v -> x(v).multiply(v(2)), new Multiply(new Divide(vx, c(1)), c(2))) - .advanced("((2 + 1) / 1)", "(2 + 1) / 1", v -> v(3), new Divide(new Add(c(2), c(1)), c(1))) - .advanced( - "(1 + (1 + (2 + 1)))", - "1 + 1 + 2 + 1", - v -> v(1 + 1 + 2 + 1), - new Add(c(1), new Add(c(1), new Add(c(2), c(1)))) - ) - .advanced( - "($x - ((1 * 2) + $x))", - "$x - (1 * 2 + $x)", - v -> x(v).subtract(v(1 * 2).add(x(v))), - new Subtract(vx, new Add(new Multiply(c(1), c(2)), vx)) - ) - .advanced( - "($x * (2 / ($x - 1)))", - "$x * (2 / ($x - 1))", - v -> x(v).multiply(v(2).divide(x(v).subtract(v(1)))), - new Multiply(vx, new Divide(c(2), new Subtract(vx, c(1)))) - ) - .advanced( - "($x / (1 + (2 + 1)))", - "$x / (1 + 2 + 1)", - v -> x(v).divide(v(1 + 2 + 1)), - new Divide(vx, new Add(c(1), new Add(c(2), c(1)))) - ) - .advanced( - "((1 * 2) + (2 + 1))", - "1 * 2 + 2 + 1", - v -> v(1 * 2 + 2 + 1), - new Add(new Multiply(c(1), c(2)), new Add(c(2), c(1))) - ) - .advanced( - "((2 + 1) - (2 + 1))", - "2 + 1 - (2 + 1)", - v -> v(2 + 1 - (2 + 1)), - new Subtract(new Add(c(2), c(1)), new Add(c(2), c(1))) - ) - .advanced( - "(($x - 1) * ($x / 1))", - "($x - 1) * ($x / 1)", - v -> x(v).subtract(v(1)).multiply(x(v).divide(v(1))), - new Multiply(new Subtract(vx, c(1)), new Divide(vx, c(1))) - ) - .advanced( - "(($x - 1) / (1 * 2))", - "($x - 1) / (1 * 2)", - v -> x(v).subtract(v(1)).divide(v(2)), - new Divide(new Subtract(vx, c(1)), new Multiply(c(1), c(2))) - ) - .advanced( - "((($x - 1) - 2) + $x)", - "$x - 1 - 2 + $x", - v -> x(v).subtract(v(3)).add(x(v)), - new Add(new Subtract(new Subtract(vx, c(1)), c(2)), vx) - ) - .advanced( - "(((1 * 2) + $x) - 1)", - "1 * 2 + $x - 1", - v -> v(1).add(x(v)), - new Subtract(new Add(new Multiply(c(1), c(2)), vx), c(1)) - ) - .advanced( - "(((2 + 1) / 1) * $x)", - "(2 + 1) / 1 * $x", - v -> v(3).multiply(x(v)), - new Multiply(new Divide(new Add(c(2), c(1)), c(1)), vx) - ) - .advanced( - "((2 / ($x - 1)) / 2)", - "2 / ($x - 1) / 2", - v -> v(2).divide(x(v).subtract(v(1))).divide(v(2)), - new Divide(new Divide(c(2), new Subtract(vx, c(1))), c(2)) - ); - } - - private static BigInteger x(final List vars) { - return vars.get(0); - } - - private static BigInteger y(final List vars) { - return vars.get(1); - } - - private static Const c(final long v) { - return TYPE.constant(v(v)); - } - - private static BigInteger v(final long v) { - return BigInteger.valueOf(v); - } - - static void main(final String... args) { - TripleExpression.SELECTOR - .variant("BigIntegerList", ExpressionTest.v(BigIntegerListExpression::tester)) - .main(args); - } -} diff --git a/java/expression/Expression.java b/java/expression/Expression.java deleted file mode 100644 index d52c16b..0000000 --- a/java/expression/Expression.java +++ /dev/null @@ -1,112 +0,0 @@ -package expression; - -import base.Asserts; -import base.ExtendedRandom; -import base.Pair; -import base.TestCounter; -import expression.common.ExpressionKind; -import expression.common.Type; - -import java.util.List; - -/** - * One-argument arithmetic expression over integers. - * - * @author Georgiy Korneev (kgeorgiy@kgeorgiy.info) - */ -@FunctionalInterface -@SuppressWarnings("ClassReferencesSubclass") -public interface Expression extends ToMiniString { - int evaluate(int x); - - // Tests follow. You may temporarily remove everything til the end. - - Subtract EXAMPLE = new Subtract( - new Multiply(new Const(2), new Variable("x")), - new Const(3) - ); - - Type TYPE = new Type<>(a -> a, ExtendedRandom::nextInt, int.class); - ExpressionKind KIND = new ExpressionKind<>( - TYPE, - Expression.class, - List.of(Pair.of("x", new Variable("x"))), - (expr, variables, values) -> expr.evaluate(values.get(0)) - ); - - private static Const c(final int c) { - return new Const(c); - } - - @SuppressWarnings({"PointlessArithmeticExpression", "Convert2MethodRef"}) - static ExpressionTester tester(final TestCounter counter) { - Asserts.assertEquals("Example toString()", "((2 * x) - 3)", EXAMPLE.toString()); - Asserts.assertEquals("Example at 5", 7, EXAMPLE.evaluate(5)); - Asserts.assertTrue("Example equals 1", - new Multiply(new Const(2), new Variable("x")) - .equals(new Multiply(new Const(2), new Variable("x")))); - Asserts.assertTrue("Example equals 2", - !new Multiply(new Const(2), new Variable("x")) - .equals(new Multiply(new Variable("x"), new Const(2)))); - - final Variable vx = new Variable("x"); - final Const c1 = c(1); - final Const c2 = c(2); - - return new ExpressionTester<>( - counter, KIND, c -> x -> c, - (op, a, b) -> x -> op.apply(a.evaluate(x), b.evaluate(x)), - (a, b) -> a + b, (a, b) -> a - b, (a, b) -> a * b, (a, b) -> a / b - ) - .basic("10", "10", x -> 10, c(10)) - .basic("x", "x", x -> x, vx) - .basic("(x + 2)", "x + 2", x -> x + 2, new Add(vx, c(2))) - .basic("(2 - x)", "2 - x", x -> 2 - x, new Subtract(c(2), vx)) - .basic("(3 * x)", "3 * x", x -> 3*x, new Multiply(c(3), vx)) - .basic("(x + x)", "x + x", x -> x + x, new Add(vx, vx)) - .basic("(x / -2)", "x / -2", x -> -x / 2, new Divide(vx, c(-2))) - .basic("(2 + x)", "2 + x", x -> 2 + x, new Add(c(2), vx)) - .basic("((1 + 2) + 3)", "1 + 2 + 3", x -> 6, new Add(new Add(c(1), c(2)), c(3))) - .basic("(1 + (2 + 3))", "1 + 2 + 3", x -> 6, new Add(c(1), new Add(c(2), c(3)))) - .basic("((1 - 2) - 3)", "1 - 2 - 3", x -> -4, new Subtract(new Subtract(c(1), c(2)), c(3))) - .basic("(1 - (2 - 3))", "1 - (2 - 3)", x -> 2, new Subtract(c(1), new Subtract(c(2), c(3)))) - .basic("((1 * 2) * 3)", "1 * 2 * 3", x -> 6, new Multiply(new Multiply(c(1), c(2)), c(3))) - .basic("(1 * (2 * 3))", "1 * 2 * 3", x -> 6, new Multiply(c(1), new Multiply(c(2), c(3)))) - .basic("((10 / 2) / 3)", "10 / 2 / 3", x -> 10 / 2 / 3, new Divide(new Divide(c(10), c(2)), c(3))) - .basic("(10 / (3 / 2))", "10 / (3 / 2)", x -> 10 / (3 / 2), new Divide(c(10), new Divide(c(3), c(2)))) - .basic("(10 * (3 / 2))", "10 * (3 / 2)", x -> 10 * (3 / 2), new Multiply(c(10), new Divide(c(3), c(2)))) - .basic("(10 + (3 - 2))", "10 + 3 - 2", x -> 10 + (3 - 2), new Add(c(10), new Subtract(c(3), c(2)))) - .basic("((x * x) + ((x - 1) / 10))", "x * x + (x - 1) / 10", x -> x * x + (x - 1) / 10, new Add( - new Multiply(vx, vx), - new Divide(new Subtract(vx, c(1)), c(10)) - )) - .basic("(x * -1000000000)", "x * -1000000000", x -> x * -1_000_000_000, new Multiply(vx, c(-1_000_000_000))) - .basic("(10 / x)", "10 / x", x -> 10 / x, new Divide(c(10), vx)) - .basic("(x / x)", "x / x", x -> x / x, new Divide(vx, vx)) - - .advanced("(2 + 1)", "2 + 1", x -> 2 + 1, new Add(c2, c1)) - .advanced("(x - 1)", "x - 1", x -> x - 1, new Subtract(vx, c1)) - .advanced("(1 * 2)", "1 * 2", x -> 1 * 2, new Multiply(c1, c2)) - .advanced("(x / 1)", "x / 1", x -> x / 1, new Divide(vx, c1)) - .advanced("(1 + (2 + 1))", "1 + 2 + 1", x -> 1 + 2 + 1, new Add(c1, new Add(c2, c1))) - .advanced("(x - (x - 1))", "x - (x - 1)", x -> x - (x - 1), new Subtract(vx, new Subtract(vx, c1))) - .advanced("(2 * (x / 1))", "2 * (x / 1)", x -> 2 * (x / 1), new Multiply(c2, new Divide(vx, c1))) - .advanced("(2 / (x - 1))", "2 / (x - 1)", x -> 2 / (x - 1), new Divide(c2, new Subtract(vx, c1))) - .advanced("((1 * 2) + x)", "1 * 2 + x", x -> 1 * 2 + x, new Add(new Multiply(c1, c2), vx)) - .advanced("((x - 1) - 2)", "x - 1 - 2", x -> x - 1 - 2, new Subtract(new Subtract(vx, c1), c2)) - .advanced("((x / 1) * 2)", "x / 1 * 2", x -> x / 1 * 2, new Multiply(new Divide(vx, c1), c2)) - .advanced("((2 + 1) / 1)", "(2 + 1) / 1", x -> (2 + 1) / 1, new Divide(new Add(c2, c1), c1)) - .advanced("(1 + (1 + (2 + 1)))", "1 + 1 + 2 + 1", x -> 1 + 1 + 2 + 1, new Add(c1, new Add(c1, new Add(c2, c1)))) - .advanced("(x - ((1 * 2) + x))", "x - (1 * 2 + x)", x -> x - (1 * 2 + x), new Subtract(vx, new Add(new Multiply(c1, c2), vx))) - .advanced("(x * (2 / (x - 1)))", "x * (2 / (x - 1))", x -> x * (2 / (x - 1)), new Multiply(vx, new Divide(c2, new Subtract(vx, c1)))) - .advanced("(x / (1 + (2 + 1)))", "x / (1 + 2 + 1)", x -> x / (1 + 2 + 1), new Divide(vx, new Add(c1, new Add(c2, c1)))) - .advanced("((1 * 2) + (2 + 1))", "1 * 2 + 2 + 1", x -> 1 * 2 + 2 + 1, new Add(new Multiply(c1, c2), new Add(c2, c1))) - .advanced("((2 + 1) - (2 + 1))", "2 + 1 - (2 + 1)", x -> 2 + 1 - (2 + 1), new Subtract(new Add(c2, c1), new Add(c2, c1))) - .advanced("((x - 1) * (x / 1))", "(x - 1) * (x / 1)", x -> (x - 1) * (x / 1), new Multiply(new Subtract(vx, c1), new Divide(vx, c1))) - .advanced("((x - 1) / (1 * 2))", "(x - 1) / (1 * 2)", x -> (x - 1) / (1 * 2), new Divide(new Subtract(vx, c1), new Multiply(c1, c2))) - .advanced("(((x - 1) - 2) + x)", "x - 1 - 2 + x", x -> x - 1 - 2 + x, new Add(new Subtract(new Subtract(vx, c1), c2), vx)) - .advanced("(((1 * 2) + x) - 1)", "1 * 2 + x - 1", x -> 1 * 2 + x - 1, new Subtract(new Add(new Multiply(c1, c2), vx), c1)) - .advanced("(((2 + 1) / 1) * x)", "(2 + 1) / 1 * x", x -> (2 + 1) / 1 * x, new Multiply(new Divide(new Add(c2, c1), c1), vx)) - .advanced("((2 / (x - 1)) / 2)", "2 / (x - 1) / 2", x -> 2 / (x - 1) / 2, new Divide(new Divide(c2, new Subtract(vx, c1)), c2)); - } -} diff --git a/java/expression/ExpressionTest.java b/java/expression/ExpressionTest.java deleted file mode 100644 index ce24173..0000000 --- a/java/expression/ExpressionTest.java +++ /dev/null @@ -1,26 +0,0 @@ -package expression; - -import base.Selector; -import base.TestCounter; - -import java.util.function.Consumer; -import java.util.function.Function; - -/** - * @author Georgiy Korneev (kgeorgiy@kgeorgiy.info) - */ -public final class ExpressionTest { - public static final Selector SELECTOR = new Selector(ExpressionTest.class, "easy", "hard") - .variant("Base", v(Expression::tester)); - - private ExpressionTest() { - } - - public static Consumer v(final Function> tester) { - return t -> tester.apply(t).test(); - } - - public static void main(final String... args) { - SELECTOR.main(args); - } -} diff --git a/java/expression/ExpressionTester.java b/java/expression/ExpressionTester.java deleted file mode 100644 index 28e789f..0000000 --- a/java/expression/ExpressionTester.java +++ /dev/null @@ -1,288 +0,0 @@ -package expression; - -import base.*; -import expression.common.*; - -import java.lang.reflect.Constructor; -import java.lang.reflect.Modifier; -import java.util.*; -import java.util.function.BinaryOperator; -import java.util.function.Function; -import java.util.stream.Collectors; -import java.util.stream.IntStream; -import java.util.stream.Stream; - -import static base.Asserts.assertTrue; - -/** - * @author Georgiy Korneev (kgeorgiy@kgeorgiy.info) - */ -public class ExpressionTester extends Tester { - private final List VALUES = IntStream.rangeClosed(-10, 10).boxed().toList(); - private final ExpressionKind kind; - - private final List basic = new ArrayList<>(); - private final List advanced = new ArrayList<>(); - private final Set used = new HashSet<>(); - private final GeneratorBuilder generator; - - private final List> prev = new ArrayList<>(); - private final Map mappings; - - protected ExpressionTester( - final TestCounter counter, - final ExpressionKind kind, - final Function expectedConstant, - final Binary binary, - final BinaryOperator add, - final BinaryOperator sub, - final BinaryOperator mul, - final BinaryOperator div, - final Map mappings - ) { - super(counter); - this.kind = kind; - this.mappings = mappings; - - generator = new GeneratorBuilder(expectedConstant, kind::constant, binary, kind::randomValue); - generator.binary("+", 1600, add, Add.class); - generator.binary("-", 1602, sub, Subtract.class); - generator.binary("*", 2001, mul, Multiply.class); - generator.binary("/", 2002, div, Divide.class); - } - - protected ExpressionTester( - final TestCounter counter, - final ExpressionKind kind, - final Function expectedConstant, - final Binary binary, - final BinaryOperator add, - final BinaryOperator sub, - final BinaryOperator mul, - final BinaryOperator div - ) { - this(counter, kind, expectedConstant, binary, add, sub, mul, div, Map.of()); - } - - @Override - public String toString() { - return kind.getName(); - } - - @Override - public void test() { - counter.scope("Basic tests", () -> basic.forEach(Test::test)); - counter.scope("Advanced tests", () -> advanced.forEach(Test::test)); - counter.scope("Random tests", generator::testRandom); - } - - @SuppressWarnings({"ConstantValue", "EqualsWithItself"}) - private void checkEqualsAndToString(final String full, final String mini, final ToMiniString expression, final ToMiniString copy) { - checkToString("toString", full, expression.toString()); - if (mode() > 0) { - checkToString("toMiniString", mini, expression.toMiniString()); - } - - counter.test(() -> { - assertTrue("Equals to this", expression.equals(expression)); - assertTrue("Equals to copy", expression.equals(copy)); - assertTrue("Equals to null", !expression.equals(null)); - assertTrue("Copy equals to null", !copy.equals(null)); - }); - - final String expressionToString = Objects.requireNonNull(expression.toString()); - for (final Pair pair : prev) { - counter.test(() -> { - final ToMiniString prev = pair.first(); - final String prevToString = pair.second(); - final boolean equals = prevToString.equals(expressionToString); - assertTrue("Equals to " + prevToString, prev.equals(expression) == equals); - assertTrue("Equals to " + prevToString, expression.equals(prev) == equals); - assertTrue("Inconsistent hashCode for " + prev + " and " + expression, (prev.hashCode() == expression.hashCode()) == equals); - }); - } - } - - private void checkToString(final String method, final String expected, final String actual) { - counter.test(() -> assertTrue(String.format("Invalid %s\n expected: %s\n actual: %s", method, expected, actual), expected.equals(actual))); - } - - private void check( - final String full, - final E expected, - final E actual, - final List variables, - final List values - ) { - final String vars = IntStream.range(0, variables.size()) - .mapToObj(i -> variables.get(i) + "=" + values.get(i)) - .collect(Collectors.joining(",")); - counter.test(() -> { - final Object expectedResult = evaluate(expected, variables, values); - final Object actualResult = evaluate(actual, variables, values); - final String reason = String.format( - "%s:%n expected `%s`,%n actual `%s`", - String.format("f(%s)\nwhere f is %s", vars, full), - Asserts.toString(expectedResult), - Asserts.toString(actualResult) - ); - if ( - expectedResult != null && actualResult != null && - expectedResult.getClass() == actualResult.getClass() - && (expectedResult.getClass() == Double.class || expectedResult.getClass() == Float.class) - ) { - final double expectedValue = ((Number) expectedResult).doubleValue(); - final double actualValue = ((Number) actualResult).doubleValue(); - Asserts.assertEquals(reason, expectedValue, actualValue, 1e-6); - } else { - assertTrue(reason, Objects.deepEquals(expectedResult, actualResult)); - } - }); - } - - private Object evaluate(final E expression, final List variables, final List values) { - try { - return kind.evaluate(expression, variables, values); - } catch (final Exception e) { - return e.getClass().getName(); - } - } - - protected ExpressionTester basic(final String full, final String mini, final E expected, final E actual) { - return basicF(full, mini, expected, vars -> actual); - } - - protected ExpressionTester basicF(final String full, final String mini, final E expected, final Function, E> actual) { - return basic(new Test(full, mini, expected, actual)); - } - - private ExpressionTester basic(final Test test) { - Asserts.assertTrue(test.full, used.add(test.full)); - basic.add(test); - return this; - } - - protected ExpressionTester advanced(final String full, final String mini, final E expected, final E actual) { - return advancedF(full, mini, expected, vars -> actual); - } - - protected ExpressionTester advancedF(final String full, final String mini, final E expected, final Function, E> actual) { - Asserts.assertTrue(full, used.add(full)); - advanced.add(new Test(full, mini, expected, actual)); - return this; - } - - protected static Named variable(final String name, final E expected) { - return Named.of(name, expected); - } - - @FunctionalInterface - public interface Binary { - E apply(BinaryOperator op, E a, E b); - } - - private final class Test { - private final String full; - private final String mini; - private final E expected; - private final Function, E> actual; - - private Test(final String full, final String mini, final E expected, final Function, E> actual) { - this.full = full; - this.mini = mini; - this.expected = expected; - this.actual = actual; - } - - private void test() { - final List> variables = kind.variables().generate(random(), 3); - final List names = Functional.map(variables, Pair::first); - final E actual = kind.cast(this.actual.apply(names)); - final String full = mangle(this.full, names); - final String mini = mangle(this.mini, names); - - counter.test(() -> { - kind.allValues(variables.size(), VALUES).forEach(values -> check(mini, expected, actual, names, values)); - checkEqualsAndToString(full, mini, actual, actual); - prev.add(Pair.of(actual, full)); - }); - } - - private String mangle(String string, final List names) { - for (int i = 0; i < names.size(); i++) { - string = string.replace("$" + (char) ('x' + i), names.get(i)); - } - for (final Map.Entry mapping : mappings.entrySet()) { - string = string.replace(mapping.getKey(), mapping.getValue().toString()); - } - return string; - } - } - - private final class GeneratorBuilder { - private final Generator.Builder generator; - private final NodeRendererBuilder renderer = new NodeRendererBuilder<>(random()); - private final Renderer.Builder expected; - private final Renderer.Builder actual; - private final Renderer.Builder copy; - private final Binary binary; - - private GeneratorBuilder( - final Function expectedConstant, - final Function actualConstant, - final Binary binary, - final Function randomValue - ) { - generator = Generator.builder(() -> randomValue.apply(random()), random()); - expected = Renderer.builder(expectedConstant::apply); - actual = Renderer.builder(actualConstant::apply); - copy = Renderer.builder(actualConstant::apply); - - this.binary = binary; - } - - private void binary(final String name, final int priority, final BinaryOperator op, final Class type) { - generator.add(name, 2); - renderer.binary(name, priority); - - expected.binary(name, (unit, a, b) -> binary.apply(op, a, b)); - - @SuppressWarnings("unchecked") final Constructor constructor = (Constructor) Arrays.stream(type.getConstructors()) - .filter(cons -> Modifier.isPublic(cons.getModifiers())) - .filter(cons -> cons.getParameterCount() == 2) - .findFirst() - .orElseGet(() -> counter.fail("%s(..., ...) constructor not found", type.getSimpleName())); - final Renderer.BinaryOperator actual = (unit, a, b) -> { - try { - return constructor.newInstance(a, b); - } catch (final Exception e) { - return counter.fail(e); - } - }; - this.actual.binary(name, actual); - copy.binary(name, actual); - } - - private void testRandom() { - final NodeRenderer renderer = this.renderer.build(); - final Renderer expectedRenderer = this.expected.build(); - final Renderer actualRenderer = this.actual.build(); - final expression.common.Generator generator = this.generator.build(kind.variables(), List.of()); - generator.testRandom(counter, 1, expr -> { - final String full = renderer.render(expr, NodeRenderer.FULL); - final String mini = renderer.render(expr, NodeRenderer.MINI); - final E expected = expectedRenderer.render(expr, Unit.INSTANCE); - final E actual = actualRenderer.render(expr, Unit.INSTANCE); - - final List> variables = expr.variables(); - final List names = Functional.map(variables, Pair::first); - final List values = Stream.generate(() -> kind.randomValue(random())) - .limit(variables.size()) - .toList(); - - checkEqualsAndToString(full, mini, actual, copy.build().render(expr, Unit.INSTANCE)); - check(full, expected, actual, names, values); - }); - } - } -} diff --git a/java/expression/ListExpression.java b/java/expression/ListExpression.java deleted file mode 100644 index 7f5ff95..0000000 --- a/java/expression/ListExpression.java +++ /dev/null @@ -1,211 +0,0 @@ -package expression; - -import base.Asserts; -import base.ExtendedRandom; -import base.Pair; -import base.TestCounter; -import expression.common.ExpressionKind; -import expression.common.Type; - -import java.util.List; -import java.util.stream.IntStream; - -/** - * @author Georgiy Korneev (kgeorgiy@kgeorgiy.info) - */ -@SuppressWarnings("ClassReferencesSubclass") -@FunctionalInterface -public interface ListExpression extends ToMiniString { - int evaluate(List variables); - - // Tests follow. You may temporarily remove everything til the end. - - Add EXAMPLE = new Add( - new Subtract(new Variable(0), new Const(1)), - new Multiply(new Variable(1), new Const(10)) - ); - - Type TYPE = new Type<>(a -> a, ExtendedRandom::nextInt, int.class); - ExpressionKind KIND = new ExpressionKind<>( - TYPE, - ListExpression.class, - (r, c) -> IntStream.range(0, c) - .mapToObj(name -> Pair.of("$" + name, new Variable(name))) - .toList(), - (expr, variables, values) -> expr.evaluate(values) - ); - - private static Const c(final Integer c) { - return TYPE.constant(c); - } - - @SuppressWarnings({"PointlessArithmeticExpression", "Convert2MethodRef"}) - static ExpressionTester tester(final TestCounter counter) { - Asserts.assertEquals("Example toString()", "(($0 - 1) + ($1 * 10))", EXAMPLE.toString()); - Asserts.assertEquals(EXAMPLE + " at (2, 3)", 31, EXAMPLE.evaluate(List.of(2, 3))); - - final Variable vx = new Variable(0); - return new ExpressionTester<>( - counter, KIND, c -> vars -> c, - (op, a, b) -> vars -> op.apply(a.evaluate(vars), b.evaluate(vars)), - (a, b) -> a + b, (a, b) -> a - b, (a, b) -> a * b, (a, b) -> a / b - ) - .basic("10", "10", vars -> 10, c(10)) - .basic("$x", "$x", ListExpression::x, vx) - .basic("($x + 2)", "$x + 2", vars -> x(vars) + 2, new Add(vx, c(2))) - .basic("(2 - $x)", "2 - $x", vars -> 2 - x(vars), new Subtract(c(2), vx)) - .basic("(3 * $x)", "3 * $x", vars -> 3 * x(vars), new Multiply(c(3), vx)) - .basic("($x + $x)", "$x + $x", vars -> x(vars) + x(vars), new Add(vx, vx)) - .basic("($x / -2)", "$x / -2", vars -> -x(vars) / 2, new Divide(vx, c(-2))) - .basic("(2 + $x)", "2 + $x", vars -> 2 + x(vars), new Add(c(2), vx)) - .basic("((1 + 2) + 3)", "1 + 2 + 3", vars -> 6, new Add(new Add(c(1), c(2)), c(3))) - .basic("(1 + (2 + 3))", "1 + 2 + 3", vars -> 6, new Add(c(1), new Add(c(2), c(3)))) - .basic("((1 - 2) - 3)", "1 - 2 - 3", vars -> -4, new Subtract(new Subtract(c(1), c(2)), c(3))) - .basic("(1 - (2 - 3))", "1 - (2 - 3)", vars -> 2, new Subtract(c(1), new Subtract(c(2), c(3)))) - .basic("((1 * 2) * 3)", "1 * 2 * 3", vars -> 6, new Multiply(new Multiply(c(1), c(2)), c(3))) - .basic("(1 * (2 * 3))", "1 * 2 * 3", vars -> 6, new Multiply(c(1), new Multiply(c(2), c(3)))) - .basic("((10 / 2) / 3)", "10 / 2 / 3", vars -> 10 / 2 / 3, new Divide(new Divide(c(10), c(2)), c(3))) - .basic("(10 / (3 / 2))", "10 / (3 / 2)", vars -> 10 / (3 / 2), new Divide(c(10), new Divide(c(3), c(2)))) - .basic("(10 * (3 / 2))", "10 * (3 / 2)", vars -> 10 * (3 / 2), new Multiply(c(10), new Divide(c(3), c(2)))) - .basic("(10 + (3 - 2))", "10 + 3 - 2", vars -> 10 + (3 - 2), new Add(c(10), new Subtract(c(3), c(2)))) - .basic( - "(($x * $x) + (($x - 1) / 10))", - "$x * $x + ($x - 1) / 10", - vars -> x(vars) * x(vars) + (x(vars) - 1) / 10, - new Add(new Multiply(vx, vx), new Divide(new Subtract(vx, c(1)), c(10))) - ) - .basic( - "($x * -1000000000)", - "$x * -1000000000", - vars -> x(vars) * -1_000_000_000, - new Multiply(vx, c(-1_000_000_000)) - ) - .basic("(10 / $x)", "10 / $x", vars -> 10 / x(vars), new Divide(c(10), vx)) - .basic("($x / $x)", "$x / $x", vars -> x(vars) / x(vars), new Divide(vx, vx)) - - .advanced("(2 + 1)", "2 + 1", vars -> 2 + 1, new Add(c(2), c(1))) - .advanced("($x - 1)", "$x - 1", vars -> x(vars) - 1, new Subtract(vx, c(1))) - .advanced("(1 * 2)", "1 * 2", vars -> 1 * 2, new Multiply(c(1), c(2))) - .advanced("($x / 1)", "$x / 1", vars -> x(vars) / 1, new Divide(vx, c(1))) - .advanced("(1 + (2 + 1))", "1 + 2 + 1", vars -> 1 + 2 + 1, new Add(c(1), new Add(c(2), c(1)))) - .advanced( - "($x - ($x - 1))", - "$x - ($x - 1)", - vars -> x(vars) - (x(vars) - 1), - new Subtract(vx, new Subtract(vx, c(1))) - ) - .advanced( - "(2 * ($x / 1))", - "2 * ($x / 1)", - vars -> 2 * (x(vars) / 1), - new Multiply(c(2), new Divide(vx, c(1))) - ) - .advanced( - "(2 / ($x - 1))", - "2 / ($x - 1)", - vars -> 2 / (x(vars) - 1), - new Divide(c(2), new Subtract(vx, c(1))) - ) - .advanced( - "((1 * 2) + $x)", - "1 * 2 + $x", - vars -> 1 * 2 + x(vars), - new Add(new Multiply(c(1), c(2)), vx) - ) - .advanced( - "(($x - 1) - 2)", - "$x - 1 - 2", - vars -> x(vars) - 1 - 2, - new Subtract(new Subtract(vx, c(1)), c(2)) - ) - .advanced( - "(($x / 1) * 2)", - "$x / 1 * 2", - vars -> x(vars) / 1 * 2, - new Multiply(new Divide(vx, c(1)), c(2)) - ) - .advanced("((2 + 1) / 1)", "(2 + 1) / 1", vars -> (2 + 1) / 1, new Divide(new Add(c(2), c(1)), c(1))) - .advanced( - "(1 + (1 + (2 + 1)))", - "1 + 1 + 2 + 1", - vars -> 1 + 1 + 2 + 1, - new Add(c(1), new Add(c(1), new Add(c(2), c(1)))) - ) - .advanced( - "($x - ((1 * 2) + $x))", - "$x - (1 * 2 + $x)", - vars -> x(vars) - (1 * 2 + x(vars)), - new Subtract(vx, new Add(new Multiply(c(1), c(2)), vx)) - ) - .advanced( - "($x * (2 / ($x - 1)))", - "$x * (2 / ($x - 1))", - vars -> x(vars) * (2 / (x(vars) - 1)), - new Multiply(vx, new Divide(c(2), new Subtract(vx, c(1)))) - ) - .advanced( - "($x / (1 + (2 + 1)))", - "$x / (1 + 2 + 1)", - vars -> x(vars) / (1 + 2 + 1), - new Divide(vx, new Add(c(1), new Add(c(2), c(1)))) - ) - .advanced( - "((1 * 2) + (2 + 1))", - "1 * 2 + 2 + 1", - vars -> 1 * 2 + 2 + 1, - new Add(new Multiply(c(1), c(2)), new Add(c(2), c(1))) - ) - .advanced( - "((2 + 1) - (2 + 1))", - "2 + 1 - (2 + 1)", - vars -> 2 + 1 - (2 + 1), - new Subtract(new Add(c(2), c(1)), new Add(c(2), c(1))) - ) - .advanced( - "(($x - 1) * ($x / 1))", - "($x - 1) * ($x / 1)", - vars -> (x(vars) - 1) * (x(vars) / 1), - new Multiply(new Subtract(vx, c(1)), new Divide(vx, c(1))) - ) - .advanced( - "(($x - 1) / (1 * 2))", - "($x - 1) / (1 * 2)", - vars -> (x(vars) - 1) / (1 * 2), - new Divide(new Subtract(vx, c(1)), new Multiply(c(1), c(2))) - ) - .advanced( - "((($x - 1) - 2) + $x)", - "$x - 1 - 2 + $x", - vars -> x(vars) - 1 - 2 + x(vars), - new Add(new Subtract(new Subtract(vx, c(1)), c(2)), vx) - ) - .advanced( - "(((1 * 2) + $x) - 1)", - "1 * 2 + $x - 1", - vars -> 1 * 2 + x(vars) - 1, - new Subtract(new Add(new Multiply(c(1), c(2)), vx), c(1)) - ) - .advanced( - "(((2 + 1) / 1) * $x)", - "(2 + 1) / 1 * $x", - vars -> (2 + 1) / 1 * x(vars), - new Multiply(new Divide(new Add(c(2), c(1)), c(1)), vx) - ) - .advanced( - "((2 / ($x - 1)) / 2)", - "2 / ($x - 1) / 2", - vars -> 2 / (x(vars) - 1) / 2, - new Divide(new Divide(c(2), new Subtract(vx, c(1))), c(2)) - ); - } - - private static Integer x(final List vars) { - return vars.get(0); - } - - static void main(final String... args) { - TripleExpression.SELECTOR - .variant("List", ExpressionTest.v(ListExpression::tester)) - .main(args); - } -} diff --git a/java/expression/ToMiniString.java b/java/expression/ToMiniString.java deleted file mode 100644 index 60a655c..0000000 --- a/java/expression/ToMiniString.java +++ /dev/null @@ -1,10 +0,0 @@ -package expression; - -/** - * @author Georgiy Korneev (kgeorgiy@kgeorgiy.info) - */ -public interface ToMiniString { - default String toMiniString() { - return toString(); - } -} diff --git a/java/expression/TripleExpression.java b/java/expression/TripleExpression.java deleted file mode 100644 index efc6705..0000000 --- a/java/expression/TripleExpression.java +++ /dev/null @@ -1,190 +0,0 @@ -package expression; - -import base.ExtendedRandom; -import base.Pair; -import base.Selector; -import base.TestCounter; -import expression.common.ExpressionKind; -import expression.common.Type; - -import java.util.List; - -/** - * Three-argument arithmetic expression over integers. - * - * @author Georgiy Korneev (kgeorgiy@kgeorgiy.info) - */ -@FunctionalInterface -@SuppressWarnings("ClassReferencesSubclass") -public interface TripleExpression extends ToMiniString { - int evaluate(int x, int y, int z); - - // Tests follow. You may temporarily remove everything til the end. - - Type TYPE = new Type<>(a -> a, ExtendedRandom::nextInt, int.class); - ExpressionKind KIND = new ExpressionKind<>( - TYPE, - TripleExpression.class, - List.of( - Pair.of("x", new Variable("x")), - Pair.of("y", new Variable("y")), - Pair.of("z", new Variable("z")) - ), - (expr, variables, values) -> expr.evaluate(values.get(0), values.get(1), values.get(2)) - ); - - @SuppressWarnings("PointlessArithmeticExpression") - static ExpressionTester tester(final TestCounter counter) { - final Variable vx = new Variable("x"); - final Variable vy = new Variable("y"); - final Variable vz = new Variable("z"); - - return new ExpressionTester<>( - counter, KIND, c -> (x, y, z) -> c, - (op, a, b) -> (x, y, z) -> op.apply(a.evaluate(x, y, z), b.evaluate(x, y, z)), - Integer::sum, (a, b) -> a - b, (a, b) -> a * b, (a, b) -> a / b - ) - .basic("10", "10", (x, y, z) -> 10, c(10)) - .basic("x", "x", (x, y, z) -> x, vx) - .basic("y", "y", (x, y, z) -> y, vy) - .basic("z", "z", (x, y, z) -> z, vz) - .basic("(x + 2)", "x + 2", (x, y, z) -> x + 2, new Add(vx, c(2))) - .basic("(2 - y)", "2 - y", (x, y, z) -> 2 - y, new Subtract(c(2), vy)) - .basic("(3 * z)", "3 * z", (x, y, z) -> 3 * z, new Multiply(c(3), vz)) - .basic("(x / -2)", "x / -2", (x, y, z) -> -x / 2, new Divide(vx, c(-2))) - .basic("((1 + 2) + 3)", "1 + 2 + 3", (x, y, z) -> 6, new Add(new Add(c(1), c(2)), c(3))) - .basic("(1 + (2 + 3))", "1 + 2 + 3", (x, y, z) -> 6, new Add(c(1), new Add(c(2), c(3)))) - .basic("((1 - 2) - 3)", "1 - 2 - 3", (x, y, z) -> -4, new Subtract(new Subtract(c(1), c(2)), c(3))) - .basic("(1 - (2 - 3))", "1 - (2 - 3)", (x, y, z) -> 2, new Subtract(c(1), new Subtract(c(2), c(3)))) - .basic("((1 * 2) * 3)", "1 * 2 * 3", (x, y, z) -> 6, new Multiply(new Multiply(c(1), c(2)), c(3))) - .basic("(1 * (2 * 3))", "1 * 2 * 3", (x, y, z) -> 6, new Multiply(c(1), new Multiply(c(2), c(3)))) - .basic("((10 / 2) / 3)", "10 / 2 / 3", (x, y, z) -> 10 / 2 / 3, new Divide(new Divide(c(10), c(2)), c(3))) - .basic("(10 / (3 / 2))", "10 / (3 / 2)", (x, y, z) -> 10, new Divide(c(10), new Divide(c(3), c(2)))) - .basic("((x * y) + ((z - 1) / 10))", "x * y + (z - 1) / 10", (x, y, z) -> x * y + (z - 1) / 10, new Add( - new Multiply(vx, vy), - new Divide(new Subtract(vz, c(1)), c(10)) - )) - .basic("(x + y)", "x + y", (x, y, z) -> x + y, new Add(vx, vy)) - .basic("(y + x)", "y + x", (x, y, z) -> y + x, new Add(vy, vx)) - - .advanced("(1 + 1)", "1 + 1", (x, y, z) -> 1 + 1, new Add(c(1), c(1))) - .advanced("(y - x)", "y - x", (x, y, z) -> y - x, new Subtract(vy, vx)) - .advanced("(2 * x)", "2 * x", (x, y, z) -> 2 * x, new Multiply(c(2), vx)) - .advanced("(2 / x)", "2 / x", (x, y, z) -> 2 / x, new Divide(c(2), vx)) - .advanced("(z + (1 + 1))", "z + 1 + 1", (x, y, z) -> z + 1 + 1, new Add(vz, new Add(c(1), c(1)))) - .advanced( - "(2 - (y - x))", - "2 - (y - x)", - (x, y, z) -> 2 - (y - x), - new Subtract(c(2), new Subtract(vy, vx)) - ) - .advanced( - "(z * (2 / x))", - "z * (2 / x)", - (x, y, z) -> z * (2 / x), - new Multiply(vz, new Divide(c(2), vx)) - ) - .advanced( - "(z / (y - x))", - "z / (y - x)", - (x, y, z) -> z / (y - x), - new Divide(vz, new Subtract(vy, vx)) - ) - .advanced("((2 * x) + y)", "2 * x + y", (x, y, z) -> 2 * x + y, new Add(new Multiply(c(2), vx), vy)) - .advanced( - "((y - x) - 2)", - "y - x - 2", - (x, y, z) -> y - x - 2, - new Subtract(new Subtract(vy, vx), c(2)) - ) - .advanced("((2 / x) * y)", "2 / x * y", (x, y, z) -> 2 / x * y, new Multiply(new Divide(c(2), vx), vy)) - .advanced("((1 + 1) / x)", "(1 + 1) / x", (x, y, z) -> (1 + 1) / x, new Divide(new Add(c(1), c(1)), vx)) - .advanced("(1 + (2 * 3))", "1 + 2 * 3", (x, y, z) -> 7, new Add(c(1), new Multiply(c(2), c(3)))) - .advanced("(1 - (2 * 3))", "1 - 2 * 3", (x, y, z) -> -5, new Subtract(c(1), new Multiply(c(2), c(3)))) - .advanced("(1 + (2 / 3))", "1 + 2 / 3", (x, y, z) -> 1, new Add(c(1), new Divide(c(2), c(3)))) - .advanced("(1 - (2 / 3))", "1 - 2 / 3", (x, y, z) -> 1, new Subtract(c(1), new Divide(c(2), c(3)))) - .advanced( - "(2 + (z + (1 + 1)))", - "2 + z + 1 + 1", - (x, y, z) -> 2 + z + 1 + 1, - new Add(c(2), new Add(vz, new Add(c(1), c(1)))) - ) - .advanced( - "(1 - ((2 * x) + y))", - "1 - (2 * x + y)", - (x, y, z) -> 1 - (2 * x + y), - new Subtract(c(1), new Add(new Multiply(c(2), vx), vy)) - ) - .advanced( - "(1 * (z / (y - x)))", - "1 * (z / (y - x))", - (x, y, z) -> 1 * (z / (y - x)), - new Multiply(c(1), new Divide(vz, new Subtract(vy, vx))) - ) - .advanced( - "(z / (z + (1 + 1)))", - "z / (z + 1 + 1)", - (x, y, z) -> z / (z + 1 + 1), - new Divide(vz, new Add(vz, new Add(c(1), c(1)))) - ) - .advanced( - "((2 * x) + (1 + 1))", - "2 * x + 1 + 1", - (x, y, z) -> 2 * x + 1 + 1, - new Add(new Multiply(c(2), vx), new Add(c(1), c(1))) - ) - .advanced( - "((1 + 1) - (1 + 1))", - "1 + 1 - (1 + 1)", - (x, y, z) -> 1 + 1 - (1 + 1), - new Subtract(new Add(c(1), c(1)), new Add(c(1), c(1))) - ) - .advanced( - "((y - x) * (2 / x))", - "(y - x) * (2 / x)", - (x, y, z) -> (y - x) * (2 / x), - new Multiply(new Subtract(vy, vx), new Divide(c(2), vx)) - ) - .advanced( - "((y - x) / (2 * x))", - "(y - x) / (2 * x)", - (x, y, z) -> (y - x) / (2 * x), - new Divide(new Subtract(vy, vx), new Multiply(c(2), vx)) - ) - .advanced( - "(((y - x) - 2) + 1)", - "y - x - 2 + 1", - (x, y, z) -> y - x - 2 + 1, - new Add(new Subtract(new Subtract(vy, vx), c(2)), c(1)) - ) - .advanced( - "(((2 * x) + y) - z)", - "2 * x + y - z", - (x, y, z) -> 2 * x + y - z, - new Subtract(new Add(new Multiply(c(2), vx), vy), vz) - ) - .advanced( - "(((1 + 1) / x) * 2)", - "(1 + 1) / x * 2", - (x, y, z) -> (1 + 1) / x * 2, - new Multiply(new Divide(new Add(c(1), c(1)), vx), c(2)) - ) - .advanced( - "((z / (y - x)) / x)", - "z / (y - x) / x", - (x, y, z) -> z / (y - x) / x, - new Divide(new Divide(vz, new Subtract(vy, vx)), vx) - ); - } - - private static Const c(final Integer c) { - return TYPE.constant(c); - } - - Selector SELECTOR = ExpressionTest.SELECTOR - .variant("Triple", ExpressionTest.v(TripleExpression::tester)); - - static void main(final String... args) { - TripleExpression.SELECTOR.main(args); - } -} diff --git a/java/expression/common/Expr.java b/java/expression/common/Expr.java deleted file mode 100644 index b1dd418..0000000 --- a/java/expression/common/Expr.java +++ /dev/null @@ -1,32 +0,0 @@ -package expression.common; - -import base.Functional; -import base.Pair; - -import java.util.List; -import java.util.function.BiFunction; -import java.util.function.Function; - -/** - * @author Georgiy Korneev (kgeorgiy@kgeorgiy.info) - */ -public record Expr(Node node, List> variables) { - public List> variables(final BiFunction f) { - return Functional.map( - variables, - variable -> variable.second(f.apply(variable.first(), variable.second())) - ); - } - - public Expr convert(final BiFunction f) { - return of(node, variables(f)); - } - - public Expr node(final Function, Node> f) { - return of(f.apply(node), variables); - } - - public static Expr of(final Node node, final List> variables) { - return new Expr<>(node, variables); - } -} diff --git a/java/expression/common/ExpressionKind.java b/java/expression/common/ExpressionKind.java deleted file mode 100644 index d8da0aa..0000000 --- a/java/expression/common/ExpressionKind.java +++ /dev/null @@ -1,94 +0,0 @@ -package expression.common; - -import base.ExtendedRandom; -import base.Functional; -import base.Pair; -import expression.ToMiniString; - -import java.util.List; - -/** - * @author Georgiy Korneev (kgeorgiy@kgeorgiy.info) - */ -public class ExpressionKind { - private final Type type; - private final Class kind; - private final Variables variables; - private final Evaluator evaluator; - - public ExpressionKind( - final Type type, - final Class kind, - final Variables variables, - final Evaluator evaluator - ) { - this.type = type; - this.kind = kind; - this.variables = variables; - this.evaluator = evaluator; - } - - public ExpressionKind( - final Type type, - final Class kind, - final List> variables, - final Evaluator evaluator - ) { - this(type, kind, (r, c) -> variables, evaluator); - } - - public C evaluate(final E expression, final List variables, final List values) throws Exception { - return evaluator.evaluate(expression, variables, values); - } - - public E cast(final Object expression) { - return kind.cast(expression); - } - - public String getName() { - return kind.getSimpleName(); - } - - public E constant(final C value) { - return cast(type.constant(value)); - } - - public C randomValue(final ExtendedRandom random) { - return type.randomValue(random); - } - - public List> allValues(final int length, final List values) { - return Functional.allValues(fromInts(values), length); - } - - public List fromInts(final List values) { - return Functional.map(values, this::fromInt); - } - - public C fromInt(final int value) { - return type.fromInt(value); - } - - @Override - public String toString() { - return kind.getName(); - } - - public ExpressionKind withVariables(final Variables variables) { - return new ExpressionKind<>(type, kind, variables, evaluator); - } - - public Variables variables() { - return variables; - } - - @FunctionalInterface - public interface Variables { - List> generate(final ExtendedRandom random, final int count); - } - - @FunctionalInterface - public interface Evaluator { - R evaluate(final E expression, final List vars, final List values) throws Exception; - } -} diff --git a/java/expression/common/Generator.java b/java/expression/common/Generator.java deleted file mode 100644 index 2b7a52d..0000000 --- a/java/expression/common/Generator.java +++ /dev/null @@ -1,173 +0,0 @@ -package expression.common; - -import base.*; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.function.BiFunction; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.function.Supplier; -import java.util.stream.Stream; - -public class Generator { - private final Supplier constant; - private final List> ops; - private final ExpressionKind.Variables variables; - private final Set forbidden; - private final ExtendedRandom random; - private final List>, Stream>>> basicTests; - - public Generator( - final Supplier constant, - final List> ops, - final ExpressionKind.Variables variables, - final Set forbidden, - final ExtendedRandom random, - final List>, Stream>>> basicTests - ) { - this.constant = constant; - this.ops = List.copyOf(ops); - this.variables = variables; - this.forbidden = Set.copyOf(forbidden); - this.random = random; - this.basicTests = List.copyOf(basicTests); - } - - public static Builder builder(final Supplier constant, final ExtendedRandom random) { - return new Builder<>(random, constant); - } - - public void testRandom( - final TestCounter counter, - final int denominator, - final Consumer> consumer - ) { - final int d = Math.max(TestCounter.DENOMINATOR, denominator); - testRandom(counter, consumer, 1, 100, 100 / d, (vars, depth) -> generateFullDepth(vars, Math.min(depth, 3))); - testRandom(counter, consumer, 2, 1000 / d, 1, this::generateSize); - testRandom(counter, consumer, 3, 12, 100 / d, this::generateFullDepth); - testRandom(counter, consumer, 4, 777 / d, 1, this::generatePartialDepth); - } - - private void testRandom( - final TestCounter counter, - final Consumer> consumer, - final int seq, - final int levels, - final int perLevel, - final BiFunction>, Integer, Node> generator - ) { - counter.scope("Random tests #" + seq, () -> { - final int total = levels * perLevel; - int generated = 0; - for (int level = 0; level < levels; level++) { - for (int j = 0; j < perLevel; j++) { - if (generated % 100 == 0) { - progress(counter, total, generated); - } - generated++; - - final List> vars = variables(random.nextInt(10) + 1); - consumer.accept(Expr.of(generator.apply(Functional.map(vars, v -> Node.op(v.first())), level), vars)); - } - } - progress(counter, generated, total); - }); - } - - private static void progress(final TestCounter counter, final int total, final int generated) { - counter.format("Completed %4d out of %d%n", generated, total); - } - - private Node generate( - final List> variables, - final boolean nullary, - final Supplier> unary, - final Supplier, Node>> binary - ) { - if (nullary || ops.isEmpty()) { - return random.nextBoolean() ? random.randomItem(variables) : Node.constant(constant.get()); - } else { - final Named op = random.randomItem(ops); - if (Math.abs(op.value()) == 1) { - return Node.op(op.name(), (op.value() + 1) >> 1, unary.get()); - } else { - final Pair, Node> pair = binary.get(); - return Node.op(op.name(), pair.first(), pair.second()); - } - } - } - - private Node generate(final List> variables, final boolean nullary, final Supplier> child) { - return generate(variables, nullary, child, () -> Pair.of(child.get(), child.get())); - } - - private Node generateFullDepth(final List> variables, final int depth) { - return generate(variables, depth == 0, () -> generateFullDepth(variables, depth - 1)); - } - - private Node generatePartialDepth(final List> variables, final int depth) { - return generate(variables, depth == 0, () -> generatePartialDepth(variables, random.nextInt(depth))); - } - - private Node generateSize(final List> variables, final int size) { - final int first = size <= 1 ? 0 : random.nextInt(size); - return generate( - variables, - size == 0, - () -> generateSize(variables, size - 1), - () -> Pair.of( - generateSize(variables, first), - generateSize(variables, size - 1 - first) - ) - ); - } - - public void testBasic(final Consumer> consumer) { - basicTests.forEach(test -> { - final List> vars = variables(random.nextInt(5) + 3); - test.apply(Functional.map(vars, v -> Node.op(v.first()))) - .map(node -> Expr.of(node, vars)) - .forEachOrdered(consumer); - }); - } - - public List> variables(final int count) { - List> vars; - do { - vars = variables.generate(random, count); - } while (vars.stream().map(Pair::first).anyMatch(forbidden::contains)); - return vars; - } - - /** - * @author Georgiy Korneev (kgeorgiy@kgeorgiy.info) - */ - public static final class Builder { - private final ExtendedRandom random; - private final Supplier constant; - - private final List> ops = new ArrayList<>(); - private final Set forbidden = new HashSet<>(); - - private Builder(final ExtendedRandom random, final Supplier constant) { - this.random = random; - this.constant = constant; - } - - public void add(final String name, final int arity) { - ops.add(Named.of(name, arity)); - forbidden.add(name); - } - - public Generator build( - final ExpressionKind.Variables variables, - final List>, Stream>>> basicTests - ) { - return new Generator<>(constant, ops, variables, forbidden, random, basicTests); - } - } -} diff --git a/java/expression/common/Node.java b/java/expression/common/Node.java deleted file mode 100644 index df13ff8..0000000 --- a/java/expression/common/Node.java +++ /dev/null @@ -1,106 +0,0 @@ -package expression.common; - -import java.util.function.Function; - -/** - * @author Georgiy Korneev (kgeorgiy@kgeorgiy.info) - */ -public abstract class Node { - private Node() { - } - - public abstract R get(Const con, Nullary nul, Unary, R> un, Binary, R> bin); - public abstract R cata(Const con, Nullary nul, Unary un, Binary bin); - - public final String toPolish() { - return cata( - T::toString, - name -> name, - (name, priority, a) -> a + " " + name + ":1", - (name, a1, a2) -> a1 + " " + a2 + " " + name + ":2" - ); - } - - @Override - public final String toString() { - return cata( - T::toString, - name -> name, - (name, priority, a) -> name.equals("[") ? "[" + a + "]" : - (priority & 1) == 1 ? "(" + name + " " + a + ")" : "(" + a + " " + name + ")", - (name, a1, a2) -> "(" + a1 + " " + name + " " + a2 + ")" - ); - } - - public static Node constant(final T value) { - return new Node<>() { - @Override - public R get(final Const con, final Nullary nul, final Unary, R> un, final Binary, R> bin) { - return con.apply(value); - } - - @Override - public R cata(final Const con, final Nullary nul, final Unary un, final Binary bin) { - return con.apply(value); - } - }; - } - - public static Node op(final String name) { - return new Node<>() { - @Override - public R get(final Const con, final Nullary nul, final Unary, R> un, final Binary, R> bin) { - return nul.apply(name); - } - - @Override - public R cata(final Const con, final Nullary nul, final Unary un, final Binary bin) { - return nul.apply(name); - } - }; - } - - public static Node op(final String name, final int priority, final Node arg) { - return new Node<>() { - @Override - public R get(final Const con, final Nullary nul, final Unary, R> un, final Binary, R> bin) { - return un.apply(name, priority, arg); - } - - @Override - public R cata(final Const con, final Nullary nul, final Unary un, final Binary bin) { - return un.apply(name, priority, arg.cata(con, nul, un, bin)); - } - }; - } - - public static Node op(final String name, final Node arg1, final Node arg2) { - return new Node<>() { - @Override - public R get(final Const con, final Nullary nul, final Unary, R> un, final Binary, R> bin) { - return bin.apply(name, arg1, arg2); - } - - @Override - public R cata(final Const con, final Nullary nul, final Unary un, final Binary bin) { - return bin.apply(name, arg1.cata(con, nul, un, bin), arg2.cata(con, nul, un, bin)); - } - }; - } - - @FunctionalInterface - public interface Const extends Function {} - - @FunctionalInterface - public interface Nullary extends Function {} - - @FunctionalInterface - public interface Unary { - R apply(String name, int priority, T arg); - } - - @FunctionalInterface - public interface Binary { - R apply(String name, T arg1, T arg2); - } -} diff --git a/java/expression/common/NodeRenderer.java b/java/expression/common/NodeRenderer.java deleted file mode 100644 index d35e4da..0000000 --- a/java/expression/common/NodeRenderer.java +++ /dev/null @@ -1,96 +0,0 @@ -package expression.common; - -import base.ExtendedRandom; - -import java.util.List; -import java.util.Map; - -/** - * @author Georgiy Korneev (kgeorgiy@kgeorgiy.info) - */ -public class NodeRenderer { - public static final String PAREN = "["; - public static final List DEFAULT_PARENS = List.of(paren("(", ")")); - - public static final Mode MINI_MODE = Mode.SIMPLE_MINI; // Replace by TRUE_MINI for some challenge; - public static final Settings FULL = Mode.FULL.settings(0); - public static final Settings FULL_EXTRA = Mode.FULL.settings(Integer.MAX_VALUE / 4); - public static final Settings SAME = Mode.SAME.settings(0); - public static final Settings MINI = MINI_MODE.settings(0); - public static final Settings TRUE_MINI = Mode.TRUE_MINI.settings(0); - - private final Renderer> renderer; - private final Map brackets; - private final ExtendedRandom random; - - public NodeRenderer( - final Renderer> renderer, - final Map brackets, - final ExtendedRandom random - ) { - this.renderer = renderer; - this.brackets = Map.copyOf(brackets); - this.random = random; - } - - public static Node paren(final boolean condition, final Node node) { - return condition ? Node.op(PAREN, 1, node) : node; - } - - public static Paren paren(final String open, final String close) { - return new Paren(open, close); - } - - public Node renderToNode(final Settings settings, final Expr expr) { - final Expr> convert = expr.convert((name, variable) -> Node.op(name)); - return renderer.render(convert, settings); - } - - public String render(final Node node, final List parens) { - return node.cata( - String::valueOf, - name -> name, - (name, priority, arg) -> - name == PAREN ? random.randomItem(parens).apply(arg) : - priority == Integer.MAX_VALUE ? name + arg + brackets.get(name) : - (priority & 1) == 1 ? name + arg : - arg + name, - (name, a, b) -> a + " " + name + " " + b - ); - } - - public String render(final Expr expr, final Settings settings) { - return render(renderToNode(settings, expr), settings.parens()); - } - - public enum Mode { - FULL, SAME, TRUE_MINI, SIMPLE_MINI; - - public Settings settings(final int limit) { - return new Settings(this, limit); - } - } - - public record Paren(String open, String close) { - String apply(final String expression) { - return open() + expression + close(); - } - } - - public record Settings(Mode mode, int limit, List parens) { - public Settings(final Mode mode, final int limit) { - this(mode, limit, DEFAULT_PARENS); - } - - public Node extra(Node node, final ExtendedRandom random) { - while (random.nextInt(Integer.MAX_VALUE) < limit) { - node = paren(true, node); - } - return node; - } - - public Settings withParens(final List parens) { - return this.parens.equals(parens) ? this : new Settings(mode, limit, List.copyOf(parens)); - } - } -} diff --git a/java/expression/common/NodeRendererBuilder.java b/java/expression/common/NodeRendererBuilder.java deleted file mode 100644 index 4e4032a..0000000 --- a/java/expression/common/NodeRendererBuilder.java +++ /dev/null @@ -1,145 +0,0 @@ -package expression.common; - -import base.ExtendedRandom; -import base.Functional; - -import java.util.HashMap; -import java.util.Map; -import java.util.function.Supplier; - -/** - * @author Georgiy Korneev (kgeorgiy@kgeorgiy.info) - */ -@SuppressWarnings("StaticMethodOnlyUsedInOneClass") -public class NodeRendererBuilder { - private final Renderer.Builder> nodeRenderer = Renderer.builder(Node::constant); - private final Map priorities = new HashMap<>(); - private final Map brackets = new HashMap<>(); - private final ExtendedRandom random; - - public NodeRendererBuilder(final ExtendedRandom random) { - this.random = random; - nodeRenderer.unary(NodeRenderer.PAREN, (mode, arg) -> NodeRenderer.paren(true, arg)); - } - - public void unary(final String name, final int priority) { - final String space = name.equals("-") || Character.isLetter(name.charAt(0)) ? " " : ""; - nodeRenderer.unary( - name, - (settings, arg) -> settings.extra(Node.op(name, priority, inner(settings, priority, arg, space)), random) - ); - } - - public void unary(final String left, final String right) { - brackets.put(left, right); - nodeRenderer.unary( - left, - (settings, arg) -> settings.extra(Node.op(left, Integer.MAX_VALUE, arg), random) - ); - } - - private Node inner(final NodeRenderer.Settings settings, final int priority, final Node arg, final String space) { - if (settings.mode() == NodeRenderer.Mode.FULL) { - return NodeRenderer.paren(true, arg); - } else { - final String op = arg.get( - c -> space, - n -> space, - (n, p, a) -> - priority > unaryPriority(arg) ? NodeRenderer.PAREN : - NodeRenderer.PAREN.equals(n) ? "" : - space, - (n, a, b) -> NodeRenderer.PAREN - ); - return op.isEmpty() ? arg : Node.op(op, Priority.MAX.priority | 1, arg); - } - } - - private static Integer unaryPriority(final Node node) { - return node.get(c -> Integer.MAX_VALUE, n -> Integer.MAX_VALUE, (n, p, a) -> p, (n, a, b) -> Integer.MIN_VALUE); - } - - public void binary(final String name, final int priority) { - final Priority mp = new Priority(name, priority); - priorities.put(name, mp); - - nodeRenderer.binary(name, (settings, l, r) -> settings.extra(process(settings, mp, l, r), random)); - } - - private Node process(final NodeRenderer.Settings settings, final Priority mp, final Node l, final Node r) { - if (settings.mode() == NodeRenderer.Mode.FULL) { - return NodeRenderer.paren(true, op(mp, l, r)); - } - - final Priority lp = priority(l); - final Priority rp = priority(r); - - final int rc = rp.compareLevels(mp); - - // :NOTE: Especially ugly code, do not replicate - final boolean advanced = settings.mode() == NodeRenderer.Mode.SAME - || mp.has(2) - || mp.has(1) && (mp != rp || (settings.mode() == NodeRenderer.Mode.TRUE_MINI && hasOther(r, rp))); - - final Node al = NodeRenderer.paren(lp.compareLevels(mp) < 0, l); - if (rc == 0 && !advanced) { - return get(r, null, (n, a, b) -> rp.op(mp.op(al, a), b)); - } else { - return mp.op(al, NodeRenderer.paren(rc == 0 && advanced || rc < 0, r)); - } - } - - private boolean hasOther(final Node node, final Priority priority) { - return get(node, () -> false, (name, l, r) -> { - final Priority p = Functional.get(priorities, name); - if (p.compareLevels(priority) != 0) { - return false; - } - return p != priority || hasOther(l, priority); - }); - } - - private Node op(final Priority mp, final Node l, final Node r) { - return mp.op(l, r); - } - - private Priority priority(final Node node) { - return get(node, () -> Priority.MAX, (n, a, b) -> Functional.get(priorities, n)); - } - - private R get(final Node node, final Supplier common, final Node.Binary, R> binary) { - return node.get( - c -> common.get(), - n -> common.get(), - (n, p, a) -> common.get(), - binary - ); - } - - public NodeRenderer build() { - return new NodeRenderer<>(nodeRenderer.build(), brackets, random); - } - - // :NOTE: Especially ugly bit-fiddling, do not replicate - private record Priority(String op, int priority) { - private static final int Q = 3; - private static final Priority MAX = new Priority("MAX", Integer.MAX_VALUE - Q); - - private int compareLevels(final Priority that) { - return (priority | Q) - (that.priority | Q); - } - - @Override - public String toString() { - return String.format("Priority(%s, %d, %d)", op, priority | Q, priority & Q); - } - - public Node op(final Node l, final Node r) { - return Node.op(op, l, r); - } - - private boolean has(final int value) { - return (priority & Q) == value; - } - } -} diff --git a/java/expression/common/Reason.java b/java/expression/common/Reason.java deleted file mode 100644 index 9ad5b22..0000000 --- a/java/expression/common/Reason.java +++ /dev/null @@ -1,60 +0,0 @@ -package expression.common; - -import base.Either; - -import java.util.function.LongUnaryOperator; -import java.util.function.Supplier; - -/** - * @author Georgiy Korneev (kgeorgiy@kgeorgiy.info) - */ -public final class Reason { - public static final Reason OVERFLOW = new Reason("Overflow"); - public static final Reason DBZ = new Reason("Division by zero"); - - private final String description; - - public Reason(final String description) { - this.description = description; - } - - public static Either eval(final Supplier action) { - try { - return Either.right(action.get()); - } catch (final ReasonException e) { - return Either.left(e.reason); - } - } - - public static int overflow(final long value) { - return value < Integer.MIN_VALUE || Integer.MAX_VALUE < value - ? OVERFLOW.error() - : (int) value; - } - - public T error() { - throw new ReasonException(this); - } - - public LongUnaryOperator less(final long limit, final LongUnaryOperator op) { - return a -> a < limit ? error() : op.applyAsLong(a); - } - - public LongUnaryOperator greater(final int limit, final LongUnaryOperator op) { - return a -> a > limit ? error() : op.applyAsLong(a); - } - - private static class ReasonException extends RuntimeException { - private final Reason reason; - - public ReasonException(final Reason reason) { - super(reason.description); - this.reason = reason; - } - } - - @Override - public String toString() { - return String.format("Reason(%s)", description); - } -} diff --git a/java/expression/common/Renderer.java b/java/expression/common/Renderer.java deleted file mode 100644 index 1187f31..0000000 --- a/java/expression/common/Renderer.java +++ /dev/null @@ -1,60 +0,0 @@ -package expression.common; - -import base.Functional; -import base.Pair; - -import java.util.HashMap; -import java.util.Map; -import java.util.stream.Collectors; - -/** - * @author Georgiy Korneev (kgeorgiy@kgeorgiy.info) - */ -public interface Renderer { - static Builder builder(final Node.Const constant) { - return new Builder<>(constant); - } - - R render(final Expr expr, final S settings); - - @FunctionalInterface - interface UnaryOperator { - R apply(S settings, R arg); - } - - @FunctionalInterface - interface BinaryOperator { - R apply(S settings, R arg1, R arg2); - } - - final class Builder { - private final Node.Const constant; - private final Map> unary = new HashMap<>(); - private final Map> binary = new HashMap<>(); - - private Builder(final Node.Const constant) { - this.constant = constant; - } - - public void unary(final String name, final UnaryOperator op) { - unary.put(name, op); - } - - public void binary(final String name, final BinaryOperator op) { - binary.put(name, op); - } - - public Renderer build() { - return (expr, settings) -> { - final Map vars = expr.variables().stream() - .collect(Collectors.toMap(Pair::first, Pair::second)); - return expr.node().cata( - constant, - name -> Functional.get(vars, name), - (name, p, arg) -> Functional.get(unary, name).apply(settings, arg), - (name, arg1, arg2) -> Functional.get(binary, name).apply(settings, arg1, arg2) - ); - }; - } - } -} diff --git a/java/expression/common/TestGenerator.java b/java/expression/common/TestGenerator.java deleted file mode 100644 index fcf7288..0000000 --- a/java/expression/common/TestGenerator.java +++ /dev/null @@ -1,56 +0,0 @@ -package expression.common; - -import base.Pair; -import base.TestCounter; -import expression.ToMiniString; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.function.Consumer; - -public class TestGenerator { - private final Generator generator; - private final NodeRenderer renderer; - - public TestGenerator(final Generator generator, final NodeRenderer renderer) { - this.generator = generator; - this.renderer = renderer; - } - - public void testBasic(final Consumer> test) { - generator.testBasic(consumer(test)); - } - - public void testRandom(final TestCounter counter, final int denominator, final Consumer> test) { - generator.testRandom(counter, denominator, consumer(test)); - } - - private Consumer> consumer(final Consumer> consumer) { - return expr -> consumer.accept(new TestGenerator.Test<>(expr, renderer)); - } - - - public List> variables(final int count) { - return generator.variables(count); - } - - public String render(final Expr expr, final NodeRenderer.Settings settings) { - return renderer.render(expr, settings); - } - - public static class Test { - public final Expr expr; - private final Map rendered = new HashMap<>(); - private final NodeRenderer renderer; - - public Test(final Expr expr, final NodeRenderer renderer) { - this.expr = expr; - this.renderer = renderer; - } - - public String render(final NodeRenderer.Settings settings) { - return rendered.computeIfAbsent(settings, s -> renderer.render(expr, s)); - } - } -} diff --git a/java/expression/common/TestGeneratorBuilder.java b/java/expression/common/TestGeneratorBuilder.java deleted file mode 100644 index fa3a7b5..0000000 --- a/java/expression/common/TestGeneratorBuilder.java +++ /dev/null @@ -1,145 +0,0 @@ -package expression.common; - -import base.ExtendedRandom; -import base.Functional; -import expression.ToMiniString; -import expression.common.ExpressionKind.Variables; - -import java.util.*; -import java.util.function.Function; -import java.util.function.Supplier; -import java.util.stream.Stream; - -/** - * @author Georgiy Korneev (kgeorgiy@kgeorgiy.info) - */ -public class TestGeneratorBuilder { - private final ExtendedRandom random; - - private final Generator.Builder generator; - private final NodeRendererBuilder renderer; - - private final List>, Stream>>> basicTests = new ArrayList<>(); - private final List> consts; - private final boolean verbose; - - public TestGeneratorBuilder( - final ExtendedRandom random, - final Supplier constant, - final List constants, - final boolean verbose - ) { - this.random = random; - this.verbose = verbose; - - generator = Generator.builder(constant, random); - renderer = new NodeRendererBuilder<>(random); - - consts = Functional.map(constants, Node::constant); - basicTests.add(vars -> consts.stream()); - basicTests.add(List::stream); - } - - private Node c() { - return random.randomItem(consts); - } - - private Node v(final List> variables) { - return random.randomItem(variables); - } - - private static Node f(final String name, final int priority, final Node arg) { - return Node.op(name, priority, arg); - } - - private static Node f(final String left, final Node arg) { - return Node.op(left, Integer.MAX_VALUE, arg); - } - - private static Node f(final String name, final Node arg1, final Node arg2) { - return Node.op(name, arg1, arg2); - } - - @SafeVarargs - private void basicTests(final Function>, Node>... tests) { - Arrays.stream(tests).map(test -> test.andThen(Stream::of)).forEachOrdered(basicTests::add); - } - - public void unary(final String name, final int priority) { - generator.add(name, (priority & 1) * 2 - 1); - renderer.unary(name, priority); - - if (verbose) { - basicTests.add(vars -> Stream.concat(consts.stream(), vars.stream()).map(a -> f(name, priority, a))); - } else { - basicTests(vars -> f(name, priority, c()), vars -> f(name, priority, v(vars))); - } - - final Function>, Node> p1 = vars -> f(name, priority, f(name, priority, f("+", v(vars), c()))); - final Function>, Node> p2 = vars -> f("*", v(vars), f("*", v(vars), f(name, priority, c()))); - basicTests( - vars -> f(name, priority, f("+", v(vars), v(vars))), - vars -> f(name, priority, f(name, priority, v(vars))), - vars -> f(name, priority, f("/", f(name, priority, v(vars)), f("+", v(vars), v(vars)))), - p1, - p2, - vars -> f("+", p1.apply(vars), p2.apply(vars)) - ); - } - - public void unary(final String left, final String right) { - generator.add(left, 1); - renderer.unary(left, right); - - if (verbose) { - basicTests.add(vars -> Stream.concat(consts.stream(), vars.stream()).map(a -> f(left, a))); - } else { - basicTests(vars -> f(left, c()), vars -> f(left, v(vars))); - } - - final Function>, Node> p1 = vars -> f(left, f(left, f("+", v(vars), c()))); - final Function>, Node> p2 = vars -> f("*", v(vars), f("*", v(vars), f(left, c()))); - basicTests( - vars -> f(left, f("+", v(vars), v(vars))), - vars -> f(left, f(left, v(vars))), - vars -> f(left, f("/", f(left, v(vars)), f("+", v(vars), v(vars)))), - p1, - p2, - vars -> f("+", p1.apply(vars), p2.apply(vars)) - ); - } - - public void binary(final String name, final int priority) { - generator.add(name, 2); - renderer.binary(name, priority); - - if (verbose) { - basicTests.add(vars -> Stream.concat(consts.stream(), vars.stream().limit(3)) - .flatMap(a -> consts.stream().map(b -> f(name, a, b)))); - } else { - basicTests( - vars -> f(name, c(), c()), - vars -> f(name, v(vars), c()), - vars -> f(name, c(), v(vars)), - vars -> f(name, v(vars), v(vars)) - ); - } - - final Function>, Node> p1 = vars -> f(name, f(name, f("+", v(vars), c()), v(vars)), v(vars)); - final Function>, Node> p2 = vars -> f("*", v(vars), f("*", v(vars), f(name, c(), v(vars)))); - - basicTests( - vars -> f(name, f(name, v(vars), v(vars)), v(vars)), - vars -> f(name, v(vars), f(name, v(vars), v(vars))), - vars -> f(name, f(name, v(vars), v(vars)), f(name, v(vars), v(vars))), - vars -> f(name, f("-", f(name, v(vars), v(vars)), c()), f("+", v(vars), v(vars))), - p1, - p2, - vars -> f("+", p1.apply(vars), p2.apply(vars)) - ); - } - - public TestGenerator build(final Variables variables) { - return new TestGenerator<>(generator.build(variables, basicTests), renderer.build()); - } -} diff --git a/java/expression/common/Type.java b/java/expression/common/Type.java deleted file mode 100644 index 3b396e9..0000000 --- a/java/expression/common/Type.java +++ /dev/null @@ -1,51 +0,0 @@ -package expression.common; - -import base.Asserts; -import base.ExtendedRandom; -import expression.Const; - -import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodHandles; -import java.lang.invoke.MethodType; -import java.util.function.Function; -import java.util.function.IntFunction; - -/** - * @author Georgiy Korneev (kgeorgiy@kgeorgiy.info) - */ -public class Type { - private final IntFunction fromInt; - private final Function random; - private final Function constant; - - public Type(final IntFunction fromInt, final Function random, final Class type) { - this.fromInt = fromInt; - this.random = random; - - try { - final MethodHandle constructor = MethodHandles.publicLookup() - .findConstructor(Const.class, MethodType.methodType(void.class, type)); - constant = c -> { - try { - return (Const) constructor.invoke(c); - } catch (final Throwable e) { - throw Asserts.error("Cannot create new Const(%s): %s", c, e); - } - }; - } catch (final IllegalAccessException | NoSuchMethodException e) { - throw Asserts.error("Cannot find constructor Const(%s): %s", type, e); - } - } - - public Const constant(final C value) { - return constant.apply(value); - } - - public C fromInt(final int value) { - return fromInt.apply(value); - } - - public C randomValue(final ExtendedRandom random) { - return this.random.apply(random); - } -} diff --git a/java/expression/common/package-info.java b/java/expression/common/package-info.java deleted file mode 100644 index 70d03f2..0000000 --- a/java/expression/common/package-info.java +++ /dev/null @@ -1,7 +0,0 @@ -/** - * Expressions generators for expression-based homeworks - * of Introduction to Programming course. - * - * @author Georgiy Korneev (kgeorgiy@kgeorgiy.info) - */ -package expression.common; \ No newline at end of file diff --git a/java/expression/exceptions/ExceptionsTest.java b/java/expression/exceptions/ExceptionsTest.java deleted file mode 100644 index 851f635..0000000 --- a/java/expression/exceptions/ExceptionsTest.java +++ /dev/null @@ -1,30 +0,0 @@ -package expression.exceptions; - -import base.Selector; -import expression.ListExpression; -import expression.parser.Operations; - -import static expression.parser.Operations.*; - -/** - * @author Georgiy Korneev (kgeorgiy@kgeorgiy.info) - */ -public final class ExceptionsTest { - private static final ExpressionParser PARSER = new ExpressionParser(); - private static final Operations.Operation LIST = kind(ListExpression.KIND, PARSER::parse); - - public static final Selector SELECTOR = Selector.composite(ExceptionsTest.class, ExceptionsTester::new, "easy", "hard") - .variant("Base", LIST, ADD, SUBTRACT, MULTIPLY, DIVIDE, NEGATE) - .variant("3637", POW, LOG) - .variant("3839", POW, LOG, POW_2, LOG_2) - .variant("3435", POW_2, LOG_2) - .variant("3233", HIGH, LOW) - .selector(); - - private ExceptionsTest() { - } - - public static void main(final String... args) { - SELECTOR.main(args); - } -} diff --git a/java/expression/exceptions/ExceptionsTestSet.java b/java/expression/exceptions/ExceptionsTestSet.java deleted file mode 100644 index f19baa5..0000000 --- a/java/expression/exceptions/ExceptionsTestSet.java +++ /dev/null @@ -1,162 +0,0 @@ -package expression.exceptions; - -import base.Functional; -import base.Named; -import base.Pair; -import expression.ToMiniString; -import expression.Variable; -import expression.common.ExpressionKind; -import expression.parser.ParserTestSet; - -import java.util.ArrayList; -import java.util.List; -import java.util.function.LongBinaryOperator; - -/** - * @author Georgiy Korneev (kgeorgiy@kgeorgiy.info) - */ -public class ExceptionsTestSet extends ParserTestSet { - private static final int D = 5; - private static final List OVERFLOW_VALUES = new ArrayList<>(); - private final char[] CHARS = "AZ+-*%()[]<>".toCharArray(); - - static { - Functional.addRange(OVERFLOW_VALUES, D, Integer.MIN_VALUE + D); - Functional.addRange(OVERFLOW_VALUES, D, Integer.MIN_VALUE / 2); - Functional.addRange(OVERFLOW_VALUES, D, (int) -Math.sqrt(Integer.MAX_VALUE)); - Functional.addRange(OVERFLOW_VALUES, D, 0); - Functional.addRange(OVERFLOW_VALUES, D, (int) Math.sqrt(Integer.MAX_VALUE)); - Functional.addRange(OVERFLOW_VALUES, D, Integer.MAX_VALUE / 2); - Functional.addRange(OVERFLOW_VALUES, D, Integer.MAX_VALUE - D); - } - - private final List> parsingTest; - - public ExceptionsTestSet(final ExceptionsTester tester, final ParsedKind kind) { - super(tester, kind, false); - parsingTest = tester.parsingTest; - } - - private void testParsingErrors() { - counter.testForEach(parsingTest, op -> { - final List names = Functional.map(kind.kind().variables().generate(counter.random(), 3), Pair::first); - final String expr = mangle(op.value(), names); - try { - kind.parse(expr, names); - counter.fail("Successfully parsed '%s'", op.value()); - } catch (final Exception e) { - counter.format("%-30s %s%n", op.name(), e.getClass().getSimpleName() + ": " + e.getMessage()); - } - }); - } - - private void testOverflow() { - final List> variables = kind.kind().variables().generate(counter.random(), 3); - final List names = Functional.map(variables, Pair::first); - final Variable vx = (Variable) variables.get(0).second(); - final Variable vy = (Variable) variables.get(1).second(); - - //noinspection Convert2MethodRef - testOverflow(names, (a, b) -> a + b, "+", new CheckedAdd(vx, vy)); - testOverflow(names, (a, b) -> a - b, "-", new CheckedSubtract(vx, vy)); - testOverflow(names, (a, b) -> a * b, "*", new CheckedMultiply(vx, vy)); - testOverflow(names, (a, b) -> b == 0 ? Long.MAX_VALUE : a / b, "/", new CheckedDivide(vx, vy)); - testOverflow(names, (a, b) -> -b, "<- ignore first argument, unary -", new CheckedNegate(vy)); - } - - private void testOverflow(final List names, final LongBinaryOperator f, final String op, final Object expression) { - final ExpressionKind kind = this.kind.kind(); - for (final int a : OVERFLOW_VALUES) { - for (final int b : OVERFLOW_VALUES) { - final long expected = f.applyAsLong(a, b); - final boolean isInt = Integer.MIN_VALUE <= expected && expected <= Integer.MAX_VALUE; - try { - final C actual = kind.evaluate( - kind.cast(expression), - names, - kind.fromInts(List.of(a, b, 0)) - ); - counter.checkTrue( - isInt && kind.fromInt((int) expected).equals(actual), - "%d %s %d == %d", a, op, b, actual - ); - } catch (final Exception e) { - if (isInt) { - counter.fail(e, "Unexpected error in %d %s %d", a, op, b); - } - } - } - } - } - - @Override - protected void test() { - counter.scope("Overflow tests", (Runnable) this::testOverflow); - super.test(); - counter.scope("Parsing error tests", this::testParsingErrors); - } - - - @Override - protected E parse(final String expression, final List variables, final boolean reparse) { - final String expr = expression.strip(); - if (expr.length() > 10) { - for (final char ch : CHARS) { - for (int i = 0; i < 10; i++) { - final int index = 1 + tester.random().nextInt(expr.length() - 2); - int pi = index - 1; - while (Character.isWhitespace(expr.charAt(pi))) { - pi--; - } - int ni = index; - while (Character.isWhitespace(expr.charAt(ni))) { - ni++; - } - final char pc = expr.charAt(pi); - final char nc = expr.charAt(ni); - if ( - "-([{*∛√²³₂₃!‖⎵⎴⌊⌈=?".indexOf(nc) < 0 && - (!Character.isLetterOrDigit(pc) || !Character.isLetterOrDigit(ch)) && - nc != ch && pc != ch && - !Character.isLetterOrDigit(nc) && nc != '$' - ) { - shouldFail( - variables, - "Parsing error expected for " + insert(expr, index, "" + ch + "<-- ERROR_INSERTED>"), - insert(expr, index, String.valueOf(ch)) - ); - break; - } - } - } - parens(variables, expr, '[', ']'); - parens(variables, expr, '{', '}'); - } - - return counter.testV(() -> counter.call("parse", () -> kind.parse(expr, variables))); - } - - private static String insert(final String expr, final int index, final String value) { - return expr.substring(0, index) + value + expr.substring(index); - } - - private void parens(final List variables, final String expr, final char open, final char close) { - if (expr.indexOf(open) >= 0) { - replaces(variables, expr, open, '('); - replaces(variables, expr, close, ')'); - if (expr.indexOf('(') >= 0) { - replaces(variables, expr, '(', open); - replaces(variables, expr, ')', close); - } - } - } - - private void replaces(final List variables, final String expr, final char what, final char by) { - final String input = expr.replace(what, by); - shouldFail(variables, "Unmatched parentheses: " + input, input); - } - - private void shouldFail(final List variables, final String message, final String input) { - counter.shouldFail(message, () -> kind.parse(input, variables)); - } -} diff --git a/java/expression/exceptions/ExceptionsTester.java b/java/expression/exceptions/ExceptionsTester.java deleted file mode 100644 index df9048b..0000000 --- a/java/expression/exceptions/ExceptionsTester.java +++ /dev/null @@ -1,100 +0,0 @@ -package expression.exceptions; - -import base.Named; -import base.TestCounter; -import expression.common.Reason; -import expression.parser.ParserTestSet; -import expression.parser.ParserTester; - -import java.util.ArrayList; -import java.util.List; -import java.util.function.BiFunction; -import java.util.function.LongBinaryOperator; -import java.util.function.LongToIntFunction; - -/** - * @author Georgiy Korneev (kgeorgiy@kgeorgiy.info) - */ -public class ExceptionsTester extends ParserTester { - /* package-private */ final List> parsingTest = new ArrayList<>(List.of( - Named.of("No first argument", "* $y * $z"), - Named.of("No middle argument", "$x * * $z"), - Named.of("No last argument", "$x * $y * "), - Named.of("No first argument'", "1 + (* $y * $z) + 2"), - Named.of("No middle argument'", "1 + ($x * / 9) + 3"), - Named.of("No last argument'", "1 + ($x * $y - ) + 3"), - Named.of("No opening parenthesis", "$x * $y)"), - Named.of("No closing parenthesis", "($x * $y"), - Named.of("Mismatched closing parenthesis", "($x * $y]"), - Named.of("Mismatched open parenthesis", "[$x * $y)"), - Named.of("Start symbol", "@$x * $y"), - Named.of("Middle symbol", "$x @ * $y"), - Named.of("End symbol", "$x * $y@"), - Named.of("Constant overflow 1", Integer.MIN_VALUE - 1L + ""), - Named.of("Constant overflow 2", Integer.MAX_VALUE + 1L + ""), - Named.of("Bare +", "+"), - Named.of("Bare -", "-"), - Named.of("Bare a", "a"), - Named.of("(())", "(())"), - Named.of("Spaces in numbers", "10 20") - )); - - public ExceptionsTester(final TestCounter counter) { - super(counter); - } - - - private void parsingTests(final String... tests) { - for (final String test : tests) { - parsingTest.add(Named.of(test, test)); - } - } - - @Override - public void unary(final String name, final int priority, final BiFunction op) { - if (allowed(name)) { - parsingTests(name, "1 * " + name, name + " * 1"); - } - parsingTests(name + "()", name + "(1, 2)"); - if (name.length() > 1) { - parsingTests(name + "q"); - } - if (allLetterAndDigit(name)) { - parsingTests(name + "1", name + "q"); - } - super.unary(name, priority, op); - } - - private static boolean allowed(final String name) { - return !"xyz".contains(name.substring(0, 1)) && !"xyz".contains(name.substring(name.length() - 1)); - } - - @Override - public void binary(final String name, final int priority, final LongBinaryOperator op) { - if (allowed(name)) { - parsingTests(name); - } - parsingTests("1 " + name, "1 " + name + " * 3"); - if (!"-".equals(name)) { - parsingTests(name + " 1", "1 * " + name + " 2"); - } - if (allLetterAndDigit(name)) { - parsingTests("5" + name + "5", "5 " + name + "5", "5 " + name + "5 5", "1" + name + "x 1", "1 " + name + "x 1"); - } - super.binary(name, priority, op); - } - - private static boolean allLetterAndDigit(final String name) { - return name.chars().allMatch(Character::isLetterOrDigit); - } - - @Override - protected void test(final ParserTestSet.ParsedKind kind) { - new ExceptionsTestSet<>(this, kind).test(); - } - - @Override - protected int cast(final long value) { - return Reason.overflow(value); - } -} diff --git a/java/expression/exceptions/ListParser.java b/java/expression/exceptions/ListParser.java deleted file mode 100644 index 2370790..0000000 --- a/java/expression/exceptions/ListParser.java +++ /dev/null @@ -1,13 +0,0 @@ -package expression.exceptions; - -import expression.ListExpression; - -import java.util.List; - -/** - * @author Georgiy Korneev (kgeorgiy@kgeorgiy.info) - */ -@FunctionalInterface -public interface ListParser { - ListExpression parse(String expression, final List variables) throws Exception; -} diff --git a/java/expression/exceptions/package-info.java b/java/expression/exceptions/package-info.java deleted file mode 100644 index 5debca1..0000000 --- a/java/expression/exceptions/package-info.java +++ /dev/null @@ -1,8 +0,0 @@ -/** - * Tests for Expression Error Handling homework - * of Introduction to Programming course. - * - * - * @author Georgiy Korneev (kgeorgiy@kgeorgiy.info) - */ -package expression.exceptions; \ No newline at end of file diff --git a/java/expression/package-info.java b/java/expression/package-info.java deleted file mode 100644 index 8d9e3c1..0000000 --- a/java/expression/package-info.java +++ /dev/null @@ -1,7 +0,0 @@ -/** - * Tests for Expressions homework - * of Introduction to Programming course. - * - * @author Georgiy Korneev (kgeorgiy@kgeorgiy.info) - */ -package expression; \ No newline at end of file diff --git a/java/expression/parser/ListParser.java b/java/expression/parser/ListParser.java deleted file mode 100644 index 0f331d9..0000000 --- a/java/expression/parser/ListParser.java +++ /dev/null @@ -1,13 +0,0 @@ -package expression.parser; - -import expression.ListExpression; - -import java.util.List; - -/** - * @author Georgiy Korneev (kgeorgiy@kgeorgiy.info) - */ -@FunctionalInterface -public interface ListParser { - ListExpression parse(String expression, List variables); -} diff --git a/java/expression/parser/Operations.java b/java/expression/parser/Operations.java deleted file mode 100644 index 3266560..0000000 --- a/java/expression/parser/Operations.java +++ /dev/null @@ -1,148 +0,0 @@ -package expression.parser; - -import expression.ToMiniString; -import expression.common.ExpressionKind; -import expression.common.Reason; - -import java.math.BigInteger; -import java.util.function.*; -import java.util.stream.LongStream; - -/** - * @author Georgiy Korneev (kgeorgiy@kgeorgiy.info) - */ -public final class Operations { - // === Base - - public static final Operation NEGATE = unary("-", 1, a -> -a); - @SuppressWarnings("Convert2MethodRef") - public static final Operation ADD = binary("+", 1600, (a, b) -> a + b); - public static final Operation SUBTRACT = binary("-", 1602, (a, b) -> a - b); - public static final Operation MULTIPLY = binary("*", 2001, (a, b) -> a * b); - public static final Operation DIVIDE = binary("/", 2002, (a, b) -> b == 0 ? Reason.DBZ.error() : a / b); - - - // === MinMax - public static final Operation MIN = binary("min", 401, Math::min); - public static final Operation MAX = binary("max", 401, Math::max); - - - // === Reverse - - private static Operation digits(final String name, final boolean mask, final int r, final LongBinaryOperator q) { - return unary(name, 1, v -> LongStream.iterate(mask ? v & 0xffff_ffffL : v, n -> n != 0, n -> n / r) - .map(n -> n % r) - .reduce(0, q)); - } - - public static final Operation REVERSE = digits("reverse", false, 10, (a, b) -> a * 10 + b); - - - // === Digits - public static final Operation DIGITS = digits("digits", false, 10, Long::sum); - - - // === Floor and Ceiling - - private static long floor(final long a) { - return (a >= 0 ? a : a - FLOOR_CEILING_STEP + 1) / FLOOR_CEILING_STEP * FLOOR_CEILING_STEP; - } - - private static long ceiling(final long a) { - return (a >= 0 ? a + FLOOR_CEILING_STEP - 1: a) / FLOOR_CEILING_STEP * FLOOR_CEILING_STEP; - } - - public static final int FLOOR_CEILING_STEP = 1000; - public static final Operation FLOOR = unary("floor", 1, Operations::floor); - public static final Operation CEILING = unary("ceiling", 1, Operations::ceiling); - - // === Set, Clear - - @SuppressWarnings("IntegerMultiplicationImplicitCastToLong") - public static final Operation SET = binary("set", 202, (a, b) -> a | (1 << b)); - @SuppressWarnings("IntegerMultiplicationImplicitCastToLong") - public static final Operation CLEAR = binary("clear", 202, (a, b) -> a & ~(1 << b)); - - - // === Pow, Log - public static final Operation POW_O = binary("**", 2402, (a, b) -> - b < 0 ? 1 : BigInteger.valueOf(a).modPow(BigInteger.valueOf(b), BigInteger.valueOf(1L << 32)).intValue()); - public static final Operation LOG_O = binary("//", 2402, (a, b) -> - a == 0 && b > 0 ? Integer.MIN_VALUE : - a <= 0 || b <= 0 || a == 1 && b == 1 ? 0 : - a > 1 && b == 1 ? Integer.MAX_VALUE - : LongStream.iterate(b, v -> v <= a, v -> v * b).count() - ); - - private static final Reason INVALID_POW = new Reason("Invalid power"); - public static final Operation POW = binary("**", 2402, Operations::powC); - - private static long powC(final long a, final long b) { - if (b < 0 || a == 0 && b == 0) { - return INVALID_POW.error(); - } - if (Math.abs(a) > 1 && b > 32) { - return Reason.OVERFLOW.error(); - } - final BigInteger result = BigInteger.valueOf(a).pow((int) b); - if (result.compareTo(BigInteger.valueOf(Integer.MIN_VALUE)) < 0 || BigInteger.valueOf(Integer.MAX_VALUE).compareTo(result) < 0) { - return Reason.OVERFLOW.error(); - } - return result.intValue(); - } - - private static final Reason INVALID_LOG = new Reason("Invalid log"); - public static final Operation LOG = binary("//", 2402, (a, b) -> - a <= 0 || b <= 1 ? INVALID_LOG.error() : (int) (Math.log(a) / Math.log(b))); - - - // Pow2, Log2 - - private static final Reason NEG_LOG = new Reason("Logarithm of negative value"); - public static final Operation LOG_2 - = unary("log₂", 1, NEG_LOG.less(1, a-> (long) (Math.log(a) / Math.log(2)))); - - private static final Reason NEG_POW = new Reason("Exponentiation to negative power"); - public static final Operation POW_2 - = unary("pow₂", 1, NEG_POW.less(0, Reason.OVERFLOW.greater(31, a -> (long) Math.pow(2, a)))); - - - // === High, Low - public static final Operation HIGH = unary("high", 1, v -> Integer.highestOneBit((int) v)); - public static final Operation LOW = unary("low", 1, v -> Integer.lowestOneBit((int) v)); - - // === Common - - private Operations() { - } - - public static Operation unary(final String name, final int priority, final LongUnaryOperator op) { - return unary(name, priority, (a, c) -> op.applyAsLong(a)); - } - - public static Operation unary(final String left, final String right, final LongUnaryOperator op) { - return unary(left, right, (a, c) -> op.applyAsLong(a)); - } - - public static Operation unary(final String name, final int priority, final BiFunction op) { - return tests -> tests.unary(name, priority, op); - } - - public static Operation unary(final String left, final String right, final BiFunction op) { - return tests -> tests.unary(left, right, op); - } - - public static Operation binary(final String name, final int priority, final LongBinaryOperator op) { - return tests -> tests.binary(name, priority, op); - } - - public static Operation kind( - final ExpressionKind kind, - final ParserTestSet.Parser parser - ) { - return factory -> factory.kind(kind, parser); - } - - @FunctionalInterface - public interface Operation extends Consumer {} -} diff --git a/java/expression/parser/ParserTest.java b/java/expression/parser/ParserTest.java deleted file mode 100644 index c7b20bd..0000000 --- a/java/expression/parser/ParserTest.java +++ /dev/null @@ -1,31 +0,0 @@ -package expression.parser; - -import base.Selector; -import expression.ListExpression; - -import static expression.parser.Operations.*; - -/** - * @author Georgiy Korneev (kgeorgiy@kgeorgiy.info) - */ -public final class ParserTest { - private static final ExpressionParser PARSER = new ExpressionParser(); - private static final Operations.Operation LIST = kind(ListExpression.KIND, PARSER::parse); - - // === Common - - public static final Selector SELECTOR = Selector.composite(ParserTest.class, ParserTester::new, "easy", "hard") - .variant("Base", LIST, ADD, SUBTRACT, MULTIPLY, DIVIDE, NEGATE) - .variant("3637", MIN, MAX, REVERSE) - .variant("3839", MIN, MAX, REVERSE, DIGITS) - .variant("3435", FLOOR, CEILING, SET, CLEAR) - .variant("3233", FLOOR, CEILING) - .selector(); - - private ParserTest() { - } - - public static void main(final String... args) { - SELECTOR.main(args); - } -} diff --git a/java/expression/parser/ParserTestSet.java b/java/expression/parser/ParserTestSet.java deleted file mode 100644 index c70f039..0000000 --- a/java/expression/parser/ParserTestSet.java +++ /dev/null @@ -1,236 +0,0 @@ -package expression.parser; - -import base.*; -import expression.ToMiniString; -import expression.common.*; - -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.function.Consumer; -import java.util.regex.Pattern; -import java.util.stream.Collectors; -import java.util.stream.IntStream; - -/** - * @author Georgiy Korneev (kgeorgiy@kgeorgiy.info) - */ -public class ParserTestSet { - private static final int D = 5; - - private static final List TEST_VALUES = new ArrayList<>(); - static { - Functional.addRange(TEST_VALUES, D, D); - Functional.addRange(TEST_VALUES, D, -D); - } - - public static final List CONSTS - = List.of(0, 1, -1, 4, -4, 10, -10, 30, -30, 100, -100, Integer.MAX_VALUE, Integer.MIN_VALUE); - - protected final ParserTester tester; - protected final ParsedKind kind; - private final boolean safe; - - protected final TestCounter counter; - - public ParserTestSet(final ParserTester tester, final ParsedKind kind) { - this(tester, kind, true); - } - - protected ParserTestSet(final ParserTester tester, final ParsedKind kind, final boolean safe) { - this.tester = tester; - this.kind = kind; - this.safe = safe; - - counter = tester.getCounter(); - } - - private void examples(final TestGenerator generator) { - example(generator, "$x+2", (x, y, z) -> x + 2); - example(generator, "2-$y", (x, y, z) -> 2 - y); - example(generator, " 3* $z ", (x, y, z) -> 3 * z); - example(generator, "$x/ - 2", (x, y, z) -> -x / 2); - example(generator, "$x*$y+($z-1 )/10", (x, y, z) -> x * y + (int) (z - 1) / 10); - example(generator, "-(-(-\t\t-5 + 16 *$x*$y) + 1 * $z) -(((-11)))", (x, y, z) -> -(-(5 + 16 * x * y) + z) + 11); - example(generator, "" + Integer.MAX_VALUE, (x, y, z) -> (long) Integer.MAX_VALUE); - example(generator, "" + Integer.MIN_VALUE, (x, y, z) -> (long) Integer.MIN_VALUE); - example(generator, "$x--$y--$z", (x, y, z) -> x + y + z); - example(generator, "((2+2))-0/(--2)*555", (x, y, z) -> 4L); - example(generator, "$x-$x+$y-$y+$z-($z)", (x, y, z) -> 0L); - example(generator, "(".repeat(300) + "$x + $y + (-10*-$z)" + ")".repeat(300), (x, y, z) -> x + y + 10 * z); - example(generator, "$x / $y / $z", (x, y, z) -> y == 0 || z == 0 ? Reason.DBZ.error() : (int) x / (int) y / z); - } - - private void example(final TestGenerator generator, final String expr, final ExampleExpression expression) { - final List names = Functional.map(generator.variables(3), Pair::first); - final TExpression expected = vars -> expression.evaluate(vars.get(0), vars.get(1), vars.get(2)); - - counter.test(() -> { - final String mangled = mangle(expr, names); - final E parsed = parse(mangled, names, true); - Functional.allValues(TEST_VALUES, 3).forEach(values -> check(expected, parsed, names, values, mangled)); - }); - } - - protected static String mangle(final String expr, final List names) { - return expr - .replace("$x", names.get(0)) - .replace("$y", names.get(1)) - .replace("$z", names.get(2)); - } - - protected void test() { - final TestGenerator generator = tester.generator.build(kind.kind.variables()); - final Renderer renderer = tester.renderer.build(); - final Consumer> consumer = test -> test(renderer, test); - counter.scope("Basic tests", () -> generator.testBasic(consumer)); - counter.scope("Handmade tests", () -> examples(generator)); - counter.scope("Random tests", () -> generator.testRandom(counter, 1, consumer)); - } - - private void test(final Renderer renderer, final TestGenerator.Test test) { - final Expr expr = test.expr; - final List> vars = expr.variables(); - final List variables = Functional.map(vars, Pair::first); - final String full = test.render(NodeRenderer.FULL); - final String mini = test.render(NodeRenderer.MINI); - - final E fullParsed = parse(test, variables, NodeRenderer.FULL); - final E miniParsed = parse(test, variables, NodeRenderer.MINI); - final E safeParsed = parse(test, variables, NodeRenderer.SAME); - - checkToString(full, mini, "base", fullParsed); - if (tester.mode() > 0) { - counter.test(() -> Asserts.assertEquals("mini.toMiniString", mini, miniParsed.toMiniString())); - counter.test(() -> Asserts.assertEquals("safe.toMiniString", mini, safeParsed.toMiniString())); - } - checkToString(full, mini, "extraParentheses", parse(test, variables, NodeRenderer.FULL_EXTRA)); - checkToString(full, mini, "noSpaces", parse(removeSpaces(full), variables, false)); - checkToString(full, mini, "extraSpaces", parse(extraSpaces(full), variables, false)); - - final TExpression expected = renderer.render( - Expr.of( - expr.node(), - Functional.map(vars, (i, var) -> Pair.of(var.first(), args -> args.get(i))) - ), - Unit.INSTANCE - ); - - check(expected, fullParsed, variables, tester.random().random(variables.size(), ExtendedRandom::nextInt), full); - if (this.safe) { - final String safe = test.render(NodeRenderer.SAME); - check(expected, safeParsed, variables, tester.random().random(variables.size(), ExtendedRandom::nextInt), safe); - } - } - - private E parse( - final TestGenerator.Test test, - final List variables, - final NodeRenderer.Settings settings - ) { - return parse(test.render(settings.withParens(tester.parens)), variables, false); - } - - private static final String LOOKBEHIND = "(?*/+=!-])"; - private static final String LOOKAHEAD = "(?![a-zA-Z0-9<>*/])"; - private static final Pattern SPACES = Pattern.compile(LOOKBEHIND + " | " + LOOKAHEAD + "|" + LOOKAHEAD + LOOKBEHIND); - private String extraSpaces(final String expression) { - return SPACES.matcher(expression).replaceAll(r -> tester.random().randomString( - ExtendedRandom.SPACES, - tester.random().nextInt(5) - )); - } - - private static String removeSpaces(final String expression) { - return SPACES.matcher(expression).replaceAll(""); - } - - private void checkToString(final String full, final String mini, final String context, final ToMiniString parsed) { - counter.test(() -> { - assertEquals(context + ".toString", full, full, parsed.toString()); - if (tester.mode() > 0) { - assertEquals(context + ".toMiniString", full, mini, parsed.toMiniString()); - } - }); - } - - private static void assertEquals( - final String context, - final String original, - final String expected, - final String actual - ) { - final String message = String.format("%s:%n original `%s`,%n expected `%s`,%n actual `%s`", - context, original, expected, actual); - Asserts.assertTrue(message, Objects.equals(expected, actual)); - } - - private Either eval(final TExpression expression, final List vars) { - return Reason.eval(() -> tester.cast(expression.evaluate(vars))); - } - - protected E parse(final String expression, final List variables, final boolean reparse) { - return counter.testV(() -> { - final E parsed = counter.testV(() -> counter.call("parse", - () -> kind.parse(expression, variables))); - if (reparse) { - counter.testV(() -> counter.call("parse", () -> kind.parse(parsed.toString(), variables))); - } - return parsed; - }); - } - - private void check( - final TExpression expectedExpression, - final E expression, - final List variables, - final List values, - final String unparsed - ) { - counter.test(() -> { - final Either answer = eval(expectedExpression, values); - final String args = IntStream.range(0, variables.size()) - .mapToObj(i -> variables.get(i) + "=" + values.get(i)) - .collect(Collectors.joining(", ")); - final String message = String.format("f(%s)%n\twhere f=%s%n\tyour f=%s", args, unparsed, expression); - try { - final C actual = kind.kind.evaluate(expression, variables, kind.kind.fromInts(values)); - counter.checkTrue(answer.isRight(), "Error expected for f(%s)%n\twhere f=%s%n\tyour f=%s", args, unparsed, expression); - Asserts.assertEquals(message, answer.getRight(), actual); - } catch (final Exception e) { - if (answer.isRight()) { - counter.fail(e, "No error expected for %s", message); - } - } - }); - } - - @FunctionalInterface - public interface TExpression { - long evaluate(List vars); - } - - @FunctionalInterface - protected interface ExampleExpression { - long evaluate(long x, long y, long z); - } - - /** - * @author Georgiy Korneev (kgeorgiy@kgeorgiy.info) - */ - public record ParsedKind(ExpressionKind kind, Parser parser) { - public E parse(final String expression, final List variables) throws Exception { - return parser.parse(expression, variables); - } - - @Override - public String toString() { - return kind.toString(); - } - } - - @FunctionalInterface - public interface Parser { - E parse(final String expression, final List variables) throws Exception; - } -} diff --git a/java/expression/parser/ParserTester.java b/java/expression/parser/ParserTester.java deleted file mode 100644 index 059acf2..0000000 --- a/java/expression/parser/ParserTester.java +++ /dev/null @@ -1,76 +0,0 @@ -package expression.parser; - -import base.ExtendedRandom; -import base.TestCounter; -import base.Tester; -import base.Unit; -import expression.ToMiniString; -import expression.common.*; - -import java.util.ArrayList; -import java.util.List; -import java.util.function.BiFunction; -import java.util.function.LongBinaryOperator; -import java.util.function.LongToIntFunction; - -/** - * @author Georgiy Korneev (kgeorgiy@kgeorgiy.info) - */ -public class ParserTester extends Tester { - /* package-private */ final TestGeneratorBuilder generator; - /* package-private */ final Renderer.Builder renderer; - private final List> kinds = new ArrayList<>(); - /* package-private */ final List parens = new ArrayList<>(List.of(NodeRenderer.paren("(", ")"))); - - public ParserTester(final TestCounter counter) { - super(counter); - renderer = Renderer.builder(c -> vars -> c); - final ExtendedRandom random = counter.random(); - generator = new TestGeneratorBuilder<>(random, random::nextInt, ParserTestSet.CONSTS, true); - } - - public void unary(final String name, final int priority, final BiFunction op) { - generator.unary(name, priority); - renderer.unary(name, (unit, a) -> vars -> cast(op.apply(a.evaluate(vars), this::cast))); - } - - public void unary(final String left, final String right, final BiFunction op) { - generator.unary(left, right); - renderer.unary(left, (unit, a) -> vars -> cast(op.apply(a.evaluate(vars), this::cast))); - } - - public void binary(final String name, final int priority, final LongBinaryOperator op) { - generator.binary(name, priority); - renderer.binary(name, (unit, a, b) -> vars -> cast(op.applyAsLong(a.evaluate(vars), b.evaluate(vars)))); - } - - void kind(final ExpressionKind kind, final ParserTestSet.Parser parser) { - kinds.add(new ParserTestSet.ParsedKind<>(kind, parser)); - } - - @Override - public void test() { - for (final ParserTestSet.ParsedKind kind : kinds) { - counter.scope(kind.toString(), () -> test(kind)); - } - } - - protected void test(final ParserTestSet.ParsedKind kind) { - new ParserTestSet<>(this, kind).test(); - } - - public TestCounter getCounter() { - return counter; - } - - protected int cast(final long value) { - return (int) value; - } - - public void parens(final String... parens) { - assert parens.length % 2 == 0 : "Parens should come in pairs"; - for (int i = 0; i < parens.length; i += 2) { - this.parens.add(NodeRenderer.paren(parens[i], parens[i + 1])); - } - } -} diff --git a/java/expression/parser/package-info.java b/java/expression/parser/package-info.java deleted file mode 100644 index 1f7a1e9..0000000 --- a/java/expression/parser/package-info.java +++ /dev/null @@ -1,7 +0,0 @@ -/** - * Tests for Expressions Parsing homework - * of Introduction to Programming course. - * - * @author Georgiy Korneev (kgeorgiy@kgeorgiy.info) - */ -package expression.parser; \ No newline at end of file diff --git a/java/markup/MarkupListTest.java b/java/markup/MarkupListTest.java deleted file mode 100644 index fbc8b79..0000000 --- a/java/markup/MarkupListTest.java +++ /dev/null @@ -1,248 +0,0 @@ -package markup; - -import base.Asserts; -import base.Selector; -import base.TestCounter; - -import java.lang.reflect.ParameterizedType; -import java.lang.reflect.Type; -import java.lang.reflect.WildcardType; -import java.util.*; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.function.Predicate; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -/** - * @author Georgiy Korneev (kgeorgiy@kgeorgiy.info) - */ -public final class MarkupListTest { - public static final Consumer VARIANT = MarkupListTest.variant( - "Tex", Map.ofEntries( - Map.entry("

", "\\par{}"), Map.entry("

", ""), - Map.entry("", "\\emph{"), Map.entry("", "}"), - Map.entry("", "\\textbf{"), Map.entry("", "}"), - Map.entry("", "\\textst{"), Map.entry("", "}"), - Map.entry("
    ", "\\begin{itemize}"), Map.entry("
", "\\end{itemize}"), - Map.entry("
    ", "\\begin{enumerate}"), Map.entry("
", "\\end{enumerate}"), - Map.entry("
  • ", "\\item "), Map.entry("
  • ", "") - ) - ); - - - public static final Selector SELECTOR = new Selector(MarkupListTest.class) - .variant("3637", VARIANT) - .variant("3839", VARIANT) - .variant("4142", VARIANT) - .variant("4749", VARIANT) - - ; - - private MarkupListTest() { - } - - public static Consumer variant(final String name, final Map mapping) { - return MarkupTester.variant(MarkupListTest::test, name, mapping); - } - - private static void test(final MarkupTester.Checker checker) { - final Paragraph paragraph0 = new Paragraph(List.of(new Text("hello"))); - final String paragraph0Markup = "

    hello

    "; - - final Paragraph paragraph1 = new Paragraph(List.of( - new Strong(List.of( - new Text("1"), - new Strikeout(List.of( - new Text("2"), - new Emphasis(List.of( - new Text("3"), - new Text("4") - )), - new Text("5") - )), - new Text("6") - )) - )); - final String paragraph1Markup = "

    123456

    "; - - final Paragraph paragraph2 = new Paragraph(List.of(new Strong(List.of( - new Text("sdq"), - new Strikeout(List.of(new Emphasis(List.of(new Text("r"))), new Text("vavc"))), - new Text("zg"))) - )); - final String paragraph2Markup = "

    sdqrvavczg

    "; - - checker.test(paragraph0, paragraph0Markup); - checker.test(paragraph1, paragraph1Markup); - checker.test(paragraph2, paragraph2Markup); - - final ListItem li1 = new ListItem(List.of(new Paragraph(List.of(new Text("1.1"))), new Paragraph(List.of(new Text("1.2"))))); - final String li1Markup = "

    1.1

    1.2

    "; - final ListItem li2 = new ListItem(List.of(new Paragraph(List.of(new Text("2"))))); - final String li2Markup = "

    2

    "; - final ListItem pli1 = new ListItem(List.of(paragraph1)); - final ListItem pli2 = new ListItem(List.of(paragraph2)); - - final ListItem nestedUl = new ListItem(List.of(ul(li1, li2))); - final String nestedUlMarkup = ul(li1Markup, li2Markup); - - checker.test(ul(li1), ul(li1Markup)); - checker.test(ul(li2), ul(li2Markup)); - checker.test(ul(pli1), ul(paragraph1Markup)); - checker.test(ul(pli2), ul(paragraph2Markup)); - checker.test(ul(li1, li2), nestedUlMarkup); - checker.test(ul(pli1, pli2), ul(paragraph1Markup, paragraph2Markup)); - checker.test(ul(nestedUl), ul(nestedUlMarkup)); - - final ListItem nestedOl = new ListItem(List.of(ol(li1, li2))); - final String nestedOlMarkup = ol(li1Markup, li2Markup); - checker.test(ol(li1), ol(li1Markup)); - checker.test(ol(li2), ol(li2Markup)); - checker.test(ol(pli1), ol(paragraph1Markup)); - checker.test(ol(pli2), ol(paragraph2Markup)); - checker.test(ol(li1, li2), nestedOlMarkup); - checker.test(ol(pli1, pli2), ol(paragraph1Markup, paragraph2Markup)); - checker.test(ol(nestedOl), ol(nestedOlMarkup)); - - checker.test(ul(nestedUl, nestedOl), ul(nestedUlMarkup, nestedOlMarkup)); - checker.test(ol(nestedUl, nestedOl), ol(nestedUlMarkup, nestedOlMarkup)); - - checker.test( - ul(nestedUl, nestedOl, pli1, pli2), - ul(nestedUlMarkup, nestedOlMarkup, paragraph1Markup, paragraph2Markup) - ); - checker.test( - ol(nestedUl, nestedOl, pli1, pli2), - ol(nestedUlMarkup, nestedOlMarkup, paragraph1Markup, paragraph2Markup) - ); - - checker.test( - new Paragraph(List.of(new Strikeout(List.of(new Strong(List.of(new Strikeout(List.of(new Emphasis(List.of(new Strikeout(List.of(new Text("е"), new Text("г"), new Text("ц"))), new Strong(List.of(new Text("щэш"), new Text("игепы"), new Text("хм"))), new Strikeout(List.of(new Text("б"), new Text("е"))))), new Strong(List.of(new Strong(List.of(new Text("ю"), new Text("дърб"), new Text("еи"))), new Emphasis(List.of(new Text("зр"), new Text("дуаужш"), new Text("ш"))), new Strong(List.of(new Text("рб"), new Text("щ"))))), new Text("a"))), new Strikeout(List.of(new Text("no"), new Text("ddw"), new Strong(List.of(new Emphasis(List.of(new Text("щ"), new Text("ча"), new Text("эгфш"))), new Strikeout(List.of(new Text("фяи"), new Text("штел"), new Text("н"))), new Strikeout(List.of(new Text("ту"), new Text("ьъг"))))))), new Emphasis(List.of(new Emphasis(List.of(new Text("tc"), new Strong(List.of(new Text("щ"), new Text("э"), new Text("то"))), new Strong(List.of(new Text("а"), new Text("ц"))))), new Emphasis(List.of(new Text("hld"), new Emphasis(List.of(new Text("ыо"), new Text("яще"), new Text("лэ"))), new Text("i"))), new Text("tm"))))), new Emphasis(List.of(new Text("q"), new Emphasis(List.of(new Text("zn"), new Strong(List.of(new Text("mnphd"), new Strong(List.of(new Text("г"), new Text("вй"), new Text("шш"))), new Strong(List.of(new Text("з"), new Text("ввъ"))))), new Strikeout(List.of(new Emphasis(List.of(new Text("у"), new Text("в"), new Text("у"))), new Strikeout(List.of(new Text("лдяр"), new Text("зоъ"), new Text("эн"))), new Strikeout(List.of(new Text("в"), new Text("м"))))))), new Strikeout(List.of(new Text("cqqzbhtn"), new Text("i"), new Strong(List.of(new Text("i"), new Strikeout(List.of(new Text("э"), new Text("як"))), new Text("i"))))))), new Text("ef"))), new Strikeout(List.of(new Strikeout(List.of(new Strong(List.of(new Emphasis(List.of(new Strong(List.of(new Text("шец"), new Text("ю"), new Text("дрк"))), new Strikeout(List.of(new Text("е"), new Text("мь"), new Text("б"))), new Strong(List.of(new Text("еп"), new Text("ряэк"))))), new Strong(List.of(new Text("t"), new Emphasis(List.of(new Text("сы"), new Text("в"), new Text("к"))), new Text("rf"))), new Text("x"))), new Emphasis(List.of(new Emphasis(List.of(new Emphasis(List.of(new Text("юд"), new Text("чх"), new Text("яжюи"))), new Emphasis(List.of(new Text("и"), new Text("п"), new Text("вх"))), new Text("mf"))), new Emphasis(List.of(new Strong(List.of(new Text("шб"), new Text("вс"), new Text("е"))), new Strong(List.of(new Text("т"), new Text("шж"), new Text("ину"))), new Strong(List.of(new Text("ыа"), new Text("ьскю"))))), new Text("x"))), new Strikeout(List.of(new Emphasis(List.of(new Strong(List.of(new Text("в"), new Text("зыйгг"), new Text("о"))), new Strikeout(List.of(new Text("ок"), new Text("уч"), new Text("л"))), new Text("v"))), new Emphasis(List.of(new Strong(List.of(new Text("н"), new Text("ъчжфзтодг"), new Text("кыч"))), new Strikeout(List.of(new Text("вд"), new Text("лпбзс"), new Text("гщ"))), new Emphasis(List.of(new Text("ъ"), new Text("й"))))), new Text("n"))))), new Strong(List.of(new Strong(List.of(new Emphasis(List.of(new Strong(List.of(new Text("ю"), new Text("сдям"), new Text("ш"))), new Strong(List.of(new Text("ц"), new Text("еящж"), new Text("шн"))), new Text("upg"))), new Text("d"), new Strikeout(List.of(new Text("xu"), new Strikeout(List.of(new Text("кл"), new Text("еок"), new Text("с"))), new Strong(List.of(new Text("а"), new Text("ь"))))))), new Strong(List.of(new Strikeout(List.of(new Text("zn"), new Text("syb"), new Strong(List.of(new Text("ъзюкмц"), new Text("ндюз"))))), new Strong(List.of(new Strikeout(List.of(new Text("н"), new Text("с"), new Text("ь"))), new Strikeout(List.of(new Text("зьуес"), new Text("к"), new Text("и"))), new Strong(List.of(new Text("тв"), new Text("у"))))), new Strikeout(List.of(new Strong(List.of(new Text("ы"), new Text("г"), new Text("гм"))), new Strong(List.of(new Text("сыр"), new Text("я"), new Text("т"))), new Emphasis(List.of(new Text("ь"), new Text("махыы"))))))), new Text("k"))), new Text("q"))), new Strikeout(List.of(new Text("b"), new Text("o"), new Emphasis(List.of(new Strong(List.of(new Strikeout(List.of(new Strong(List.of(new Text("х"), new Text("йз"), new Text("ж"))), new Text("udlh"), new Strikeout(List.of(new Text("чъ"), new Text("с"))))), new Strong(List.of(new Strong(List.of(new Text("ю"), new Text("т"), new Text("яъайл"))), new Strong(List.of(new Text("х"), new Text("ри"), new Text("в"))), new Strong(List.of(new Text("щ"), new Text("вт"))))), new Text("m"))), new Text("vzb"), new Strong(List.of(new Text("oi"), new Text("r"), new Text("inpz"))))))))), - "

    егцщэшигепыхмбеюдърбеизрдуаужшшрбщanoddwщчаэгфшфяиштелнтуьъгtcщэтоацhldыоящелэitmqznmnphdгвйшшзввъувулдярзоъэнвмcqqzbhtniiэякiefшецюдркемьбепряэкtсывкrfxюдчхяжюиипвхmfшбвсетшжинуыаьскюxвзыйггоокучлvнъчжфзтодгкычвдлпбзсгщъйnюсдямшцеящжшнupgdxuклеоксаьznsybъзюкмцндюзнсьзьуескитвуыггмсырятьмахыыkqboхйзжudlhчъсютяъайлхривщвтmvzboirinpz

    " - ); - - checker.test( - new OrderedList(List.of(new ListItem(List.of(new OrderedList(List.of(new ListItem(List.of(new OrderedList(List.of()), new Paragraph(List.of(new Text("е"))), new Paragraph(List.of(new Text("х"))))), new ListItem(List.of(new OrderedList(List.of()), new OrderedList(List.of()), new Paragraph(List.of(new Text("эш"))))), new ListItem(List.of(new UnorderedList(List.of()), new Paragraph(List.of(new Text("цць"))))), new ListItem(List.of(new UnorderedList(List.of()), new Paragraph(List.of(new Text("м"))))))), new UnorderedList(List.of(new ListItem(List.of(new OrderedList(List.of()), new OrderedList(List.of()), new OrderedList(List.of()))), new ListItem(List.of(new Paragraph(List.of(new Text("ю"))), new UnorderedList(List.of()), new UnorderedList(List.of()))), new ListItem(List.of(new OrderedList(List.of()), new OrderedList(List.of()))), new ListItem(List.of(new UnorderedList(List.of()), new UnorderedList(List.of()))))), new Paragraph(List.of(new Emphasis(List.of(new Emphasis(List.of(new Text("узр"))), new Text("i"), new Emphasis(List.of(new Text("аужш"))), new Text("ш"))), new Strong(List.of(new Text("c"), new Strikeout(List.of(new Text("щ"))), new Text("a"), new Text("з"))), new Strong(List.of(new Emphasis(List.of(new Text("ь"))), new Text("ddw"), new Text("зщ"), new Text("ча"))), new Emphasis(List.of(new Strong(List.of(new Text("гфш"))), new Strikeout(List.of(new Text("фяи"))), new Text("штел"), new Text("н"))))), new OrderedList(List.of(new ListItem(List.of(new UnorderedList(List.of()), new OrderedList(List.of()), new UnorderedList(List.of()))), new ListItem(List.of(new OrderedList(List.of()), new Paragraph(List.of(new Text("юцщ"))), new UnorderedList(List.of()))), new ListItem(List.of(new UnorderedList(List.of()), new UnorderedList(List.of()))), new ListItem(List.of(new OrderedList(List.of()), new Paragraph(List.of(new Text("э"))))))))), new ListItem(List.of(new OrderedList(List.of(new ListItem(List.of(new UnorderedList(List.of()), new OrderedList(List.of()), new Paragraph(List.of(new Text("ж"))))), new ListItem(List.of(new OrderedList(List.of()), new Paragraph(List.of(new Text("ыеж"))), new Paragraph(List.of(new Text("ыо"))))), new ListItem(List.of(new Paragraph(List.of(new Text("ще"))), new Paragraph(List.of(new Text("щш"))))), new ListItem(List.of(new UnorderedList(List.of()), new OrderedList(List.of()))))), new OrderedList(List.of(new ListItem(List.of(new Paragraph(List.of(new Text("щосз"))), new OrderedList(List.of()), new UnorderedList(List.of()))), new ListItem(List.of(new UnorderedList(List.of()), new OrderedList(List.of()), new UnorderedList(List.of()))), new ListItem(List.of(new UnorderedList(List.of()), new UnorderedList(List.of()))), new ListItem(List.of(new Paragraph(List.of(new Text("сс"))), new UnorderedList(List.of()))))), new Paragraph(List.of(new Text("yu"), new Text("w"), new Text("ghtry"), new Emphasis(List.of(new Strikeout(List.of(new Text("прф"))), new Emphasis(List.of(new Text("р"))), new Text("я"), new Text("я"))))), new Paragraph(List.of(new Text("w"), new Strong(List.of(new Text("k"), new Emphasis(List.of(new Text("н"))), new Strikeout(List.of(new Text("в"))), new Text("м"))), new Strikeout(List.of(new Text("cqqzbhtn"), new Text("i"), new Text("м"), new Text("ю"))), new Strikeout(List.of(new Strong(List.of(new Text("ш"))), new Strong(List.of(new Text("к"))), new Text("ж"), new Text("б"))))))), new ListItem(List.of(new UnorderedList(List.of(new ListItem(List.of(new OrderedList(List.of()), new OrderedList(List.of()), new UnorderedList(List.of()))), new ListItem(List.of(new UnorderedList(List.of()), new OrderedList(List.of()), new UnorderedList(List.of()))), new ListItem(List.of(new OrderedList(List.of()), new UnorderedList(List.of()))), new ListItem(List.of(new UnorderedList(List.of()), new UnorderedList(List.of()))))), new UnorderedList(List.of(new ListItem(List.of(new UnorderedList(List.of()), new OrderedList(List.of()), new OrderedList(List.of()))), new ListItem(List.of(new UnorderedList(List.of()), new Paragraph(List.of(new Text("е"))), new UnorderedList(List.of()))), new ListItem(List.of(new OrderedList(List.of()), new UnorderedList(List.of()))), new ListItem(List.of(new Paragraph(List.of(new Text("ед"))), new UnorderedList(List.of()))))), new OrderedList(List.of(new ListItem(List.of(new OrderedList(List.of()), new OrderedList(List.of()), new Paragraph(List.of(new Text("п"))))), new ListItem(List.of(new UnorderedList(List.of()), new Paragraph(List.of(new Text("э"))), new UnorderedList(List.of()))), new ListItem(List.of(new UnorderedList(List.of()), new UnorderedList(List.of()))), new ListItem(List.of(new OrderedList(List.of()), new Paragraph(List.of(new Text("к"))))))), new Paragraph(List.of(new Strong(List.of(new Strong(List.of(new Text("с"))), new Text("x"), new Emphasis(List.of(new Text("йюд"))), new Text("чх"))), new Strikeout(List.of(new Strong(List.of(new Text("жюи"))), new Emphasis(List.of(new Text("и"))), new Strong(List.of(new Text("ьмт"))), new Text("йц"))), new Emphasis(List.of(new Strong(List.of(new Text("шб"))), new Strong(List.of(new Text("еф"))), new Text("ут"), new Text("шж"))), new Emphasis(List.of(new Emphasis(List.of(new Text("ну"))), new Strong(List.of(new Text("ыа"))), new Text("ьскю"), new Text("чз"))))))), new ListItem(List.of(new UnorderedList(List.of(new ListItem(List.of(new OrderedList(List.of()), new OrderedList(List.of()), new Paragraph(List.of(new Text("ыйгг"))))), new ListItem(List.of(new OrderedList(List.of()), new UnorderedList(List.of()), new Paragraph(List.of(new Text("ф"))))), new ListItem(List.of(new OrderedList(List.of()), new Paragraph(List.of(new Text("ч"))))), new ListItem(List.of(new OrderedList(List.of()), new OrderedList(List.of()))))), new Paragraph(List.of(new Strikeout(List.of(new Emphasis(List.of(new Text("э"))), new Text("amqcfdzrg"), new Emphasis(List.of(new Text("т"))), new Text("з"))), new Text("b"), new Emphasis(List.of(new Strikeout(List.of(new Text("энфны"))), new Strikeout(List.of(new Text("гщ"))), new Text("ы"), new Text("шя"))), new Text("uvpqzhn"))), new UnorderedList(List.of(new ListItem(List.of(new UnorderedList(List.of()), new OrderedList(List.of()), new OrderedList(List.of()))), new ListItem(List.of(new OrderedList(List.of()), new Paragraph(List.of(new Text("ящж"))), new UnorderedList(List.of()))), new ListItem(List.of(new OrderedList(List.of()), new Paragraph(List.of(new Text("цлл"))))), new ListItem(List.of(new OrderedList(List.of()), new Paragraph(List.of(new Text("ъ"))))))), new Paragraph(List.of(new Strong(List.of(new Strong(List.of(new Text("ъ"))), new Strikeout(List.of(new Text("кл"))), new Strikeout(List.of(new Text("счи"))), new Text("ра"))), new Strong(List.of(new Strikeout(List.of(new Text("ь"))), new Text("zn"), new Text("ъ"), new Text("умъъзюкмц"))), new Strikeout(List.of(new Emphasis(List.of(new Text("дюз"))), new Strong(List.of(new Text("эы"))), new Text("и"), new Text("р"))), new Emphasis(List.of(new Strong(List.of(new Text("ьуес"))), new Strikeout(List.of(new Text("йгтв"))), new Text("у"), new Text("еы"))))))))), - "
        1. е

          х

            1. эш

              • цць

                • м

                      1. ю

                                  узрiаужшшcщьddwзщчагфшфяиштелн

                                          1. юцщ

                                                  1. э

                                                      1. ж

                                                        1. ыеж

                                                          ыо

                                                        2. ще

                                                          щш

                                                            1. щосз

                                                                          • сс

                                                                            yuwghtryпрфряя

                                                                            wkнвмcqqzbhtniмюшкжб

                                                                                                        • е

                                                                                                              • ед

                                                                                                                    1. п

                                                                                                                      • э

                                                                                                                              1. к

                                                                                                                              сxйюдчхжюииьмтйцшбефутшжнуыаьскючз

                                                                                                                                  1. ыйгг

                                                                                                                                      • ф

                                                                                                                                        1. ч

                                                                                                                                            эamqcfdzrgтзbэнфныгщышяuvpqzhn

                                                                                                                                                    1. ящж

                                                                                                                                                        1. цлл

                                                                                                                                                          1. ъ

                                                                                                                                                          ъклсчираьznъумъъзюкмцдюзэыирьуесйгтвуеы

                                                                                                                                                        " - ); - - checker.test( - new UnorderedList(List.of(new ListItem(List.of(new OrderedList(List.of(new ListItem(List.of(new OrderedList(List.of()), new Paragraph(List.of(new Text("е"))))), new ListItem(List.of(new UnorderedList(List.of()), new OrderedList(List.of()))), new ListItem(List.of(new OrderedList(List.of()), new OrderedList(List.of()))), new ListItem(List.of(new Paragraph(List.of(new Text("нцйцць"))), new OrderedList(List.of()))), new ListItem(List.of(new Paragraph(List.of(new Text("м"))))))), new UnorderedList(List.of(new ListItem(List.of(new OrderedList(List.of()), new OrderedList(List.of()))), new ListItem(List.of(new OrderedList(List.of()), new Paragraph(List.of(new Text("ю"))))), new ListItem(List.of(new UnorderedList(List.of()), new Paragraph(List.of(new Text("щ"))))), new ListItem(List.of(new UnorderedList(List.of()), new UnorderedList(List.of()))), new ListItem(List.of(new UnorderedList(List.of()))))), new Paragraph(List.of(new Strikeout(List.of(new Emphasis(List.of(new Text("зр"))), new Text("i"), new Text("и"), new Text("г"), new Text("с"))), new Strong(List.of(new Strong(List.of(new Text("шмрб"))), new Strong(List.of(new Text("ь"))), new Text("з"), new Text("з"), new Text("фь"))), new Text("ddw"), new Strong(List.of(new Emphasis(List.of(new Text("щ"))), new Strong(List.of(new Text("втъп"))), new Text("ш"), new Text("ч"), new Text("фяи"))), new Strong(List.of(new Emphasis(List.of(new Text("тел"))), new Text("н"), new Text("ь"), new Text("ддзюцщ"), new Text("пт"))))), new Paragraph(List.of(new Text("n"), new Text("zi"), new Strong(List.of(new Emphasis(List.of(new Text("ж"))), new Text("t"), new Text("ыеж"), new Text("ч"), new Text("г"))), new Text("kwt"), new Strong(List.of(new Strong(List.of(new Text("э"))), new Text("нх"), new Text("уи"), new Text("о"), new Text("п"))))), new UnorderedList(List.of(new ListItem(List.of(new OrderedList(List.of()), new OrderedList(List.of()))), new ListItem(List.of(new Paragraph(List.of(new Text("ж"))), new UnorderedList(List.of()))), new ListItem(List.of(new UnorderedList(List.of()), new UnorderedList(List.of()))), new ListItem(List.of(new Paragraph(List.of(new Text("сс"))))), new ListItem(List.of(new Paragraph(List.of(new Text("т"))))))))), new ListItem(List.of(new UnorderedList(List.of(new ListItem(List.of(new UnorderedList(List.of()), new UnorderedList(List.of()))), new ListItem(List.of(new UnorderedList(List.of()), new UnorderedList(List.of()))), new ListItem(List.of(new OrderedList(List.of()), new OrderedList(List.of()))), new ListItem(List.of(new OrderedList(List.of()), new UnorderedList(List.of()))), new ListItem(List.of(new Paragraph(List.of(new Text("щу"))))))), new OrderedList(List.of(new ListItem(List.of(new OrderedList(List.of()), new Paragraph(List.of(new Text("ир"))))), new ListItem(List.of(new OrderedList(List.of()), new OrderedList(List.of()))), new ListItem(List.of(new Paragraph(List.of(new Text("зоъ"))), new Paragraph(List.of(new Text("е"))))), new ListItem(List.of(new Paragraph(List.of(new Text("в"))), new UnorderedList(List.of()))), new ListItem(List.of(new UnorderedList(List.of()))))), new OrderedList(List.of(new ListItem(List.of(new Paragraph(List.of(new Text("сснюпия"))), new Paragraph(List.of(new Text("щ"))))), new ListItem(List.of(new OrderedList(List.of()), new UnorderedList(List.of()))), new ListItem(List.of(new Paragraph(List.of(new Text("э"))), new OrderedList(List.of()))), new ListItem(List.of(new OrderedList(List.of()), new OrderedList(List.of()))), new ListItem(List.of(new OrderedList(List.of()))))), new UnorderedList(List.of(new ListItem(List.of(new Paragraph(List.of(new Text("м"))), new OrderedList(List.of()))), new ListItem(List.of(new UnorderedList(List.of()), new UnorderedList(List.of()))), new ListItem(List.of(new OrderedList(List.of()), new UnorderedList(List.of()))), new ListItem(List.of(new OrderedList(List.of()), new UnorderedList(List.of()))), new ListItem(List.of(new UnorderedList(List.of()))))), new UnorderedList(List.of(new ListItem(List.of(new UnorderedList(List.of()), new UnorderedList(List.of()))), new ListItem(List.of(new OrderedList(List.of()), new OrderedList(List.of()))), new ListItem(List.of(new Paragraph(List.of(new Text("е"))), new UnorderedList(List.of()))), new ListItem(List.of(new OrderedList(List.of()))), new ListItem(List.of(new UnorderedList(List.of()))))))), new ListItem(List.of(new Paragraph(List.of(new Strong(List.of(new Emphasis(List.of(new Text("п"))), new Text("l"), new Text("р"), new Text("п"), new Text("уерсы"))), new Strikeout(List.of(new Strikeout(List.of(new Text("к"))), new Text("rf"), new Text("екйюд"), new Text("чх"), new Text("яжюи"))), new Emphasis(List.of(new Strikeout(List.of(new Text("кьмт"))), new Strikeout(List.of(new Text("рщюереф"))), new Text("ут"), new Text("шж"), new Text("ину"))), new Strong(List.of(new Strong(List.of(new Text("дгб"))), new Emphasis(List.of(new Text("кю"))), new Text("чз"), new Text("мв"), new Text("зыйгг"))), new Strong(List.of(new Strikeout(List.of(new Text("ш"))), new Text("ф"), new Text("я"), new Text("ч"), new Text("ме"))))), new Paragraph(List.of(new Strikeout(List.of(new Emphasis(List.of(new Text("э"))), new Text("amqcfdzrg"), new Text("кыч"), new Text("к"), new Text("я"))), new Strikeout(List.of(new Strong(List.of(new Text("нфны"))), new Strikeout(List.of(new Text("гщ"))), new Text("ы"), new Text("шя"), new Text("е"))), new Strong(List.of(new Strong(List.of(new Text("ъю"))), new Emphasis(List.of(new Text("яхе"))), new Text("б"), new Text("бц"), new Text("еящж"))), new Text("cn"), new Emphasis(List.of(new Strong(List.of(new Text("як"))), new Text("въ"), new Text("оде"), new Text("кл"), new Text("еок"))))), new Paragraph(List.of(new Strikeout(List.of(new Strong(List.of(new Text("а"))), new Strong(List.of(new Text("иь"))), new Text("аш"), new Text("ъ"), new Text("умъъзюкмц"))), new Strikeout(List.of(new Emphasis(List.of(new Text("дюз"))), new Strong(List.of(new Text("эы"))), new Text("и"), new Text("р"), new Text("зьуес"))), new Strikeout(List.of(new Strikeout(List.of(new Text("и"))), new Strong(List.of(new Text("тв"))), new Text("у"), new Text("еы"), new Text("г"))), new Text("atsui"), new Strikeout(List.of(new Text("y"), new Text("щз"), new Text("н"), new Text("е"), new Text("э"))))), new Paragraph(List.of(new Emphasis(List.of(new Text("o"), new Text("rz"), new Text("к"), new Text("к"), new Text("б"))), new Emphasis(List.of(new Strong(List.of(new Text("ьх"))), new Emphasis(List.of(new Text("ил"))), new Text("ф"), new Text("пмгр"), new Text("и"))), new Emphasis(List.of(new Text("lhovy"), new Emphasis(List.of(new Text("ъайл"))), new Text("ь"), new Text("э"), new Text("п"))), new Strikeout(List.of(new Strong(List.of(new Text("щщ"))), new Strong(List.of(new Text("х"))), new Text("б"), new Text("е"), new Text("к"))), new Emphasis(List.of(new Strikeout(List.of(new Text("чяя"))), new Text("х"), new Text("я"), new Text("р"), new Text("ю"))))), new Paragraph(List.of(new Strikeout(List.of(new Emphasis(List.of(new Text("йл"))), new Emphasis(List.of(new Text("змл"))), new Text("б"), new Text("аж"), new Text("ъ"))), new Strong(List.of(new Strong(List.of(new Text("энян"))), new Emphasis(List.of(new Text("ю"))), new Text("п"), new Text("ымы"), new Text("ешьи"))), new Emphasis(List.of(new Strong(List.of(new Text("к"))), new Strikeout(List.of(new Text("яэ"))), new Text("п"), new Text("юзщ"), new Text("я"))), new Text("w"), new Emphasis(List.of(new Text("se"), new Text("о"), new Text("ъязе"), new Text("гзко"), new Text("ъ"))))))), new ListItem(List.of(new OrderedList(List.of(new ListItem(List.of(new Paragraph(List.of(new Text("ч"))), new Paragraph(List.of(new Text("пз"))))), new ListItem(List.of(new OrderedList(List.of()), new Paragraph(List.of(new Text("й"))))), new ListItem(List.of(new Paragraph(List.of(new Text("лчж"))), new Paragraph(List.of(new Text("чв"))))), new ListItem(List.of(new Paragraph(List.of(new Text("с"))), new OrderedList(List.of()))), new ListItem(List.of(new OrderedList(List.of()))))), new UnorderedList(List.of(new ListItem(List.of(new Paragraph(List.of(new Text("ь"))), new Paragraph(List.of(new Text("ъ"))))), new ListItem(List.of(new OrderedList(List.of()), new UnorderedList(List.of()))), new ListItem(List.of(new UnorderedList(List.of()), new UnorderedList(List.of()))), new ListItem(List.of(new Paragraph(List.of(new Text("вп"))), new Paragraph(List.of(new Text("р"))))), new ListItem(List.of(new OrderedList(List.of()))))), new Paragraph(List.of(new Text("ds"), new Emphasis(List.of(new Strikeout(List.of(new Text("дйгып"))), new Emphasis(List.of(new Text("и"))), new Text("сэ"), new Text("е"), new Text("юо"))), new Emphasis(List.of(new Strikeout(List.of(new Text("бвщ"))), new Text("d"), new Text("ъ"), new Text("ит"), new Text("бщ"))), new Emphasis(List.of(new Text("w"), new Strikeout(List.of(new Text("гсщ"))), new Text("ъ"), new Text("срцч"), new Text("хе"))), new Text("m"))), new OrderedList(List.of(new ListItem(List.of(new UnorderedList(List.of()), new OrderedList(List.of()))), new ListItem(List.of(new UnorderedList(List.of()), new UnorderedList(List.of()))), new ListItem(List.of(new OrderedList(List.of()), new UnorderedList(List.of()))), new ListItem(List.of(new Paragraph(List.of(new Text("е"))), new OrderedList(List.of()))), new ListItem(List.of(new UnorderedList(List.of()))))), new UnorderedList(List.of(new ListItem(List.of(new OrderedList(List.of()), new UnorderedList(List.of()))), new ListItem(List.of(new Paragraph(List.of(new Text("оото"))), new OrderedList(List.of()))), new ListItem(List.of(new OrderedList(List.of()), new OrderedList(List.of()))), new ListItem(List.of(new UnorderedList(List.of()))), new ListItem(List.of(new UnorderedList(List.of()))))))), new ListItem(List.of(new Paragraph(List.of(new Emphasis(List.of(new Emphasis(List.of(new Text("я"))), new Strong(List.of(new Text("сшъ"))), new Text("лм"), new Text("ы"), new Text("рц"))), new Emphasis(List.of(new Strikeout(List.of(new Text("я"))), new Strikeout(List.of(new Text("ъ"))), new Text("п"), new Text("дхдэ"), new Text("щэ"))), new Emphasis(List.of(new Text("dtt"), new Emphasis(List.of(new Text("дрм"))), new Text("в"), new Text("яешц"), new Text("йшй"))), new Strong(List.of(new Strong(List.of(new Text("мив"))), new Text("u"), new Text("у"), new Text("к"), new Text("б"))), new Strikeout(List.of(new Text("c"), new Text("э"), new Text("м"), new Text("п"), new Text("о"))))), new UnorderedList(List.of(new ListItem(List.of(new OrderedList(List.of()), new OrderedList(List.of()))), new ListItem(List.of(new Paragraph(List.of(new Text("х"))), new Paragraph(List.of(new Text("й"))))), new ListItem(List.of(new Paragraph(List.of(new Text("эя"))), new UnorderedList(List.of()))), new ListItem(List.of(new UnorderedList(List.of()), new Paragraph(List.of(new Text("ф"))))), new ListItem(List.of(new OrderedList(List.of()))))), new OrderedList(List.of(new ListItem(List.of(new OrderedList(List.of()), new Paragraph(List.of(new Text("щ"))))), new ListItem(List.of(new Paragraph(List.of(new Text("чи"))), new OrderedList(List.of()))), new ListItem(List.of(new Paragraph(List.of(new Text("к"))), new OrderedList(List.of()))), new ListItem(List.of(new UnorderedList(List.of()), new OrderedList(List.of()))), new ListItem(List.of(new Paragraph(List.of(new Text("ф"))))))), new OrderedList(List.of(new ListItem(List.of(new OrderedList(List.of()), new UnorderedList(List.of()))), new ListItem(List.of(new Paragraph(List.of(new Text("м"))), new Paragraph(List.of(new Text("щцс"))))), new ListItem(List.of(new Paragraph(List.of(new Text("вус"))), new Paragraph(List.of(new Text("я"))))), new ListItem(List.of(new Paragraph(List.of(new Text("кр"))))), new ListItem(List.of(new UnorderedList(List.of()))))), new UnorderedList(List.of(new ListItem(List.of(new UnorderedList(List.of()), new Paragraph(List.of(new Text("я"))))), new ListItem(List.of(new UnorderedList(List.of()), new Paragraph(List.of(new Text("гр"))))), new ListItem(List.of(new Paragraph(List.of(new Text("ж"))), new UnorderedList(List.of()))), new ListItem(List.of(new UnorderedList(List.of()))), new ListItem(List.of(new OrderedList(List.of()))))))))), - "
                                                                                                                                                            1. е

                                                                                                                                                                    1. нцйцць

                                                                                                                                                                      1. м

                                                                                                                                                                            1. ю

                                                                                                                                                                              • щ

                                                                                                                                                                                    зрiигсшмрбьззфьddwщвтъпшчфяителньддзюцщпт

                                                                                                                                                                                    nziжtыежчгkwtэнхуиоп

                                                                                                                                                                                        1. ж

                                                                                                                                                                                              • сс

                                                                                                                                                                                              • т

                                                                                                                                                                                                              • щу

                                                                                                                                                                                                                1. ир

                                                                                                                                                                                                                    1. зоъ

                                                                                                                                                                                                                      е

                                                                                                                                                                                                                    2. в

                                                                                                                                                                                                                        1. сснюпия

                                                                                                                                                                                                                          щ

                                                                                                                                                                                                                            • э

                                                                                                                                                                                                                                    • м

                                                                                                                                                                                                                                                            1. е

                                                                                                                                                                                                                                                                1. пlрпуерсыкrfекйюдчхяжюикьмтрщюерефутшжинудгбкючзмвзыйггшфячме

                                                                                                                                                                                                                                                                  эamqcfdzrgкычкянфныгщышяеъюяхеббцеящжcnяквъодеклеок

                                                                                                                                                                                                                                                                  аиьашъумъъзюкмцдюзэыирзьуеситвуеыгatsuiyщзнеэ

                                                                                                                                                                                                                                                                  orzккбьхилфпмгриlhovyъайльэпщщхбекчяяхярю

                                                                                                                                                                                                                                                                  йлзмлбажъэнянюпымыешьикяэпюзщяwseоъязегзкоъ

                                                                                                                                                                                                                                                                  1. ч

                                                                                                                                                                                                                                                                    пз

                                                                                                                                                                                                                                                                    1. й

                                                                                                                                                                                                                                                                    2. лчж

                                                                                                                                                                                                                                                                      чв

                                                                                                                                                                                                                                                                    3. с

                                                                                                                                                                                                                                                                        • ь

                                                                                                                                                                                                                                                                          ъ

                                                                                                                                                                                                                                                                                • вп

                                                                                                                                                                                                                                                                                  р

                                                                                                                                                                                                                                                                                  dsдйгыписэеюобвщdъитбщwгсщъсрцчхеm

                                                                                                                                                                                                                                                                                              • е

                                                                                                                                                                                                                                                                                                      • оото

                                                                                                                                                                                                                                                                                                              • ясшълмырцяъпдхдэщэdttдрмвяешцйшймивuукбcэмпо

                                                                                                                                                                                                                                                                                                                    1. х

                                                                                                                                                                                                                                                                                                                      й

                                                                                                                                                                                                                                                                                                                    2. эя

                                                                                                                                                                                                                                                                                                                        • ф

                                                                                                                                                                                                                                                                                                                            1. щ

                                                                                                                                                                                                                                                                                                                            2. чи

                                                                                                                                                                                                                                                                                                                              1. к

                                                                                                                                                                                                                                                                                                                                    1. ф

                                                                                                                                                                                                                                                                                                                                        • м

                                                                                                                                                                                                                                                                                                                                          щцс

                                                                                                                                                                                                                                                                                                                                        • вус

                                                                                                                                                                                                                                                                                                                                          я

                                                                                                                                                                                                                                                                                                                                        • кр

                                                                                                                                                                                                                                                                                                                                            • я

                                                                                                                                                                                                                                                                                                                                              • гр

                                                                                                                                                                                                                                                                                                                                              • ж

                                                                                                                                                                                                                                                                                                                                                  " - ); - - checkTypes(); - } - - private static OrderedList ol(final ListItem... items) { - return new OrderedList(List.of(items)); - } - - private static String ol(final String... items) { - return list("ol", items); - } - - private static UnorderedList ul(final ListItem... items) { - return new UnorderedList(List.of(items)); - } - - private static String ul(final String... items) { - return list("ul", items); - } - - private static String list(final String type, final String[] items) { - return "<" + type + ">" + Stream.of(items).map(item -> "
                                                                                                                                                                                                                                                                                                                                                • " + item + "
                                                                                                                                                                                                                                                                                                                                                • ").collect(Collectors.joining()) + ""; - } - - private static Class loadClass(final String name) { - try { - return Class.forName(name); - } catch (final ClassNotFoundException e) { - throw Asserts.error("Cannot find class %s: %s", name, e); - } - } - - private static Map> loadClasses(final String... names) { - return Arrays.stream(names) - .collect(Collectors.toUnmodifiableMap(Function.identity(), name -> loadClass("markup." + name))); - } - - private static void checkTypes() { - final Map> classes = loadClasses("Text", "Emphasis", "Strikeout", "Strong", "Paragraph", "OrderedList", "UnorderedList", "ListItem"); - final String[] inlineClasses = {"Text", "Emphasis", "Strikeout", "Strong"}; - - checkConstructor(classes, "OrderedList", "ListItem"); - checkConstructor(classes, "UnorderedList", "ListItem"); - checkConstructor(classes, "ListItem", "OrderedList", "UnorderedList", "Paragraph"); - Stream.of("Paragraph", "Emphasis", "Strong", "Strikeout") - .forEach(parent -> checkConstructor(classes, parent, inlineClasses)); - } - - private static void checkConstructor(final Map> classes, final String parent, final String... children) { - new TypeChecker(classes, parent, children).checkConstructor(); - } - - private static class TypeChecker { - private final Map> classes; - private final Set> children; - private final Class parent; - - public TypeChecker(final Map> classes, final String parent, final String[] children) { - this.classes = classes; - this.children = Arrays.stream(children).map(classes::get).collect(Collectors.toUnmodifiableSet()); - this.parent = Objects.requireNonNull(classes.get(parent)); - } - - private void checkClassType(final Class classType) { - final Predicate> isAssignableFrom = classType::isAssignableFrom; - checkType(parent, Predicate.not(isAssignableFrom), "not ", children.stream()); - checkType(parent, isAssignableFrom, "", classes.values().stream().filter(Predicate.not(children::contains))); - } - - private static void checkType(final Class parent, final Predicate> predicate, final String not, final Stream> children) { - children.filter(predicate).findAny().ifPresent(child -> { - throw Asserts.error("%s is %scompatible with child of type %s", parent, not, child); - }); - } - - @SuppressWarnings("ChainOfInstanceofChecks") - private void checkParametrizedType(final ParameterizedType type) { - final Type actualType = type.getActualTypeArguments()[0]; - if (actualType instanceof Class) { - checkClassType((Class) actualType); - } else if (actualType instanceof WildcardType) { - for (final Type boundType : ((WildcardType) actualType).getUpperBounds()) { - if (boundType instanceof Class) { - checkClassType((Class) boundType); - } else { - throw Asserts.error("Unsupported wildcard bound type in %s(List<...>): %s", parent, boundType); - } - } - } else { - throw Asserts.error("Unsupported type argument type in %s(List<...>): %s", parent, actualType); - } - } - - @SuppressWarnings("ChainOfInstanceofChecks") - private void checkConstructor() { - try { - final Type argType = parent.getConstructor(List.class).getGenericParameterTypes()[0]; - if (argType instanceof ParameterizedType) { - checkParametrizedType((ParameterizedType) argType); - } else if (argType instanceof Class) { - throw Asserts.error("Raw List type in %s(List)", parent.getName()); - } else { - throw Asserts.error("Unsupported argument type in %s(List<...>): %s", parent.getName(), argType); - } - } catch (final NoSuchMethodException e) { - throw Asserts.error("Missing %s(List<...>) constructor: %s", parent.getName(), e); - } - } - } - - public static void main(final String... args) { - MarkupTest.main(args); - SELECTOR.main(args); - } -} diff --git a/java/markup/MarkupTest.java b/java/markup/MarkupTest.java deleted file mode 100644 index 9574b13..0000000 --- a/java/markup/MarkupTest.java +++ /dev/null @@ -1,97 +0,0 @@ -package markup; - -import base.Selector; -import base.TestCounter; - -import java.util.List; -import java.util.Map; -import java.util.function.Consumer; - -/** - * @author Georgiy Korneev (kgeorgiy@kgeorgiy.info) - */ -public final class MarkupTest { - private static final Consumer MARKDOWN = MarkupTest.variant( - "Markdown", Map.of( - "&[", "", "&]", "", - "<", "", ">", "" - ) - ); - - private static final Consumer HTML = MarkupTest.variant( - "Html", Map.of( - "&[", "

                                                                                                                                                                                                                                                                                                                                                  ", "&]", "

                                                                                                                                                                                                                                                                                                                                                  ", - "*<", "", "*>", "", - "__<", "", "__>", "", - "~<", "", "~>", "" - ) - ); - - public static final Selector SELECTOR = new Selector(MarkupTest.class) - .variant("Base", MARKDOWN) - .variant("3637", MARKDOWN) - .variant("3839", MARKDOWN) - .variant("3435", HTML) - .variant("3233", HTML) - .variant("4142", MARKDOWN) - .variant("4749", MARKDOWN) - - ; - - public static Consumer variant(final String name, final Map mapping) { - return MarkupTester.variant(MarkupTest::test, name, mapping); - } - - private MarkupTest() { - } - - public static void test(final MarkupTester.Checker checker) { - test(checker, new Paragraph(List.of(new Text("Hello"))), "Hello"); - test(checker, new Paragraph(List.of(new Emphasis(List.of(new Text("Hello"))))), "*"); - test(checker, new Paragraph(List.of(new Strong(List.of(new Text("Hello"))))), "__"); - test(checker, new Paragraph(List.of(new Strikeout(List.of(new Text("Hello"))))), "~"); - - final Paragraph paragraph = new Paragraph(List.of( - new Strong(List.of( - new Text("1"), - new Strikeout(List.of( - new Text("2"), - new Emphasis(List.of( - new Text("3"), - new Text("4") - )), - new Text("5") - )), - new Text("6") - )) - )); - test(checker, paragraph, "__<1~<2*<34*>5~>6__>"); - test( - checker, - new Paragraph(List.of(new Strong(List.of( - new Text("sdq"), - new Strikeout(List.of(new Emphasis(List.of(new Text("r"))), new Text("vavc"))), - new Text("zg") - )))), - "__vavc~>zg__>" - ); - test( - checker, - new Paragraph(List.of(new Strikeout(List.of(new Strong(List.of(new Strikeout(List.of(new Text("е"), new Text("е"), new Text("г"))), new Text("ftje"), new Strong(List.of(new Text("йцць"), new Text("р"))))), new Strong(List.of(new Strikeout(List.of(new Text("д"), new Text("б"), new Text("е"))), new Strong(List.of(new Text("лъ"), new Text("шщ"))), new Strong(List.of(new Text("б"), new Text("еи"))))), new Emphasis(List.of(new Emphasis(List.of(new Text("м"), new Text("к"))), new Emphasis(List.of(new Text("уаужш"), new Text("ш"))), new Strong(List.of(new Text("рб"), new Text("щ"))))))), new Text("a"), new Strikeout(List.of(new Text("no"), new Text("ddw"), new Strong(List.of(new Emphasis(List.of(new Text("щ"), new Text("ча"))), new Emphasis(List.of(new Text("ъп"), new Text("ш"))), new Text("psk"))))))), - "~<__<~<еег~>ftje__<йццьр__>__>__<~<дбе~>__<лъшщ__>__<беи__>__>*<*<мк*>*<уаужшш*>__<рбщ__>*>~>a~*<ъпш*>psk__>~>" - ); - test( - checker, - new Paragraph(List.of(new Strikeout(List.of(new Strong(List.of(new Strikeout(List.of(new Emphasis(List.of(new Text("об"))), new Strikeout(List.of(new Text("ц"))), new Text("зснцйцць"), new Text("р"), new Text("а"))), new Strikeout(List.of(new Strikeout(List.of(new Text("б"))), new Strikeout(List.of(new Text("ялъ"))), new Text("шщ"), new Text("ф"), new Text("м"))), new Emphasis(List.of(new Emphasis(List.of(new Text("узр"))), new Text("i"), new Text("и"), new Text("г"), new Text("с"))), new Strong(List.of(new Strong(List.of(new Text("шмрб"))), new Strong(List.of(new Text("ь"))), new Text("з"), new Text("з"), new Text("фь"))), new Text("ddw"))), new Strong(List.of(new Emphasis(List.of(new Emphasis(List.of(new Text("ввтъп"))), new Strong(List.of(new Text("ш"))), new Text("хте"), new Text("чюе"), new Text("х"))), new Text("g"), new Strikeout(List.of(new Strikeout(List.of(new Text("ддзюцщ"))), new Strong(List.of(new Text("к"))), new Text("йщ"), new Text("э"), new Text("то"))), new Strong(List.of(new Emphasis(List.of(new Text("ж"))), new Text("t"), new Text("ыеж"), new Text("ч"), new Text("г"))), new Text("kwt"))), new Strong(List.of(new Strong(List.of(new Emphasis(List.of(new Text("ш"))), new Strong(List.of(new Text("х"))), new Text("уи"), new Text("о"), new Text("п"))), new Emphasis(List.of(new Text("zn"), new Strong(List.of(new Text("нш"))), new Text("диуьг"), new Text("вй"), new Text("шш"))), new Strong(List.of(new Emphasis(List.of(new Text("ьмша"))), new Emphasis(List.of(new Text("у"))), new Text("в"), new Text("у"), new Text("ир"))), new Emphasis(List.of(new Strikeout(List.of(new Text("я"))), new Strikeout(List.of(new Text("зоъ"))), new Text("эн"), new Text("ъ"), new Text("ьо"))), new Text("cqqzbhtn"))), new Text("i"), new Strong(List.of(new Text("i"), new Strikeout(List.of(new Strong(List.of(new Text("ш"))), new Strong(List.of(new Text("к"))), new Text("ж"), new Text("б"), new Text("ащ"))), new Strikeout(List.of(new Strikeout(List.of(new Text("пян"))), new Emphasis(List.of(new Text("ц"))), new Text("ю"), new Text("дрк"), new Text("лщ"))), new Strong(List.of(new Text("xywa"), new Text("ряэк"), new Text("п"), new Text("э"), new Text("т"))), new Strong(List.of(new Strikeout(List.of(new Text("е"))), new Text("чб"), new Text("зс"), new Text("екйюд"), new Text("чх"))))))), new Strikeout(List.of(new Strong(List.of(new Strong(List.of(new Strong(List.of(new Text("юи"))), new Emphasis(List.of(new Text("и"))), new Text("п"), new Text("вх"), new Text("ф"))), new Strong(List.of(new Strong(List.of(new Text("щюереф"))), new Text("otvic"), new Text("ж"), new Text("уыа"), new Text("ьскю"))), new Text("x"), new Strikeout(List.of(new Emphasis(List.of(new Text("ж"))), new Strikeout(List.of(new Text("зыйгг"))), new Text("о"), new Text("ш"), new Text("ф"))), new Text("zf"))), new Emphasis(List.of(new Text("a"), new Strikeout(List.of(new Emphasis(List.of(new Text("э"))), new Text("amqcfdzrg"), new Text("кыч"), new Text("к"), new Text("я"))), new Strikeout(List.of(new Strong(List.of(new Text("нфны"))), new Strikeout(List.of(new Text("гщ"))), new Text("ы"), new Text("шя"), new Text("е"))), new Strong(List.of(new Strong(List.of(new Text("ъю"))), new Emphasis(List.of(new Text("яхе"))), new Text("б"), new Text("бц"), new Text("еящж"))), new Text("cn"))), new Emphasis(List.of(new Strong(List.of(new Strong(List.of(new Text("л"))), new Text("wl"), new Text("оде"), new Text("кл"), new Text("еок"))), new Strikeout(List.of(new Strikeout(List.of(new Text("яяиь"))), new Strong(List.of(new Text("ик"))), new Text("юью"), new Text("ь"), new Text("э"))), new Emphasis(List.of(new Strikeout(List.of(new Text("жп"))), new Emphasis(List.of(new Text("ц"))), new Text("ндюз"), new Text("ч"), new Text("н"))), new Text("r"), new Strikeout(List.of(new Strikeout(List.of(new Text("зьуес"))), new Text("к"), new Text("и"), new Text("к"), new Text("й"))))), new Strikeout(List.of(new Emphasis(List.of(new Strikeout(List.of(new Text("еы"))), new Emphasis(List.of(new Text("б"))), new Text("сйсыр"), new Text("я"), new Text("т"))), new Emphasis(List.of(new Emphasis(List.of(new Text("з"))), new Strong(List.of(new Text("ахыы"))), new Text("х"), new Text("м"), new Text("п"))), new Strikeout(List.of(new Text("b"), new Text("o"), new Text("шьх"), new Text("йз"), new Text("ж"))), new Text("udlh"), new Strikeout(List.of(new Strikeout(List.of(new Text("п"))), new Text("хъфоз"), new Text("е"), new Text("ыф"), new Text("ю"))))), new Text("z"))), new Text("hy"), new Strong(List.of(new Text("tyv"), new Text("x"), new Strikeout(List.of(new Text("vzb"), new Strong(List.of(new Text("oi"), new Text("r"), new Text("ю"), new Text("с"), new Text("еппзмл"))), new Text("r"), new Emphasis(List.of(new Strikeout(List.of(new Text("игс"))), new Emphasis(List.of(new Text("нян"))), new Text("ю"), new Text("с"), new Text("цлъ"))), new Text("rptq"))), new Emphasis(List.of(new Strong(List.of(new Text("u"), new Strong(List.of(new Text("кще"))), new Text("пхте"), new Text("у"), new Text("з"))), new Text("zbmflu"), new Strikeout(List.of(new Strong(List.of(new Text("л"))), new Emphasis(List.of(new Text("ко"))), new Text("ъ"), new Text("щ"), new Text("жч"))), new Strong(List.of(new Strong(List.of(new Text("ж"))), new Strikeout(List.of(new Text("еъ"))), new Text("в"), new Text("ф"), new Text("йб"))), new Text("kvuf"))), new Strikeout(List.of(new Text("azn"), new Strikeout(List.of(new Strong(List.of(new Text("ъ"))), new Emphasis(List.of(new Text("ре"))), new Text("йч"), new Text("н"), new Text("ир"))), new Emphasis(List.of(new Emphasis(List.of(new Text("с"))), new Strong(List.of(new Text("щ"))), new Text("ъсбчиюзи"), new Text("сэ"), new Text("е"))), new Strikeout(List.of(new Emphasis(List.of(new Text("о"))), new Text("г"), new Text("бвщ"), new Text("пр"), new Text("йвъч"))), new Text("c"))))), new Strong(List.of(new Strikeout(List.of(new Strikeout(List.of(new Emphasis(List.of(new Text("жбфц"))), new Strong(List.of(new Text("рцч"))), new Text("хе"), new Text("ж"), new Text("ы"))), new Strikeout(List.of(new Emphasis(List.of(new Text("я"))), new Emphasis(List.of(new Text("мн"))), new Text("яе"), new Text("е"), new Text("дхпг"))), new Emphasis(List.of(new Emphasis(List.of(new Text("нй"))), new Text("gf"), new Text("и"), new Text("хю"), new Text("ця"))), new Strong(List.of(new Emphasis(List.of(new Text("о"))), new Emphasis(List.of(new Text("ъ"))), new Text("лм"), new Text("ы"), new Text("рц"))), new Emphasis(List.of(new Strikeout(List.of(new Text("я"))), new Text("ыл"), new Text("г"), new Text("я"), new Text("эй"))))), new Text("qi"), new Emphasis(List.of(new Text("dtt"), new Emphasis(List.of(new Strong(List.of(new Text("пв"))), new Text("i"), new Text("яешц"), new Text("йшй"), new Text("щмив"))), new Text("u"), new Text("d"), new Strikeout(List.of(new Strikeout(List.of(new Text("о"))), new Text("иов"), new Text("к"), new Text("кои"), new Text("яс"))))), new Strikeout(List.of(new Emphasis(List.of(new Text("j"), new Strong(List.of(new Text("эя"))), new Text("шыф"), new Text("дрн"), new Text("щ"))), new Text("j"), new Strong(List.of(new Emphasis(List.of(new Text("ю"))), new Strikeout(List.of(new Text("чцин"))), new Text("сф"), new Text("з"), new Text("юэи"))), new Emphasis(List.of(new Emphasis(List.of(new Text("цс"))), new Text("ювус"), new Text("ъ"), new Text("щэны"), new Text("б"))), new Emphasis(List.of(new Text("cbogf"), new Text("э"), new Text("ж"), new Text("ш"), new Text("м"))))), new Strikeout(List.of(new Strong(List.of(new Strong(List.of(new Text("ф"))), new Text("w"), new Text("цеъ"), new Text("н"), new Text("ем"))), new Strikeout(List.of(new Strikeout(List.of(new Text("л"))), new Strong(List.of(new Text("э"))), new Text("лд"), new Text("эд"), new Text("л"))), new Emphasis(List.of(new Emphasis(List.of(new Text("уг"))), new Strikeout(List.of(new Text("зп"))), new Text("юб"), new Text("сгы"), new Text("шю"))), new Strikeout(List.of(new Emphasis(List.of(new Text("рйей"))), new Text("с"), new Text("зюй"), new Text("р"), new Text("в"))), new Emphasis(List.of(new Text("p"), new Text("у"), new Text("на"), new Text("б"), new Text("х"))))))))), - "~<__<~<*<об*>~<ц~>зснцйццьра~>~<~<б~>~<ялъ~>шщфм~>*<*<узр*>iигс*>__<__<шмрб__>__<ь__>ззфь__>ddw__>__<*<*<ввтъп*>__<ш__>хтечюех*>g~<~<ддзюцщ~>__<к__>йщэто~>__<*<ж*>tыежчг__>kwt__>__<__<*<ш*>__<х__>уиоп__>*диуьгвйшш*>__<*<ьмша*>*<у*>вуир__>*<~<я~>~<зоъ~>энъьо*>cqqzbhtn__>i____<к__>жбащ~>~<~<пян~>*<ц*>юдрклщ~>____<~<е~>чбзсекйюдчх__>__>~>~<__<__<__<юи__>*<и*>пвхф__>__<__<щюереф__>otvicжуыаьскю__>x~<*<ж*>~<зыйгг~>ошф~>zf__>*amqcfdzrgкычкя~>~<__<нфны__>~<гщ~>ышяе~>__<__<ъю__>*<яхе*>ббцеящж__>cn*>*<__<__<л__>wlодеклеок__>~<~<яяиь~>__<ик__>юьюьэ~>*<~<жп~>*<ц*>ндюзчн*>r~<~<зьуес~>кикй~>*>~<*<~<еы~>*<б*>сйсырят*>*<*<з*>__<ахыы__>хмп*>~udlh~<~<п~>хъфозеыфю~>~>z~>hy__r*<~<игс~>*<нян*>юсцлъ*>rptq~>*<__пхтеуз__>zbmflu~<__<л__>*<ко*>ъщжч~>__<__<ж__>~<еъ~>вфйб__>kvuf*>~*<ре*>йчнир~>*<*<с*>__<щ__>ъсбчиюзисэе*>~<*<о*>гбвщпрйвъч~>c~>__>__<~<~<*<жбфц*>__<рцч__>хежы~>~<*<я*>*<мн*>яеедхпг~>*<*<нй*>gfихюця*>__<*<о*>*<ъ*>лмырц__>*<~<я~>ылгяэй*>~>qi*iяешцйшйщмив*>ud~<~<о~>иовккоияс~>*>~<*шыфдрнщ*>j__<*<ю*>~<чцин~>сфзюэи__>*<*<цс*>ювусъщэныб*>*~>~<__<__<ф__>wцеънем__>~<~<л~>__<э__>лдэдл~>*<*<уг*>~<зп~>юбсгышю*>~<*<рйей*>сзюйрв~>*~>__>" - ); - } - - private static void test(final MarkupTester.Checker checker, final Paragraph paragraph, final String template) { - checker.test(paragraph, String.format("&[%s&]", template)); - } - - public static void main(final String... args) { - SELECTOR.main(args); - } -} diff --git a/java/markup/MarkupTester.java b/java/markup/MarkupTester.java deleted file mode 100644 index 4d93d97..0000000 --- a/java/markup/MarkupTester.java +++ /dev/null @@ -1,71 +0,0 @@ -package markup; - -import base.Asserts; -import base.BaseChecker; -import base.TestCounter; - -import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodHandles; -import java.lang.invoke.MethodType; -import java.util.Map; -import java.util.function.BiConsumer; -import java.util.function.Consumer; - -/** - * @author Georgiy Korneev (kgeorgiy@kgeorgiy.info) - */ -public final class MarkupTester { - private final Map mapping; - private final String toString; - - private MarkupTester(final Map mapping, final String toString) { - this.mapping = mapping; - this.toString = toString; - } - - public static Consumer variant(final Consumer checker, final String name, final Map mapping) { - return counter -> test(checker).accept(new MarkupTester(mapping, "to" + name), counter); - } - - public static BiConsumer test(final Consumer tester) { - return (checker, counter) -> tester.accept(checker.new Checker(counter)); - } - - @Override - public String toString() { - return toString; - } - - public class Checker extends BaseChecker { - public Checker(final TestCounter counter) { - super(counter); - } - - private MethodHandle findMethod(final T value) { - try { - return MethodHandles.publicLookup().findVirtual(value.getClass(), toString, MethodType.methodType(void.class, StringBuilder.class)); - } catch (final NoSuchMethodException | IllegalAccessException e) { - throw Asserts.error("Cannot find method 'void %s(StringBuilder)' for %s", toString, value.getClass()); - } - } - - public void test(final T value, String expectedTemplate) { - final MethodHandle method = findMethod(value); - for (final Map.Entry entry : mapping.entrySet()) { - expectedTemplate = expectedTemplate.replace(entry.getKey(), entry.getValue()); - } - - final String expected = expectedTemplate; - counter.println("Test " + counter.getTestNo()); - counter.test(() -> { - final StringBuilder sb = new StringBuilder(); - try { - method.invoke(value, sb); - } catch (final Throwable e) { - throw Asserts.error("%s(StringBuilder) for %s thrown exception: %s", toString, value.getClass(), e); - } - Asserts.assertEquals("Result", expected, sb.toString()); - }); - } - } -} diff --git a/java/markup/package-info.java b/java/markup/package-info.java deleted file mode 100644 index fdef1bc..0000000 --- a/java/markup/package-info.java +++ /dev/null @@ -1,7 +0,0 @@ -/** - * Tests for Markup homework - * of Introduction to Programming course. - * - * @author Georgiy Korneev (kgeorgiy@kgeorgiy.info) - */ -package markup; \ No newline at end of file diff --git a/java/sum/.idea/.gitignore b/java/sum/.idea/.gitignore new file mode 100644 index 0000000..ab1f416 --- /dev/null +++ b/java/sum/.idea/.gitignore @@ -0,0 +1,10 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Ignored default folder with query files +/queries/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/java/sum/.idea/misc.xml b/java/sum/.idea/misc.xml new file mode 100644 index 0000000..a20905f --- /dev/null +++ b/java/sum/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/java/sum/.idea/modules.xml b/java/sum/.idea/modules.xml new file mode 100644 index 0000000..d8cb954 --- /dev/null +++ b/java/sum/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/java/sum/.idea/vcs.xml b/java/sum/.idea/vcs.xml new file mode 100644 index 0000000..b2bdec2 --- /dev/null +++ b/java/sum/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/java/sum/Sum.java b/java/sum/Sum.java new file mode 100644 index 0000000..831dd79 --- /dev/null +++ b/java/sum/Sum.java @@ -0,0 +1,20 @@ +package sum; + +public class Sum { + public static void main(String[] args) { + int res = 0; + for (String arg : args) { + StringBuilder builder = new StringBuilder(); + for (char c : arg.toCharArray()) { + if (!Character.isWhitespace(c)) { + builder.append(c); + } else { + res += (!builder.toString().isEmpty()) ? Integer.parseInt(builder.toString()) : 0; + builder = new StringBuilder(); + } + } + res += (!builder.toString().isEmpty()) ? Integer.parseInt(builder.toString()) : 0; + } + System.out.println(res); + } +}