diff --git a/src/main/java/org/warp/picalculator/gui/expression/InputContext.java b/src/main/java/org/warp/picalculator/gui/expression/InputContext.java index 2c18e5c4..5a532a4b 100644 --- a/src/main/java/org/warp/picalculator/gui/expression/InputContext.java +++ b/src/main/java/org/warp/picalculator/gui/expression/InputContext.java @@ -3,6 +3,7 @@ package org.warp.picalculator.gui.expression; import java.util.HashMap; import org.warp.picalculator.gui.expression.blocks.BlockVariable; +import org.warp.picalculator.math.MathematicalSymbols; import org.warp.picalculator.math.functions.Variable.V_TYPE; public class InputContext { @@ -11,6 +12,7 @@ public class InputContext { public InputContext() { this.variableTypes = new HashMap<>(); + this.variableTypes.put(MathematicalSymbols.PI, V_TYPE.CONSTANT); } public InputContext(HashMap variableTypes) { diff --git a/src/main/java/org/warp/picalculator/gui/expression/blocks/BlockVariable.java b/src/main/java/org/warp/picalculator/gui/expression/blocks/BlockVariable.java index bf95d7f0..b4a29939 100644 --- a/src/main/java/org/warp/picalculator/gui/expression/blocks/BlockVariable.java +++ b/src/main/java/org/warp/picalculator/gui/expression/blocks/BlockVariable.java @@ -23,22 +23,29 @@ public class BlockVariable extends Block { private int color; private boolean mustRefresh = true; private BlockVariable typeDirtyID; + private final boolean typeLocked; public BlockVariable(InputContext ic, char ch) { + this(ic, ch, false); + } + public BlockVariable(InputContext ic, char ch, boolean typeLocked) { this.ic = ic; this.ch = ch; - this.menu = new VariableMenu(this); - this.type = V_TYPE.UNKNOWN; + this.type = V_TYPE.VARIABLE; this.color = 0xFF304ffe; this.typeDirtyID = this; + this.typeLocked = typeLocked; + this.menu = typeLocked ? null : new VariableMenu(this); retrieveValue(); recomputeDimensions(); } private void retrieveValue() { - type = ic.variableTypes.getOrDefault(ch, V_TYPE.UNKNOWN); + type = ic.variableTypes.getOrDefault(ch, V_TYPE.VARIABLE); typeDirtyID = ic.variableTypeDirtyID; - menu.mustRefreshMenu = true; + if (menu != null) { + menu.mustRefreshMenu = true; + } mustRefresh = true; System.out.println("retrieve:"+type.toString()); } @@ -63,11 +70,11 @@ public class BlockVariable extends Block { if (mustRefresh) { mustRefresh = false; switch (type) { - case UNKNOWN: + case VARIABLE: color = 0xFF304ffe; break; - case COEFFICIENT: - color = 0xFF35913F; + case CONSTANT: + color = typeLocked ? 0xFF000000 : 0xFF35913F; break; case SOLUTION: default: @@ -149,15 +156,15 @@ public class BlockVariable extends Block { case LEFT: case UP: switch (block.type) { - case UNKNOWN: + case VARIABLE: block.type = V_TYPE.SOLUTION; break; - case COEFFICIENT: - block.type = V_TYPE.UNKNOWN; + case CONSTANT: + block.type = V_TYPE.VARIABLE; break; case SOLUTION: default: - block.type = V_TYPE.COEFFICIENT; + block.type = V_TYPE.CONSTANT; break; } break; @@ -166,15 +173,15 @@ public class BlockVariable extends Block { case EQUAL: case SIMPLIFY: switch (block.type) { - case UNKNOWN: - block.type = V_TYPE.COEFFICIENT; + case VARIABLE: + block.type = V_TYPE.CONSTANT; break; - case COEFFICIENT: + case CONSTANT: block.type = V_TYPE.SOLUTION; break; case SOLUTION: default: - block.type = V_TYPE.UNKNOWN; + block.type = V_TYPE.VARIABLE; break; } break; diff --git a/src/main/java/org/warp/picalculator/gui/expression/containers/NormalInputContainer.java b/src/main/java/org/warp/picalculator/gui/expression/containers/NormalInputContainer.java index e5a58fef..94de7211 100755 --- a/src/main/java/org/warp/picalculator/gui/expression/containers/NormalInputContainer.java +++ b/src/main/java/org/warp/picalculator/gui/expression/containers/NormalInputContainer.java @@ -66,6 +66,8 @@ public class NormalInputContainer extends InputContainer { return new BlockChar(c); case MathematicalSymbols.SINE: return new BlockSine(); + case MathematicalSymbols.PI: + return new BlockVariable(inputContext, c, true); default: for (char v : MathematicalSymbols.variables) { if (c == v) { diff --git a/src/main/java/org/warp/picalculator/gui/screens/MathInputScreen.java b/src/main/java/org/warp/picalculator/gui/screens/MathInputScreen.java index dce7b995..221d70a2 100755 --- a/src/main/java/org/warp/picalculator/gui/screens/MathInputScreen.java +++ b/src/main/java/org/warp/picalculator/gui/screens/MathInputScreen.java @@ -658,7 +658,7 @@ public class MathInputScreen extends Screen { } else if (f instanceof FunctionSingle) { res.addAll(getKnownVariables(new Function[] { ((FunctionSingle) f).getParameter() })); } else if (f instanceof Variable) { - if (((Variable) f).getType() == Variable.V_TYPE.COEFFICIENT) { + if (((Variable) f).getType() == Variable.V_TYPE.CONSTANT) { if (!res.contains(f)) { res.add(f); } diff --git a/src/main/java/org/warp/picalculator/math/MathematicalSymbols.java b/src/main/java/org/warp/picalculator/math/MathematicalSymbols.java index 644e53ff..96ed1150 100755 --- a/src/main/java/org/warp/picalculator/math/MathematicalSymbols.java +++ b/src/main/java/org/warp/picalculator/math/MathematicalSymbols.java @@ -36,6 +36,9 @@ public class MathematicalSymbols { private static final char[] signumsWithoutMultiplication = new char[] { SUM, SUM_SUBTRACTION, SUBTRACTION, DIVISION }; private static final char[] signumsWithMultiplication = Utils.add(signumsWithoutMultiplication, MULTIPLICATION); + public static final char[] functionsNSNAndSignums = concat(functionsNSN, signumsWithMultiplication); + public static final char[] functionsAndSignums = concat(functions, signumsWithMultiplication); + public static final char[] signums(boolean withMultiplication) { if (withMultiplication) { return signumsWithMultiplication; diff --git a/src/main/java/org/warp/picalculator/math/functions/Division.java b/src/main/java/org/warp/picalculator/math/functions/Division.java index 55306112..f8b160f4 100755 --- a/src/main/java/org/warp/picalculator/math/functions/Division.java +++ b/src/main/java/org/warp/picalculator/math/functions/Division.java @@ -19,6 +19,7 @@ import org.warp.picalculator.math.rules.FractionsRule12; import org.warp.picalculator.math.rules.FractionsRule2; import org.warp.picalculator.math.rules.FractionsRule3; import org.warp.picalculator.math.rules.UndefinedRule2; +import org.warp.picalculator.math.rules.methods.DivisionRule1; import it.unimi.dsi.fastutil.objects.ObjectArrayList; @@ -50,13 +51,16 @@ public class Division extends FunctionOperator { if (UndefinedRule2.compare(this)) { return true; } + if (DivisionRule1.compare(this)) { + return true; + } if (variable1 instanceof Number && variable2 instanceof Number) { if (getMathContext().exactMode) { try { if (((Number) variable1).isInteger() && ((Number) variable2).isInteger()) { LinkedList factors1 = ((Number) variable1).getFactors(); LinkedList factors2 = ((Number) variable2).getFactors(); - return factors1.retainAll(factors2); //True If something changed in the factors list by keeping only the intersection of the two factor lists. + return factors1.retainAll(factors2) /* True If something changed in the factors list by keeping only the intersection of the two factor lists */ && factors1.size() > 0 /* true if there is at least one common factor */; } else if (((Number) variable1).divide((Number) variable2).isInteger()) { return true; } else { @@ -89,6 +93,8 @@ public class Division extends FunctionOperator { result = FractionsRule12.execute(this); } else if (UndefinedRule2.compare(this)) { result = UndefinedRule2.execute(this); + } else if (DivisionRule1.compare(this)) { + result = DivisionRule1.execute(this); } else if (variable1 instanceof Number && variable2 instanceof Number) { if (getMathContext().exactMode && (((Number) variable1).isInteger() && ((Number) variable2).isInteger())) { LinkedList factors1 = ((Number) variable1).getFactors(); diff --git a/src/main/java/org/warp/picalculator/math/functions/Multiplication.java b/src/main/java/org/warp/picalculator/math/functions/Multiplication.java index 4eec0186..a7c59522 100755 --- a/src/main/java/org/warp/picalculator/math/functions/Multiplication.java +++ b/src/main/java/org/warp/picalculator/math/functions/Multiplication.java @@ -3,6 +3,7 @@ package org.warp.picalculator.math.functions; import org.warp.picalculator.Error; import org.warp.picalculator.gui.expression.blocks.Block; import org.warp.picalculator.gui.expression.blocks.BlockChar; +import org.warp.picalculator.gui.expression.blocks.BlockParenthesis; import org.warp.picalculator.math.Function; import org.warp.picalculator.math.FunctionOperator; import org.warp.picalculator.math.MathContext; @@ -108,18 +109,36 @@ public class Multiplication extends FunctionOperator { @Override public ObjectArrayList toBlock(MathContext context) throws Error { ObjectArrayList result = new ObjectArrayList<>(); - ObjectArrayList sub1 = getParameter1().toBlock(context); - ObjectArrayList sub2 = getParameter2().toBlock(context); + Function par1 = getParameter1(); + Function par2 = getParameter2(); + ObjectArrayList sub1 = par1.toBlock(context); + ObjectArrayList sub2 = par2.toBlock(context); Block nearLeft = sub1.get(sub1.size()-1); Block nearRight = sub2.get(0); - result.addAll(sub1); - if (nearLeft instanceof BlockChar && nearRight instanceof BlockChar) { - + if (par1 instanceof Number && ((Number)par1).equals(new Number(context, -1))) { + result.add(new BlockChar(MathematicalSymbols.MINUS)); + if (new Expression(context, par2).parenthesisNeeded()) { + BlockParenthesis par = new BlockParenthesis(); + ObjectArrayList parBlocks = par2.toBlock(context); + for (Block b: parBlocks) { + par.getNumberContainer().appendBlockUnsafe(b); // Skips recomputeDimension + } + par.recomputeDimensions(); // Recompute dimensions after appendBlockUnsafe + result.add(par); + } else { + result.addAll(par2.toBlock(context)); + } + return result; } else { - result.add(new BlockChar(MathematicalSymbols.MULTIPLICATION)); + result.addAll(sub1); + if ((nearLeft instanceof BlockChar && nearRight instanceof BlockChar) && !(par2 instanceof Negative)) { + + } else { + result.add(new BlockChar(MathematicalSymbols.MULTIPLICATION)); + } + result.addAll(sub2); + return result; } - result.addAll(sub2); - return result; } } \ No newline at end of file diff --git a/src/main/java/org/warp/picalculator/math/functions/Negative.java b/src/main/java/org/warp/picalculator/math/functions/Negative.java index 28c04e5c..63a8e69d 100755 --- a/src/main/java/org/warp/picalculator/math/functions/Negative.java +++ b/src/main/java/org/warp/picalculator/math/functions/Negative.java @@ -3,9 +3,12 @@ package org.warp.picalculator.math.functions; import org.warp.picalculator.Error; import org.warp.picalculator.Errors; import org.warp.picalculator.gui.expression.blocks.Block; +import org.warp.picalculator.gui.expression.blocks.BlockChar; +import org.warp.picalculator.gui.expression.blocks.BlockParenthesis; import org.warp.picalculator.math.Function; import org.warp.picalculator.math.FunctionSingle; import org.warp.picalculator.math.MathContext; +import org.warp.picalculator.math.MathematicalSymbols; import org.warp.picalculator.math.rules.ExpandRule1; import org.warp.picalculator.math.rules.ExpandRule5; @@ -19,16 +22,16 @@ public class Negative extends FunctionSingle { @Override protected boolean isSolvable() { - if (parameter instanceof Number) { - return true; - } if (ExpandRule1.compare(this)) { return true; } if (ExpandRule5.compare(this)) { return true; } - return false; + if (parameter instanceof Number) { + return true; + } + return true; } @Override @@ -41,10 +44,10 @@ public class Negative extends FunctionSingle { result = ExpandRule1.execute(this); } else if (ExpandRule5.compare(this)) { result = ExpandRule5.execute(this); - } else if (parameter.isSimplified()) { + } else if (parameter instanceof Number) { try { final Number var = (Number) getParameter(); - result.add(var.multiply(new Number(mathContext, "-1"))); + result.add(var.multiply(new Number(mathContext, -1))); } catch (final NullPointerException ex) { throw new Error(Errors.ERROR); } catch (final NumberFormatException ex) { @@ -53,16 +56,7 @@ public class Negative extends FunctionSingle { throw new Error(Errors.NUMBER_TOO_SMALL); } } else { - final ObjectArrayList l1 = new ObjectArrayList<>(); - if (parameter.isSimplified()) { - l1.add(parameter); - } else { - l1.addAll(parameter.simplify()); - } - - for (final Function f : l1) { - result.add(new Negative(mathContext, f)); - } + result.add(new Multiplication(parameter.getMathContext(), new Number(parameter.getMathContext(), -1), parameter)); } return result; } @@ -82,7 +76,20 @@ public class Negative extends FunctionSingle { @Override public ObjectArrayList toBlock(MathContext context) throws Error { - // TODO Auto-generated method stub - throw new Error(Errors.NOT_IMPLEMENTED, "Unknown function " + getClass().getSimpleName()); + ObjectArrayList blocks = new ObjectArrayList(); + blocks.add(new BlockChar(MathematicalSymbols.MINUS)); + if (new Expression(context, getParameter()).parenthesisNeeded()) { + BlockParenthesis par = new BlockParenthesis(); + ObjectArrayList parBlocks = getParameter().toBlock(context); + for (Block b: parBlocks) { + par.getNumberContainer().appendBlockUnsafe(b); // Skips recomputeDimension + } + par.recomputeDimensions(); // Recompute dimensions after appendBlockUnsafe + blocks.add(par); + } else { + blocks.addAll(getParameter().toBlock(context)); + } + return blocks; + // throw new Error(Errors.NOT_IMPLEMENTED, "Unknown function " + getClass().getSimpleName()); } } diff --git a/src/main/java/org/warp/picalculator/math/functions/Variable.java b/src/main/java/org/warp/picalculator/math/functions/Variable.java index 74c1eea2..c0027e06 100755 --- a/src/main/java/org/warp/picalculator/math/functions/Variable.java +++ b/src/main/java/org/warp/picalculator/math/functions/Variable.java @@ -14,7 +14,7 @@ public class Variable implements Function { protected char var; protected final MathContext root; - protected V_TYPE type = V_TYPE.COEFFICIENT; + protected V_TYPE type = V_TYPE.CONSTANT; public Variable(MathContext root, char val, V_TYPE type) { this.root = root; @@ -93,7 +93,7 @@ public class Variable implements Function { } public static enum V_TYPE { - COEFFICIENT, UNKNOWN, SOLUTION + CONSTANT, VARIABLE, SOLUTION } @Override diff --git a/src/main/java/org/warp/picalculator/math/parser/MathParser.java b/src/main/java/org/warp/picalculator/math/parser/MathParser.java index 50f560f4..a89dfc47 100755 --- a/src/main/java/org/warp/picalculator/math/parser/MathParser.java +++ b/src/main/java/org/warp/picalculator/math/parser/MathParser.java @@ -15,7 +15,11 @@ import org.warp.picalculator.math.parser.features.FeatureChar; import org.warp.picalculator.math.parser.features.FeatureDivision; import org.warp.picalculator.math.parser.features.FeatureMultiplication; import org.warp.picalculator.math.parser.features.FeatureNumber; +import org.warp.picalculator.math.parser.features.FeaturePower; +import org.warp.picalculator.math.parser.features.FeaturePowerChar; +import org.warp.picalculator.math.parser.features.FeatureSubtraction; import org.warp.picalculator.math.parser.features.FeatureSum; +import org.warp.picalculator.math.parser.features.FeatureSumSubtraction; import org.warp.picalculator.math.parser.features.FeatureVariable; import org.warp.picalculator.math.parser.features.interfaces.Feature; import org.warp.picalculator.math.parser.steps.JoinNumberAndVariables; @@ -92,14 +96,15 @@ public class MathParser { lastElement = null; IntegerObj curIndex = new IntegerObj(initialIndex); while(curIndex.i >= 0 && curIndex.i < functionsList.size()) { - final Function f = functionsList.get(curIndex.i); + final int i = curIndex.i; + final Function f = functionsList.get(i); if (step.eval(curIndex, lastElement, f, functionsList)) { lastLoopDidSomething = true; } - lastElement=f; - curIndex.i+=stepQty; + lastElement = (i >= functionsList.size()) ? null : functionsList.get(i); + curIndex.i += stepQty; } } while (lastLoopDidSomething); Utils.out.print(Utils.OUTPUTLEVEL_DEBUG_MAX, "\tStatus: "); @@ -132,6 +137,8 @@ public class MathParser { features = makeNumbers(context, features); + features = makePowers(context, features); + features = convertFunctionChars(context, features); return features; @@ -172,7 +179,7 @@ public class MathParser { for (char var : MathematicalSymbols.variables) { if (featureChar == var) { - result = new FeatureVariable(featureChar, V_TYPE.UNKNOWN); + result = new FeatureVariable(featureChar, V_TYPE.VARIABLE); break; } } @@ -212,7 +219,7 @@ public class MathParser { break; } } - if (bcf.ch == '-' || bcf.ch == '.') { + if (bcf.ch == MathematicalSymbols.MINUS || bcf.ch == '.') { isNumber = true; } if (isNumber) { @@ -249,13 +256,13 @@ public class MathParser { final ObjectArrayList process = new ObjectArrayList<>(); Feature lastFeature = null; for (final Feature f : features) { - if (f instanceof FeatureChar && ((FeatureChar) f).ch == MathematicalSymbols.SUBTRACTION) { + if (f instanceof FeatureChar && (((FeatureChar) f).ch == MathematicalSymbols.SUBTRACTION || ((FeatureChar) f).ch == MathematicalSymbols.MINUS)) { boolean isNegativeOfNumber = false; if (lastFeature == null) { isNegativeOfNumber = true; } else if (lastFeature instanceof FeatureChar) { final FeatureChar lcf = (FeatureChar) lastFeature; - final char[] operators = MathematicalSymbols.functionsNSN; + final char[] operators = MathematicalSymbols.functionsAndSignums; for (final char operator : operators) { if (lcf.ch == operator) { isNegativeOfNumber = true; @@ -275,4 +282,32 @@ public class MathParser { } return process; } + + /** + * Make powers [12][^[15]] => [[12]^[15]] + * + * @param context + * @param features + * @return + * @throws Error + */ + private static ObjectArrayList makePowers(MathContext context, ObjectArrayList features) throws Error { + final ObjectArrayList process = new ObjectArrayList<>(); + + Feature lastFeature = null; + for (final Feature f : features) { + if (f instanceof FeaturePowerChar) { + if (lastFeature != null) { + process.set(process.size() - 1, new FeaturePower(lastFeature.toFunction(context), ((FeaturePowerChar) f).getChild())); + } else { + process.add(f); + } + } else { + process.add(f); + } + lastFeature = f; + } + + return process; + } } diff --git a/src/main/java/org/warp/picalculator/math/parser/features/FeatureNumber.java b/src/main/java/org/warp/picalculator/math/parser/features/FeatureNumber.java index 473d9fbe..4d5739f5 100755 --- a/src/main/java/org/warp/picalculator/math/parser/features/FeatureNumber.java +++ b/src/main/java/org/warp/picalculator/math/parser/features/FeatureNumber.java @@ -3,6 +3,7 @@ package org.warp.picalculator.math.parser.features; import org.warp.picalculator.Error; import org.warp.picalculator.math.Function; import org.warp.picalculator.math.MathContext; +import org.warp.picalculator.math.MathematicalSymbols; import org.warp.picalculator.math.functions.Number; import org.warp.picalculator.math.parser.features.interfaces.FeatureBasic; @@ -31,6 +32,16 @@ public class FeatureNumber implements FeatureBasic { @Override public Number toFunction(MathContext context) throws Error { - return new Number(context, getNumberString()); + String nmbstr = getNumberString(); + if (nmbstr.charAt(0) == '.') { + nmbstr = '0' + nmbstr; + } else if (nmbstr.charAt(nmbstr.length() - 1) == '.') { + nmbstr += "0"; + } else if (nmbstr.charAt(0) == MathematicalSymbols.MINUS) { + nmbstr += "1"; + } else if (nmbstr.charAt(0) == MathematicalSymbols.SUBTRACTION) { + nmbstr += "1"; + } + return new Number(context, nmbstr); } } diff --git a/src/main/java/org/warp/picalculator/math/parser/FeatureSubtraction.java b/src/main/java/org/warp/picalculator/math/parser/features/FeatureSubtraction.java similarity index 82% rename from src/main/java/org/warp/picalculator/math/parser/FeatureSubtraction.java rename to src/main/java/org/warp/picalculator/math/parser/features/FeatureSubtraction.java index bee84cba..cb3cd0a3 100644 --- a/src/main/java/org/warp/picalculator/math/parser/FeatureSubtraction.java +++ b/src/main/java/org/warp/picalculator/math/parser/features/FeatureSubtraction.java @@ -1,10 +1,9 @@ -package org.warp.picalculator.math.parser; +package org.warp.picalculator.math.parser.features; import org.warp.picalculator.Error; import org.warp.picalculator.math.Function; import org.warp.picalculator.math.MathContext; import org.warp.picalculator.math.functions.Subtraction; -import org.warp.picalculator.math.parser.features.FeatureDoubleImpl; import org.warp.picalculator.math.parser.features.interfaces.Feature; import org.warp.picalculator.math.parser.features.interfaces.FeatureDouble; diff --git a/src/main/java/org/warp/picalculator/math/parser/FeatureSumSubtraction.java b/src/main/java/org/warp/picalculator/math/parser/features/FeatureSumSubtraction.java similarity index 81% rename from src/main/java/org/warp/picalculator/math/parser/FeatureSumSubtraction.java rename to src/main/java/org/warp/picalculator/math/parser/features/FeatureSumSubtraction.java index 52a7aaf1..e91b4b3a 100644 --- a/src/main/java/org/warp/picalculator/math/parser/FeatureSumSubtraction.java +++ b/src/main/java/org/warp/picalculator/math/parser/features/FeatureSumSubtraction.java @@ -1,10 +1,9 @@ -package org.warp.picalculator.math.parser; +package org.warp.picalculator.math.parser.features; import org.warp.picalculator.Error; import org.warp.picalculator.math.Function; import org.warp.picalculator.math.MathContext; import org.warp.picalculator.math.functions.SumSubtraction; -import org.warp.picalculator.math.parser.features.FeatureDoubleImpl; import org.warp.picalculator.math.parser.features.interfaces.Feature; public class FeatureSumSubtraction extends FeatureDoubleImpl { diff --git a/src/main/java/org/warp/picalculator/math/parser/steps/JoinNumberAndVariables.java b/src/main/java/org/warp/picalculator/math/parser/steps/JoinNumberAndVariables.java index f3e58bda..45f8f97f 100644 --- a/src/main/java/org/warp/picalculator/math/parser/steps/JoinNumberAndVariables.java +++ b/src/main/java/org/warp/picalculator/math/parser/steps/JoinNumberAndVariables.java @@ -1,8 +1,10 @@ package org.warp.picalculator.math.parser.steps; import org.warp.picalculator.IntegerObj; +import org.warp.picalculator.Utils; import org.warp.picalculator.math.Function; import org.warp.picalculator.math.MathContext; +import org.warp.picalculator.math.functions.Division; import org.warp.picalculator.math.functions.Multiplication; import org.warp.picalculator.math.functions.Number; import org.warp.picalculator.math.functions.Variable; @@ -20,11 +22,11 @@ public class JoinNumberAndVariables implements MathParserStep { @Override public boolean eval(IntegerObj curIndex, Function lastFunction, Function currentFunction, ObjectArrayList functionsList) { - if (currentFunction instanceof Number | currentFunction instanceof Variable) { + if (currentFunction instanceof Number | currentFunction instanceof Variable | currentFunction instanceof Division) { if (lastFunction instanceof Variable | lastFunction instanceof Number | (lastFunction instanceof Multiplication && ((Multiplication)lastFunction).getParameter2() != null)) { - final Function var = lastFunction; - final Function numb = currentFunction; - functionsList.set(curIndex.i, new Multiplication(context, numb, var)); + final Function a = currentFunction; + final Function b = lastFunction; + functionsList.set(curIndex.i, new Multiplication(context, a, b)); functionsList.remove(curIndex.i + 1); return true; } diff --git a/src/main/java/org/warp/picalculator/math/rules/FractionsRule14.java b/src/main/java/org/warp/picalculator/math/rules/FractionsRule14.java index 3a906f9d..fb13e395 100755 --- a/src/main/java/org/warp/picalculator/math/rules/FractionsRule14.java +++ b/src/main/java/org/warp/picalculator/math/rules/FractionsRule14.java @@ -3,7 +3,6 @@ package org.warp.picalculator.math.rules; import org.warp.picalculator.Error; import org.warp.picalculator.math.Function; import org.warp.picalculator.math.functions.Division; -import org.warp.picalculator.math.functions.Expression; import org.warp.picalculator.math.functions.Multiplication; import it.unimi.dsi.fastutil.objects.ObjectArrayList; @@ -62,21 +61,21 @@ public class FractionsRule14 { b = div1.getParameter2(); c = div2.getParameter1(); d = div2.getParameter2(); - final Division div = new Division(fnc.getMathContext(), new Multiplication(fnc.getMathContext(), new Expression(fnc.getMathContext(), a), new Expression(fnc.getMathContext(), c)), new Multiplication(fnc.getMathContext(), new Expression(fnc.getMathContext(), b), new Expression(fnc.getMathContext(), d))); + final Division div = new Division(fnc.getMathContext(), new Multiplication(fnc.getMathContext(), a, c), new Multiplication(fnc.getMathContext(), b, d)); result.add(div); } else if (fnc.getParameter1() instanceof Division) { final Division div1 = (Division) fnc.getParameter1(); a = div1.getParameter1(); b = div1.getParameter2(); c = fnc.getParameter2(); - final Division div = new Division(fnc.getMathContext(), new Multiplication(fnc.getMathContext(), new Expression(fnc.getMathContext(), a), new Expression(fnc.getMathContext(), c)), b); + final Division div = new Division(fnc.getMathContext(), new Multiplication(fnc.getMathContext(), a, c), b); result.add(div); } else if (fnc.getParameter2() instanceof Division) { final Division div2 = (Division) fnc.getParameter2(); a = fnc.getParameter1(); c = div2.getParameter1(); d = div2.getParameter2(); - final Division div = new Division(fnc.getMathContext(), new Multiplication(fnc.getMathContext(), new Expression(fnc.getMathContext(), a), new Expression(fnc.getMathContext(), c)), d); + final Division div = new Division(fnc.getMathContext(), new Multiplication(fnc.getMathContext(), a, c), d); result.add(div); } return result; diff --git a/src/main/java/org/warp/picalculator/math/rules/methods/DivisionRule1.java b/src/main/java/org/warp/picalculator/math/rules/methods/DivisionRule1.java index c7c7d971..9f65b48a 100755 --- a/src/main/java/org/warp/picalculator/math/rules/methods/DivisionRule1.java +++ b/src/main/java/org/warp/picalculator/math/rules/methods/DivisionRule1.java @@ -11,7 +11,7 @@ import it.unimi.dsi.fastutil.objects.ObjectArrayList; /** * Division method
- * Example: (XY)/(YZ) = X/Z + * Example: (XY)/(YZ) = Y/Y * X/Z * * @author Andrea Cavalli * @@ -19,18 +19,19 @@ import it.unimi.dsi.fastutil.objects.ObjectArrayList; public class DivisionRule1 { public static boolean compare(Division f) { - return f.getParameter1().isSimplified() && f.getParameter2().isSimplified() && !(f.getParameter1() instanceof Number && f.getParameter2() instanceof Number) && getFirstWorkingDivisionCouple(getDivisionElements(f)) != null; + return f.getParameter1().isSimplified() && f.getParameter2().isSimplified() && (f.getParameter1() instanceof Multiplication || f.getParameter2() instanceof Multiplication) && getFirstWorkingDivisionCouple(getDivisionElements(f)) != null; } public static ObjectArrayList execute(Division f) throws Error { + System.out.println(f); final MathContext root = f.getMathContext(); Function result; - final ObjectArrayList elements = getDivisionElements(f); + final ObjectArrayList[] elements = getDivisionElements(f); final int[] workingElementCouple = getFirstWorkingDivisionCouple(elements); - final Function elem1 = elements.get(workingElementCouple[0]); - final Function elem2 = elements.get(workingElementCouple[1]); + final Function elem1 = elements[0].get(workingElementCouple[0]); + final Function elem2 = elements[1].get(workingElementCouple[1]); - final int size = elements.size(); + /*final int size = elements.size(); Function prec = new Multiplication(root, elem1, elem2); for (int i = size - 1; i >= 0; i--) { if (i != workingElementCouple[0] & i != workingElementCouple[1]) { @@ -38,17 +39,42 @@ public class DivisionRule1 { final Function b = elements.get(i); prec = new Multiplication(root, a, b); } + }*/ + + + final int[] size = new int[] {elements[0].size(), elements[1].size()}; + Function separatedDivision = new Division(root, elem1, elem2); + + Function[] resultDivisionArray = new Function[2]; + Function prec; + for (int part = 0; part < 2; part++) { + prec = null; + for (int i = size[part] - 1; i >= 0; i--) { + if (i != workingElementCouple[part]) { + if (prec == null) { + prec = elements[part].get(i); + } else { + final Function a = elements[part].get(i); + final Function b = prec; + prec = new Multiplication(root, a, b); + } + } + } + if (prec == null) { + prec = new Number(root, 1); + } + resultDivisionArray[part] = prec; } - result = prec; + result = new Multiplication(root, separatedDivision, new Division(root, resultDivisionArray[0], resultDivisionArray[1])); final ObjectArrayList results = new ObjectArrayList<>(); results.add(result); return results; } - private static ObjectArrayList getDivisionElements(Division division) { - /* + @SuppressWarnings("unchecked") + private static ObjectArrayList[] getDivisionElements(Division division) { final ObjectArrayList elementsNumerator = new ObjectArrayList<>(); Function numMult = division.getParameter1(); while (numMult instanceof Multiplication) { @@ -58,42 +84,35 @@ public class DivisionRule1 { elementsNumerator.add(numMult); final ObjectArrayList elementsDenominator = new ObjectArrayList<>(); - Function denomMult = division.getParameter1(); + Function denomMult = division.getParameter2(); while (denomMult instanceof Multiplication) { elementsDenominator.add(((Multiplication) denomMult).getParameter1()); denomMult = ((Multiplication) denomMult).getParameter2(); } elementsDenominator.add(denomMult); - - return elements; - */ - return null; + + return new ObjectArrayList[] {elementsNumerator, elementsDenominator}; } - private static int[] getFirstWorkingDivisionCouple(ObjectArrayList elements) { - /* - final int size = elements.size(); + private static int[] getFirstWorkingDivisionCouple(ObjectArrayList[] elements) { + final int[] size = new int[] {elements[0].size(), elements[1].size()}; Function a; Function b; - if (elements.size() == 2) { + if (elements[0].size() + elements[1].size() <= 2) { return null; } - for (int i = 0; i < size; i++) { - a = elements.get(i); - for (int j = 0; j < size; j++) { - b = elements.get(j); - if (i != j) { - Function testFunc; - testFunc = new Multiplication(root, a, b); - if (!testFunc.isSimplified()) { - return new int[] { i, j }; - } + for (int i = 0; i < size[0]; i++) { + a = elements[0].get(i); + for (int j = 0; j < size[1]; j++) { + b = elements[1].get(j); + Function testFunc; + testFunc = new Division(a.getMathContext(), a, b); + if (!testFunc.isSimplified()) { + return new int[] { i, j }; } } } return null; - */ - return null; } }