0

What I'm trying to accomplish:

I'm trying to create a regex program that can do the following:

A^C + B^C = (A + B)^C

My regex:

/(^|[^^*/\dt.-])(-?)(\d+\.?(?:\d+)?)x(?:(?:\^(\d+\.?(?:\d+)?))|(?:\^\(([\s\S]+)\)))?([+-])(-?)(\d+\.?(?:\d+)?)x(?:(?:\^(\d+\.?(?:\d+)?))|(?:\^\(([\s\S]+)\)))?(?=$|[^(^*/!\d\.])/

Broken down into chunks:

/(^|[^^*/\dt.-]) characters that shouldn't precede the match

(-?)(\d+\.?(?:\d+)?)x a (negative) number followed by an x

(?:(?:\^(\d+\.?(?:\d+)?))|(?:\^\(([\s\S]+)\)))? possibly x raised to a number or something between parentheses

([+-]) plus or minus

(-?)(\d+\.?(?:\d+)?)x a (negative) number followed by an x

(?:(?:\^(\d+\.?(?:\d+)?))|(?:\^\(([\s\S]+)\)))? Same power thing

(?=$|[^(^*/!\d\.])/ characters that shouldn't follow the match

Sample text:

What it does is it finds matches like the fourth example here, where the powers, between the parentheses aren't the same. I then check in the function I provide in the replace regex method that the powers are the same, and the equation can be simplified.

5-3x+7x //Here it finds 3x+7x

3x^2+4x^2-5 //Here it finds 3x^2+4x^2

3x^2+5x^3+8x^3 //Here it finds 3x^2 + 5x^3, but not 5x^3 + 8x^3 <-- The problem

3x^(5x+7x)+5x^(6x+6x) //Here it finds 3x^(5x+7x)+5x^(6x+6x) but not the inner 5x+7x and 6x+6x <--Also the problem

What I've tried:

I tried implementing this solution, but I don't know how to use that with the regex replace function: stackoverflow: How can I match overlapping strings with regex?

My code:

Expected result: 3x^2+13x^3
Actual result: 3x^2+5x^3+8x^3 (same as input)

var solvedEquation = "3x^2+5x^3+8x^3";

addXterms();

console.log(solvedEquation);

function addXterms() {
  var legitPattern = true;
  var addVariablesPattern = /(^|[^^*/\dt.-])(-?)(\d+\.?(?:\d+)?)x(?:(?:\^(\d+\.?(?:\d+)?))|(?:\^\(([\s\S]+)\)))?([+-])(-?)(\d+\.?(?:\d+)?)x(?:(?:\^(\d+\.?(?:\d+)?))|(?:\^\(([\s\S]+)\)))?(?=$|[^(^*/!\d\.])/g;
  while (addVariablesPattern.test(solvedEquation)) {
    solvedEquation = solvedEquation.replace(addVariablesPattern, function (match, operator1, minusSign1, num1, numPower1, parPower1, operator2, minusSign2, num2, numPower2, parPower2) {
        var result;

        if (numPower1 == numPower2 && parPower1 == parPower2) {
            num1 = parseFloat(num1) * (minusSign1 == "-" ? -1 : 1);
            num2 = parseFloat(num2) * (minusSign2 == "-" ? -1 : 1);

            if (operator2 == "+") {
                result = num1 + num2;
            } else {
                result = num1 - num2;
            }
            equationSolved = false;

            if (numPower1 != "" && typeof numPower1 != "undefined") {
                return operator1 + result + "x^" + numPower1;
            } else if (parPower1 != "" && typeof parPower1 != "undefined") {
                return operator1 + result + "x^(" + parPower1 + ")";
            } else {
                return operator1 + result + "x";
            }

        } else {
            legitPattern = false;
            return match;
        }
    });
  }
}
Community
  • 1
  • 1
The Coding Wombat
  • 805
  • 1
  • 10
  • 29
  • I would suggest breaking down your regex in multiple chunks: don't try and do it all at once. First parse the complex exponents (those that need to be computed), then break down your equation along their operators and compute these elements, then run your main simplify function – kuzyn May 03 '17 at 22:04
  • What if the complex exponents are also of the format A^(B^(Dx + Ex) + C^(Dx + Ex)) ? How do I make my program recognize them then? I don't see a way of breaking up my regex so it would do those first. If you do, please explain in a comment or answer. – The Coding Wombat May 03 '17 at 22:13
  • Or if they can't be computed, that the exponent is for example (3x^3 + 5x^2), this can't be added up, but if you have this equation: `2x^(3x^3 + 5x^2) + 3x^(3x^3 + 5x^2)` it still can be simplified to `5x^(3x^3 + 5x^2)` – The Coding Wombat May 03 '17 at 22:19
  • @kuzyn do you know of a way? – The Coding Wombat May 04 '17 at 11:38
  • Just to be clear, what you are trying to do is either impossible to do in one pass, or rather shouldn't be done in one pass because it will be unmaintainable. You will need to create smaller functions that look for different things. It is not complicated, but you will need to code a bit of logic to compare your variables. The regex to get each subpart is the simplest part of your problem. Just break up your matching function into smaller functions. For nested exponents, that means that you can simply call the appropriate function recursively as many time as needed. – kuzyn May 04 '17 at 12:51
  • As others have indicated, it would be best to parse the equation in the first place, _then_ figure out if it could be simplified. – Whothehellisthat May 04 '17 at 19:12
  • @Whothehellisthat What do you mean by parse? Isn't simplifying parsing? English isn't my native language, sorry. – The Coding Wombat May 04 '17 at 22:07

0 Answers0