From 1ece8443a0ca73ce94723970716dfbfbccd22dd9 Mon Sep 17 00:00:00 2001 From: codejava Date: Mon, 13 Apr 2026 10:51:24 +0300 Subject: [PATCH] Upload files to "java/expression" --- java/expression/Subtract.java | 44 ++++ java/expression/ToMiniString.java | 10 + java/expression/TripleExpression.java | 317 ++++++++++++++++++++++++++ java/expression/Variable.java | 118 ++++++++++ 4 files changed, 489 insertions(+) create mode 100644 java/expression/Subtract.java create mode 100644 java/expression/ToMiniString.java create mode 100644 java/expression/TripleExpression.java create mode 100644 java/expression/Variable.java diff --git a/java/expression/Subtract.java b/java/expression/Subtract.java new file mode 100644 index 0000000..5ad4848 --- /dev/null +++ b/java/expression/Subtract.java @@ -0,0 +1,44 @@ +package expression; + +import java.math.BigDecimal; +import java.math.BigInteger; + +/** + * @author Doschennikov Nikita (me@fymio.us) + */ +public class Subtract extends AbstractBinaryOperation { + + public Subtract(AbstractExpression l, AbstractExpression r) { + super(l, r); + } + + @Override + protected String getOperator() { + return "-"; + } + + @Override + protected int getPriority() { + return 1; + } + + @Override + protected boolean isRightAssoc() { + return true; + } + + @Override + protected int applyInt(int a, int b) { + return a - b; + } + + @Override + protected BigInteger applyBi(BigInteger a, BigInteger b) { + return a.subtract(b); + } + + @Override + protected BigDecimal applyBd(BigDecimal a, BigDecimal b) { + return a.subtract(b); + } +} diff --git a/java/expression/ToMiniString.java b/java/expression/ToMiniString.java new file mode 100644 index 0000000..60a655c --- /dev/null +++ b/java/expression/ToMiniString.java @@ -0,0 +1,10 @@ +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 new file mode 100644 index 0000000..d48010a --- /dev/null +++ b/java/expression/TripleExpression.java @@ -0,0 +1,317 @@ +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/Variable.java b/java/expression/Variable.java new file mode 100644 index 0000000..e9f1837 --- /dev/null +++ b/java/expression/Variable.java @@ -0,0 +1,118 @@ +package expression; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.List; + +/** + * @author Doschennikov Nikita (me@fymio.us) + */ +public class Variable extends AbstractExpression { + + private final String name; + private final int index; + + public Variable(String name) { + this.name = name; + this.index = -1; + } + + public Variable(int index) { + this.index = index; + this.name = "$" + index; + } + + public Variable(int index, String name) { + this.index = index; + this.name = name; + } + + @Override + public int evaluate(int x) { + if (index >= 0) { + if (index == 0) return x; + throw new IllegalStateException( + "Positional variable $" + + index + + " cannot be evaluated with a single value" + ); + } + if ("x".equals(name)) return x; + throw new IllegalStateException( + "Variable '" + name + "' is not 'x'; use evaluate(x, y, z) instead" + ); + } + + @Override + public int evaluate(int x, int y, int z) { + if (index >= 0) { + return switch (index) { + case 0 -> x; + case 1 -> y; + case 2 -> z; + default -> throw new IndexOutOfBoundsException( + "Variable index " + + index + + " out of range for triple evaluate" + ); + }; + } + return switch (name) { + case "x" -> x; + case "y" -> y; + case "z" -> z; + default -> throw new IllegalStateException( + "Unknown variable: " + name + ); + }; + } + + @Override + public int evaluate(List vars) { + return vars.get(resolvedIndex()); + } + + @Override + public BigInteger evaluateBi(List vars) { + return vars.get(resolvedIndex()); + } + + @Override + public BigDecimal evaluateBd(List vars) { + return vars.get(resolvedIndex()); + } + + private int resolvedIndex() { + if (index >= 0) return index; + return switch (name) { + case "x" -> 0; + case "y" -> 1; + case "z" -> 2; + default -> throw new IllegalStateException( + "Unknown variable: " + name + ); + }; + } + + @Override + public String toString() { + return name; + } + + @Override + public String toMiniString() { + return name; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (!(obj instanceof Variable)) return false; + return name.equals(((Variable) obj).name); + } + + @Override + public int hashCode() { + return name.hashCode(); + } +}