Upload files to "java/expression"
This commit is contained in:
51
java/expression/High.java
Normal file
51
java/expression/High.java
Normal file
@@ -0,0 +1,51 @@
|
||||
package expression;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Doschennikov Nikita (me@fymio.us)
|
||||
*/
|
||||
public class High extends AbstractExpression {
|
||||
private final AbstractExpression operand;
|
||||
|
||||
public High(AbstractExpression operand) {
|
||||
this.operand = operand;
|
||||
}
|
||||
|
||||
private static int highestBit(int n) {
|
||||
if (n == 0) return 0;
|
||||
n |= (n >> 1);
|
||||
n |= (n >> 2);
|
||||
n |= (n >> 4);
|
||||
n |= (n >> 8);
|
||||
n |= (n >> 16);
|
||||
return n - (n >>> 1);
|
||||
}
|
||||
|
||||
@Override public int evaluate(int x) { return highestBit(operand.evaluate(x)); }
|
||||
@Override public int evaluate(int x, int y, int z) { return highestBit(operand.evaluate(x,y,z)); }
|
||||
@Override public int evaluate(List<Integer> vars) { return highestBit(operand.evaluate(vars)); }
|
||||
@Override public BigInteger evaluateBi(List<BigInteger> vars) { throw new UnsupportedOperationException(); }
|
||||
@Override public BigDecimal evaluateBd(List<BigDecimal> vars) { throw new UnsupportedOperationException(); }
|
||||
|
||||
@Override public String toString() { return "high(" + operand + ")"; }
|
||||
|
||||
@Override
|
||||
public String toMiniString() {
|
||||
if (operand instanceof AbstractBinaryOperation) {
|
||||
return "high(" + operand.toMiniString() + ")";
|
||||
}
|
||||
return "high " + operand.toMiniString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof High)) return false;
|
||||
return operand.equals(((High) obj).operand);
|
||||
}
|
||||
|
||||
@Override public int hashCode() { return operand.hashCode() ^ 0x48494748; }
|
||||
}
|
||||
337
java/expression/ListExpression.java
Normal file
337
java/expression/ListExpression.java
Normal file
@@ -0,0 +1,337 @@
|
||||
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<Integer> 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<Integer> TYPE = new Type<>(a -> a, ExtendedRandom::nextInt, int.class);
|
||||
ExpressionKind<ListExpression, Integer> KIND = new ExpressionKind<>(
|
||||
TYPE,
|
||||
ListExpression.class,
|
||||
(r, c) ->
|
||||
IntStream.range(0, c)
|
||||
.mapToObj(name ->
|
||||
Pair.<String, ListExpression>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<Integer> vars) {
|
||||
return vars.get(0);
|
||||
}
|
||||
|
||||
static void main(final String... args) {
|
||||
TripleExpression.SELECTOR.variant(
|
||||
"List",
|
||||
ExpressionTest.v(ListExpression::tester)
|
||||
).main(args);
|
||||
}
|
||||
}
|
||||
46
java/expression/Log.java
Normal file
46
java/expression/Log.java
Normal file
@@ -0,0 +1,46 @@
|
||||
package expression;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
|
||||
/**
|
||||
* @author Doschennikov Nikita (me@fymio.us)
|
||||
*/
|
||||
public class Log extends AbstractBinaryOperation {
|
||||
public Log(AbstractExpression l, AbstractExpression r) { super(l, r); }
|
||||
|
||||
@Override protected String getOperator() { return "//"; }
|
||||
@Override protected int getPriority() { return 3; }
|
||||
@Override protected boolean isRightAssoc() { return true; }
|
||||
|
||||
@Override
|
||||
protected int applyInt(int a, int b) {
|
||||
if (a <= 0) throw new ArithmeticException("logarithm of non-positive number");
|
||||
if (b <= 1) throw new ArithmeticException("logarithm base must be > 1");
|
||||
int result = 0;
|
||||
int power = 1;
|
||||
while (power <= a / b) {
|
||||
power *= b;
|
||||
result++;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BigInteger applyBi(BigInteger a, BigInteger b) {
|
||||
if (a.signum() <= 0) throw new ArithmeticException("logarithm of non-positive number");
|
||||
if (b.compareTo(BigInteger.TWO) < 0) throw new ArithmeticException("logarithm base must be > 1");
|
||||
int result = 0;
|
||||
BigInteger power = BigInteger.ONE;
|
||||
while (power.multiply(b).compareTo(a) <= 0) {
|
||||
power = power.multiply(b);
|
||||
result++;
|
||||
}
|
||||
return BigInteger.valueOf(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BigDecimal applyBd(BigDecimal a, BigDecimal b) {
|
||||
throw new UnsupportedOperationException("log not supported for BigDecimal");
|
||||
}
|
||||
}
|
||||
52
java/expression/Log2.java
Normal file
52
java/expression/Log2.java
Normal file
@@ -0,0 +1,52 @@
|
||||
package expression;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Doschennikov Nikita (me@fymio.us)
|
||||
*/
|
||||
public class Log2 extends AbstractExpression {
|
||||
private final AbstractExpression operand;
|
||||
|
||||
public Log2(AbstractExpression operand) {
|
||||
this.operand = operand;
|
||||
}
|
||||
|
||||
private static int log2(int n) {
|
||||
if (n <= 0) throw new ArithmeticException("log₂ of non-positive number: " + n);
|
||||
int result = 0;
|
||||
int v = n;
|
||||
while (v > 1) {
|
||||
v >>= 1;
|
||||
result++;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override public int evaluate(int x) { return log2(operand.evaluate(x)); }
|
||||
@Override public int evaluate(int x, int y, int z) { return log2(operand.evaluate(x,y,z)); }
|
||||
@Override public int evaluate(List<Integer> vars) { return log2(operand.evaluate(vars)); }
|
||||
@Override public BigInteger evaluateBi(List<BigInteger> vars) { throw new UnsupportedOperationException(); }
|
||||
@Override public BigDecimal evaluateBd(List<BigDecimal> vars) { throw new UnsupportedOperationException(); }
|
||||
|
||||
@Override public String toString() { return "log₂(" + operand + ")"; }
|
||||
|
||||
@Override
|
||||
public String toMiniString() {
|
||||
if (operand instanceof AbstractBinaryOperation) {
|
||||
return "log₂(" + operand.toMiniString() + ")";
|
||||
}
|
||||
return "log₂ " + operand.toMiniString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof Log2)) return false;
|
||||
return operand.equals(((Log2) obj).operand);
|
||||
}
|
||||
|
||||
@Override public int hashCode() { return operand.hashCode() ^ 0x4C4F4732; }
|
||||
}
|
||||
41
java/expression/Low.java
Normal file
41
java/expression/Low.java
Normal file
@@ -0,0 +1,41 @@
|
||||
package expression;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Doschennikov Nikita (me@fymio.us)
|
||||
*/
|
||||
public class Low extends AbstractExpression {
|
||||
private final AbstractExpression operand;
|
||||
|
||||
public Low(AbstractExpression operand) {
|
||||
this.operand = operand;
|
||||
}
|
||||
|
||||
@Override public int evaluate(int x) { int n = operand.evaluate(x); return n & -n; }
|
||||
@Override public int evaluate(int x, int y, int z) { int n = operand.evaluate(x,y,z); return n & -n; }
|
||||
@Override public int evaluate(List<Integer> vars) { int n = operand.evaluate(vars); return n & -n; }
|
||||
@Override public BigInteger evaluateBi(List<BigInteger> vars) { throw new UnsupportedOperationException(); }
|
||||
@Override public BigDecimal evaluateBd(List<BigDecimal> vars) { throw new UnsupportedOperationException(); }
|
||||
|
||||
@Override public String toString() { return "low(" + operand + ")"; }
|
||||
|
||||
@Override
|
||||
public String toMiniString() {
|
||||
if (operand instanceof AbstractBinaryOperation) {
|
||||
return "low(" + operand.toMiniString() + ")";
|
||||
}
|
||||
return "low " + operand.toMiniString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof Low)) return false;
|
||||
return operand.equals(((Low) obj).operand);
|
||||
}
|
||||
|
||||
@Override public int hashCode() { return operand.hashCode() ^ 0x4C4F5700; }
|
||||
}
|
||||
Reference in New Issue
Block a user