From 131fc493391811fe3c2c206c4b204d5986fcdb95 Mon Sep 17 00:00:00 2001 From: serso Date: Sat, 22 Oct 2011 17:59:40 +0400 Subject: [PATCH] symbolic calculations --- .../model/FromJsclSimplifyTextProcessor.java | 94 ++++++++++++++++++- .../FromJsclSimplifyTextProcessorTest.java | 32 ++++++- 2 files changed, 116 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/solovyev/android/calculator/model/FromJsclSimplifyTextProcessor.java b/src/main/java/org/solovyev/android/calculator/model/FromJsclSimplifyTextProcessor.java index e39a0e35..aafe567f 100644 --- a/src/main/java/org/solovyev/android/calculator/model/FromJsclSimplifyTextProcessor.java +++ b/src/main/java/org/solovyev/android/calculator/model/FromJsclSimplifyTextProcessor.java @@ -2,11 +2,14 @@ package org.solovyev.android.calculator.model; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.solovyev.android.calculator.StartsWithFinder; +import org.solovyev.android.calculator.math.Functions; import org.solovyev.android.calculator.math.MathType; import org.solovyev.common.utils.CollectionsUtils; import org.solovyev.common.utils.Finder; +import java.util.Arrays; +import java.util.List; + /** * User: serso * Date: 10/20/11 @@ -50,11 +53,12 @@ public class FromJsclSimplifyTextProcessor implements TextProcessor { replaceSystemVars(sb, number); - if (mathType == MathType.constant) { + if (mathType == MathType.constant){ sb.append(mathTypeResult.getMatch()); i += mathTypeResult.getMatch().length() - 1; - } else if (ch == '*') { - sb.append("×"); + } else if ( mathType == MathType.function) { + sb.append(fromJsclFunction(mathTypeResult.getMatch())); + i += mathTypeResult.getMatch().length() - 1; } else { sb.append(ch); } @@ -73,10 +77,87 @@ public class FromJsclSimplifyTextProcessor implements TextProcessor { replaceSystemVars(sb, number); + return removeMultiplicationSigns(sb.toString()); + } + + @NotNull + private static String fromJsclFunction(@NotNull String function) { + final String result; + + if (function.equals(Functions.LN_JSCL)) { + result = Functions.LN; + } else if (function.equals(Functions.SQRT_JSCL)) { + result = Functions.SQRT; + } else { + result = function; + } + + return result; + } + + @NotNull + private String removeMultiplicationSigns(String s) { + final StringBuilder sb = new StringBuilder(); + + MathType.Result mathTypeBefore; + MathType.Result mathType = null; + MathType.Result mathTypeAfter = null; + + for (int i = 0; i < s.length(); i++) { + mathTypeBefore = mathType; + if (mathTypeAfter == null) { + mathType = MathType.getType(s, i); + } else { + mathType = mathTypeAfter; + } + + char ch = s.charAt(i); + if (ch == '*') { + if (i + 1 < s.length()) { + mathTypeAfter = MathType.getType(s, i + 1); + } else { + mathTypeAfter = null; + } + + if (needMultiplicationSign(mathTypeBefore == null ? null : mathTypeBefore.getMathType(), mathTypeAfter == null ? null : mathTypeAfter.getMathType())) { + sb.append("×"); + } + + } else { + if (mathType.getMathType() == MathType.constant || mathType.getMathType() == MathType.function) { + sb.append(mathType.getMatch()); + i += mathType.getMatch().length() - 1; + } else { + sb.append(ch); + } + mathTypeAfter = null; + } + + } + return sb.toString(); } - private void replaceSystemVars(StringBuilder sb, String number) { + private final List mathTypes = Arrays.asList(MathType.function, MathType.constant); + + private boolean needMultiplicationSign(@Nullable MathType mathTypeBefore, @Nullable MathType mathTypeAfter) { + if (mathTypeBefore == null || mathTypeAfter == null) { + return true; + } else if (mathTypes.contains(mathTypeBefore) || mathTypes.contains(mathTypeAfter)) { + return false; + } else if ( mathTypeBefore == MathType.close_group_symbol ) { + return false; + } else if ( mathTypeAfter == MathType.open_group_symbol ) { + return false; + } + + return true; + } + + @Nullable + private MathType replaceSystemVars(StringBuilder sb, String number) { + MathType result = null; + if (number != null) { final String finalNumber = number; final Var var = CollectionsUtils.get(CalculatorEngine.instance.getVarsRegister().getSystemVars(), new Finder() { @@ -89,8 +170,11 @@ public class FromJsclSimplifyTextProcessor implements TextProcessor { if (var != null) { sb.delete(sb.length() - number.length(), sb.length()); sb.append(var.getName()); + result = MathType.constant; } } + + return result; } } diff --git a/src/test/java/org/solovyev/android/calculator/model/FromJsclSimplifyTextProcessorTest.java b/src/test/java/org/solovyev/android/calculator/model/FromJsclSimplifyTextProcessorTest.java index 49503d8d..bd9fc8c4 100644 --- a/src/test/java/org/solovyev/android/calculator/model/FromJsclSimplifyTextProcessorTest.java +++ b/src/test/java/org/solovyev/android/calculator/model/FromJsclSimplifyTextProcessorTest.java @@ -1,10 +1,8 @@ package org.solovyev.android.calculator.model; import org.junit.Assert; -import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; -import org.solovyev.android.calculator.jscl.JsclOperation; /** * User: serso @@ -21,12 +19,36 @@ public class FromJsclSimplifyTextProcessorTest { @Test public void testProcess() throws Exception { FromJsclSimplifyTextProcessor tp = new FromJsclSimplifyTextProcessor(); - Assert.assertEquals("t11×e", tp.process("t11*2.718281828459045")); + Assert.assertEquals("t11e", tp.process("t11*2.718281828459045")); Assert.assertEquals("e", tp.process("2.718281828459045")); - Assert.assertEquals("te×e", tp.process("t2.718281828459045*2.718281828459045")); + Assert.assertEquals("tee", tp.process("t2.718281828459045*2.718281828459045")); CalculatorEngine.instance.getVarsRegister().addVar(null, new Var.Builder("t2.718281828459045", "2")); - Assert.assertEquals("t2.718281828459045×e", tp.process("t2.718281828459045*2.718281828459045")); + Assert.assertEquals("t2.718281828459045e", tp.process("t2.718281828459045*2.718281828459045")); + Assert.assertEquals("t×", tp.process("t*")); + Assert.assertEquals("×t", tp.process("*t")); + Assert.assertEquals("t×2", tp.process("t*2")); + Assert.assertEquals("2×t", tp.process("2*t")); + CalculatorEngine.instance.getVarsRegister().addVar(null, new Var.Builder("t", (String)null)); + Assert.assertEquals("t×", tp.process("t*")); + Assert.assertEquals("×t", tp.process("*t")); + + Assert.assertEquals("t2", tp.process("t*2")); + Assert.assertEquals("2t", tp.process("2*t")); + + Assert.assertEquals("t^2×2", tp.process("t^2*2")); + Assert.assertEquals("2t^2", tp.process("2*t^2")); + + Assert.assertEquals("t^[2×2t]", tp.process("t^[2*2*t]")); + Assert.assertEquals("2t^2[2t]", tp.process("2*t^2[2*t]")); + + CalculatorEngine.instance.getVarsRegister().addVar(null, new Var.Builder("k", (String)null)); + Assert.assertEquals("(t+2k)[k+2t]", tp.process("(t+2*k)*[k+2*t]")); + Assert.assertEquals("(te+2k)e[k+2te]", tp.process("(t*e+2*k)*e*[k+2*t*e]")); + + + Assert.assertEquals("tln(3)", tp.process("t*log(3)")); + Assert.assertEquals("t√(3)", tp.process("t*sqrt(3)")); } }