From fbf4514404982547d5c1bfbf8ced4f640dcc4700 Mon Sep 17 00:00:00 2001 From: markus polleryd Date: Tue, 16 Jan 2018 13:32:51 +0100 Subject: [PATCH 1/6] Expressions with polynomials divided by polynomials are now simplified --- .../fractionsSearch/cancelLikeTerms.js | 53 +++++++++++++++++-- .../fractionsSearch/cancelLikeTerms.test.js | 6 ++- test/simplifyExpression/simplify.test.js | 2 + 3 files changed, 54 insertions(+), 7 deletions(-) diff --git a/lib/simplifyExpression/fractionsSearch/cancelLikeTerms.js b/lib/simplifyExpression/fractionsSearch/cancelLikeTerms.js index ca8f7763..2c5f879a 100644 --- a/lib/simplifyExpression/fractionsSearch/cancelLikeTerms.js +++ b/lib/simplifyExpression/fractionsSearch/cancelLikeTerms.js @@ -240,7 +240,6 @@ function cancelTerms(numerator, denominator) { if (print.ascii(numerator) === print.ascii(denominator)) { return new CancelOutStatus(null, null, true); } - // case 2: they're both exponent nodes with the same base // e.g. (2x+5)^8 and (2x+5)^2 if (Node.Type.isOperator(numerator, '^') && @@ -257,16 +256,25 @@ function cancelTerms(numerator, denominator) { numerator.args[1] = newExponent; return new CancelOutStatus(numerator, null, true); } - // case 3: they're both polynomial terms, check if they have the same symbol // e.g. 4x^2 / 5x^2 => 4 / 5 // e.g. 4x^3 / 5x^2 => 4x^(3-2) / 5 + // Case 3.1: they're both polynomial terms with different symbols but with coefficients + // e.g 20x / 40y => 1x / 2y + // e.g 60x / 40y => 3x / 2y + // e.g 4x / 2y => 2x / y if (Node.PolynomialTerm.isPolynomialTerm(numerator) && Node.PolynomialTerm.isPolynomialTerm(denominator)) { const numeratorTerm = new Node.PolynomialTerm(numerator); const denominatorTerm = new Node.PolynomialTerm(denominator); if (numeratorTerm.getSymbolName() !== denominatorTerm.getSymbolName()) { - return new CancelOutStatus(numerator, denominator); + if (Node.Type.isOperator(numerator, '*') && Node.Type.isOperator(denominator, '*')) { + // case 3.1 + return cancelCoeffs(numerator, denominator); + } + else { + return new CancelOutStatus(numerator, denominator); + } } const numeratorExponent = numeratorTerm.getExponentNode(true); let denominatorExponent = denominatorTerm.getExponentNode(true); @@ -294,7 +302,6 @@ function cancelTerms(numerator, denominator) { // or is multiplication node // e.g. 2 / 4x -> 1 / 2x // e.g. ignore cases like: 2 / a and 2 / x^2 - if (Node.Type.isConstant(numerator) && Node.Type.isOperator(denominator, '*') && Node.PolynomialTerm.isPolynomialTerm(denominator)) { @@ -330,7 +337,6 @@ function cancelTerms(numerator, denominator) { // case 5: both numerator and denominator are numbers within a more complicated fraction // e.g. (35 * nthRoot (7)) / (5 * nthRoot(5)) -> (7 * nthRoot(7)) / nthRoot(5) - if (Node.Type.isConstant(numerator) && Node.Type.isConstant(denominator)) { const frac = Node.Creator.operator('/', [numerator, denominator]); const reduceStatus = divideByGCD(frac); @@ -371,4 +377,41 @@ function isMultiplicationOfTerms(node) { !Node.PolynomialTerm.isPolynomialTerm(node)); } +function cancelCoeffs(numerator, denominator){ + const denominatorTerm = new Node.PolynomialTerm(denominator); + const numeratorTerm = new Node.PolynomialTerm(numerator); + + const denominatorCoeff = denominatorTerm.getCoeffNode(); + const denomintorVariable = denominatorTerm.getSymbolNode(); + const denominatorExponent = denominatorTerm.getExponentNode(); + + const numeratorCoeff = numeratorTerm.getCoeffNode(); + const numeratorVariable = numeratorTerm.getSymbolNode(); + const numeratorExponent = numeratorTerm.getExponentNode(); + + // simplify a constant fraction (e.g 2 / 4) + const frac = Node.Creator.operator('/', [numeratorCoeff, denominatorCoeff]); + + let newCoeff = clone(denominatorCoeff); + const reduceStatus = divideByGCD(frac); + + if (!reduceStatus.hasChanged()) { + return new CancelOutStatus(numerator, denominator, false); + } + + // Sometimes the fraction reduces to a constant e.g. 6 / 2 -> 3, + // in which case `newCoeff` (the denominator coefficient) should be null + if (Node.Type.isConstant(reduceStatus.newNode)) { + numerator = Node.Creator.polynomialTerm(numeratorVariable,numeratorExponent,reduceStatus.newNode); + newCoeff = null; + } + else { + numerator = Node.Creator.polynomialTerm(numeratorVariable,numeratorExponent,reduceStatus.newNode.args[0]); + newCoeff = reduceStatus.newNode.args[1]; + } + denominator = Node.Creator.polynomialTerm(denomintorVariable, denominatorExponent, newCoeff); + + return new CancelOutStatus(numerator, denominator, true); +} + module.exports = cancelLikeTerms; diff --git a/test/simplifyExpression/fractionsSearch/cancelLikeTerms.test.js b/test/simplifyExpression/fractionsSearch/cancelLikeTerms.test.js index a877684e..c94fafa5 100644 --- a/test/simplifyExpression/fractionsSearch/cancelLikeTerms.test.js +++ b/test/simplifyExpression/fractionsSearch/cancelLikeTerms.test.js @@ -24,9 +24,11 @@ describe('cancel like terms', function () { ['2/ (4x)', '1 / (2x)'], ['2/ (4x^2)', '1 / (2x^2)'], ['2 a / a', '2'], - ['(35 * nthRoot (7)) / (5 * nthRoot(5))','(7 * nthRoot(7)) / nthRoot(5)'], + ['(35 * nthRoot (7)) / (5 * nthRoot(5))', '(7 * nthRoot(7)) / nthRoot(5)'], ['3/(9r^2)', '1 / (3r^2)'], - ['6/(2x)', '3 / (x)'] + ['6/(2x)', '3 / (x)'], + ['(40 * x) / (20 * y)', '(2x) / (y)'], + ['(20 * x) / (40 * y)', '(x) / (2y)'], ]; tests.forEach(t => testCancelLikeTerms(t[0], t[1])); diff --git a/test/simplifyExpression/simplify.test.js b/test/simplifyExpression/simplify.test.js index 6fec2487..f42b5429 100644 --- a/test/simplifyExpression/simplify.test.js +++ b/test/simplifyExpression/simplify.test.js @@ -51,6 +51,8 @@ describe('can simplify with division', function () { ['2x/x', '2'], ['2x/4/3', '1/6 x'], ['((2+x)(3+x))/(2+x)', '3 + x'], + ['(20 * x) / (5 * (40 * y))', 'x / (10y)'], + ['400 * z / ((20 * x) / (5 * (40 * y)))', '(4000y * z) / x'] ]; tests.forEach(t => testSimplify(t[0], t[1], t[2])); // TODO: factor the numerator to cancel out with denominator From 6e10e9ea9ddefe0baee4c0cf8a1fa5b448898269 Mon Sep 17 00:00:00 2001 From: markus polleryd Date: Wed, 17 Jan 2018 11:43:14 +0100 Subject: [PATCH 2/6] minor naming/style changes --- .../fractionsSearch/cancelLikeTerms.js | 23 ++++++++++--------- .../fractionsSearch/cancelLikeTerms.test.js | 3 +++ test/simplifyExpression/simplify.test.js | 5 +++- 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/lib/simplifyExpression/fractionsSearch/cancelLikeTerms.js b/lib/simplifyExpression/fractionsSearch/cancelLikeTerms.js index 2c5f879a..d8fc87bf 100644 --- a/lib/simplifyExpression/fractionsSearch/cancelLikeTerms.js +++ b/lib/simplifyExpression/fractionsSearch/cancelLikeTerms.js @@ -259,8 +259,8 @@ function cancelTerms(numerator, denominator) { // case 3: they're both polynomial terms, check if they have the same symbol // e.g. 4x^2 / 5x^2 => 4 / 5 // e.g. 4x^3 / 5x^2 => 4x^(3-2) / 5 - // Case 3.1: they're both polynomial terms with different symbols but with coefficients - // e.g 20x / 40y => 1x / 2y + // case 3.1: they're both polynomial terms with different symbols but with coefficients + // e.g 20x / 40y => x / 2y // e.g 60x / 40y => 3x / 2y // e.g 4x / 2y => 2x / y if (Node.PolynomialTerm.isPolynomialTerm(numerator) && @@ -382,7 +382,7 @@ function cancelCoeffs(numerator, denominator){ const numeratorTerm = new Node.PolynomialTerm(numerator); const denominatorCoeff = denominatorTerm.getCoeffNode(); - const denomintorVariable = denominatorTerm.getSymbolNode(); + const denominatorVariable = denominatorTerm.getSymbolNode(); const denominatorExponent = denominatorTerm.getExponentNode(); const numeratorCoeff = numeratorTerm.getCoeffNode(); @@ -392,7 +392,6 @@ function cancelCoeffs(numerator, denominator){ // simplify a constant fraction (e.g 2 / 4) const frac = Node.Creator.operator('/', [numeratorCoeff, denominatorCoeff]); - let newCoeff = clone(denominatorCoeff); const reduceStatus = divideByGCD(frac); if (!reduceStatus.hasChanged()) { @@ -400,18 +399,20 @@ function cancelCoeffs(numerator, denominator){ } // Sometimes the fraction reduces to a constant e.g. 6 / 2 -> 3, - // in which case `newCoeff` (the denominator coefficient) should be null + // in which case the denominator coefficient should be null + let newDenominator = null; + let newNumerator = null; if (Node.Type.isConstant(reduceStatus.newNode)) { - numerator = Node.Creator.polynomialTerm(numeratorVariable,numeratorExponent,reduceStatus.newNode); - newCoeff = null; + newNumerator = Node.Creator.polynomialTerm(numeratorVariable, numeratorExponent, reduceStatus.newNode); + newDenominator = null; } else { - numerator = Node.Creator.polynomialTerm(numeratorVariable,numeratorExponent,reduceStatus.newNode.args[0]); - newCoeff = reduceStatus.newNode.args[1]; + newNumerator = Node.Creator.polynomialTerm(numeratorVariable, numeratorExponent, reduceStatus.newNode.args[0]); + newDenominator = reduceStatus.newNode.args[1]; } - denominator = Node.Creator.polynomialTerm(denomintorVariable, denominatorExponent, newCoeff); + denominator = Node.Creator.polynomialTerm(denominatorVariable, denominatorExponent, newDenominator); - return new CancelOutStatus(numerator, denominator, true); + return new CancelOutStatus(newNumerator, denominator, true); } module.exports = cancelLikeTerms; diff --git a/test/simplifyExpression/fractionsSearch/cancelLikeTerms.test.js b/test/simplifyExpression/fractionsSearch/cancelLikeTerms.test.js index c94fafa5..6fe79df6 100644 --- a/test/simplifyExpression/fractionsSearch/cancelLikeTerms.test.js +++ b/test/simplifyExpression/fractionsSearch/cancelLikeTerms.test.js @@ -29,6 +29,9 @@ describe('cancel like terms', function () { ['6/(2x)', '3 / (x)'], ['(40 * x) / (20 * y)', '(2x) / (y)'], ['(20 * x) / (40 * y)', '(x) / (2y)'], + ['20x / (40y)', 'x / (2y)'], + ['60x / (40y)', '3x / (2y)'], + ['4x / (2y)', '2x / (y)'] ]; tests.forEach(t => testCancelLikeTerms(t[0], t[1])); diff --git a/test/simplifyExpression/simplify.test.js b/test/simplifyExpression/simplify.test.js index f42b5429..d6a30840 100644 --- a/test/simplifyExpression/simplify.test.js +++ b/test/simplifyExpression/simplify.test.js @@ -52,7 +52,10 @@ describe('can simplify with division', function () { ['2x/4/3', '1/6 x'], ['((2+x)(3+x))/(2+x)', '3 + x'], ['(20 * x) / (5 * (40 * y))', 'x / (10y)'], - ['400 * z / ((20 * x) / (5 * (40 * y)))', '(4000y * z) / x'] + ['400 * z / ((20 * x) / (5 * (40 * y)))', '(4000y * z) / x'], + ['20x / (40y)', 'x / (2y)'], + ['60x / (40y)', '3x / (2y)'], + ['4x / (2y)', '2x / y'] ]; tests.forEach(t => testSimplify(t[0], t[1], t[2])); // TODO: factor the numerator to cancel out with denominator From d2ec124648008fa59840fd2741d68718f683bf3e Mon Sep 17 00:00:00 2001 From: markus polleryd Date: Wed, 17 Jan 2018 11:54:31 +0100 Subject: [PATCH 3/6] minor thought fail fix --- .../fractionsSearch/cancelLikeTerms.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/simplifyExpression/fractionsSearch/cancelLikeTerms.js b/lib/simplifyExpression/fractionsSearch/cancelLikeTerms.js index d8fc87bf..85f84b4b 100644 --- a/lib/simplifyExpression/fractionsSearch/cancelLikeTerms.js +++ b/lib/simplifyExpression/fractionsSearch/cancelLikeTerms.js @@ -400,19 +400,19 @@ function cancelCoeffs(numerator, denominator){ // Sometimes the fraction reduces to a constant e.g. 6 / 2 -> 3, // in which case the denominator coefficient should be null - let newDenominator = null; + let newDenominatorCoeff = null; let newNumerator = null; if (Node.Type.isConstant(reduceStatus.newNode)) { newNumerator = Node.Creator.polynomialTerm(numeratorVariable, numeratorExponent, reduceStatus.newNode); - newDenominator = null; + newDenominatorCoeff = null; } else { newNumerator = Node.Creator.polynomialTerm(numeratorVariable, numeratorExponent, reduceStatus.newNode.args[0]); - newDenominator = reduceStatus.newNode.args[1]; + newDenominatorCoeff = reduceStatus.newNode.args[1]; } - denominator = Node.Creator.polynomialTerm(denominatorVariable, denominatorExponent, newDenominator); + const newDenominator = Node.Creator.polynomialTerm(denominatorVariable, denominatorExponent, newDenominatorCoeff); - return new CancelOutStatus(newNumerator, denominator, true); + return new CancelOutStatus(newNumerator, newDenominator, true); } module.exports = cancelLikeTerms; From 7d4515ab45d691927247249eccee25af91fe7476 Mon Sep 17 00:00:00 2001 From: markus polleryd Date: Wed, 16 May 2018 10:34:16 +0200 Subject: [PATCH 4/6] fixed... --- .../fractionsSearch/addConstantFractions.js | 70 +++++++++++++--- .../fractionsSearch/cancelLikeTerms.js | 83 ++++++++++++++++++- .../fractionsSearch/divideByGCD.js | 19 +++-- 3 files changed, 153 insertions(+), 19 deletions(-) diff --git a/lib/simplifyExpression/fractionsSearch/addConstantFractions.js b/lib/simplifyExpression/fractionsSearch/addConstantFractions.js index 1179c366..f1793a6f 100644 --- a/lib/simplifyExpression/fractionsSearch/addConstantFractions.js +++ b/lib/simplifyExpression/fractionsSearch/addConstantFractions.js @@ -20,7 +20,8 @@ function addConstantFractions(node) { if (!Node.Type.isOperator(node) || node.op !== '+') { return Node.Status.noChange(node); } - if (!node.args.every(n => Node.Type.isIntegerFraction(n, true))) { + if (!node.args.every(n => Node.Type.isIntegerFraction(n, true) || + hasIntegerMultiplicationDenominator(n))) { return Node.Status.noChange(node); } const denominators = node.args.map(fraction => { @@ -48,6 +49,16 @@ function addConstantFractions(node) { newNode = Node.Status.resetChangeGroups(status.newNode); } + const newDenominators = newNode.args.map(fraction => { + return fraction.args[1]; + }); + if (!newDenominators.every(denominator => hasEqualNumberOfArgs(denominator, newDenominators[0]))){ + // Multiply out the denominators + status = evaluateDenominators(newNode); + substeps.push(status); + newNode = Node.Status.resetChangeGroups(status.newNode); + } + // 2A. Now that they all have the same denominator, combine the numerators // e.g. 2/3 + 5/3 -> (2+5)/3 status = combineNumeratorsAboveCommonDenominator(newNode); @@ -127,25 +138,25 @@ function makeCommonDenominator(node) { const denominators = newNode.args.map(fraction => { return parseFloat(fraction.args[1].value); - }); +}); const commonDenominator = math.lcm(...denominators); newNode.args.forEach((child, i) => { // missingFactor is what we need to multiply the top and bottom by // so that the denominator is the LCD const missingFactor = commonDenominator / denominators[i]; - if (missingFactor !== 1) { - const missingFactorNode = Node.Creator.constant(missingFactor); - const newNumerator = Node.Creator.parenthesis( + if (missingFactor !== 1) { + const missingFactorNode = Node.Creator.constant(missingFactor); + const newNumerator = Node.Creator.parenthesis( Node.Creator.operator('*', [child.args[0], missingFactorNode])); - const newDeominator = Node.Creator.parenthesis( + const newDeominator = Node.Creator.parenthesis( Node.Creator.operator('*', [child.args[1], missingFactorNode])); - newNode.args[i] = Node.Creator.operator('/', [newNumerator, newDeominator]); - } - }); + newNode.args[i] = Node.Creator.operator('/', [newNumerator, newDeominator]); + } +}); return Node.Status.nodeChanged( - ChangeTypes.COMMON_DENOMINATOR, node, newNode); + ChangeTypes.COMMON_DENOMINATOR, node, newNode); } function evaluateDenominators(node) { @@ -170,4 +181,43 @@ function evaluateNumerators(node) { ChangeTypes.MULTIPLY_NUMERATORS, node, newNode); } +function hasIntegerMultiplicationDenominator(node) { + if (!Node.Type.isOperator(node, '/')) { + return false; + } + const numerator = node.args[0]; + var denominator; + if (Node.Type.isParenthesis(node.args[1])) { + denominator = node.args[1].content; + } + else { + denominator = node.args[1]; + } + if (!Node.Type.isOperator(denominator, '*')) { + return false; + } + if (!denominator.args.every(n => (Node.Type.isConstant(n, true) || + Number.isInteger(parseFloat(n.value))))) + { + return false; + } + return true; +} + +function hasEqualNumberOfArgs(n1, n2){ + let node1 = clone(n1); + let node2 = clone(n2); + node1 = Node.Type.isParenthesis(node1) ? node1.content : node1; + node2 = Node.Type.isParenthesis(node2) ? node2.content : node2; + let length1 = 1; + let length2 = 1; + if (node1.args) { + length1 = node1.args.length; + } + if (node2.args) { + length2 = node2.args.length; + } + return length1 === length2; +} + module.exports = addConstantFractions; diff --git a/lib/simplifyExpression/fractionsSearch/cancelLikeTerms.js b/lib/simplifyExpression/fractionsSearch/cancelLikeTerms.js index 85f84b4b..983ecf18 100644 --- a/lib/simplifyExpression/fractionsSearch/cancelLikeTerms.js +++ b/lib/simplifyExpression/fractionsSearch/cancelLikeTerms.js @@ -56,8 +56,9 @@ function cancelLikeTerms(node) { // away because we always adjust the exponent in the numerator) else if (isMultiplicationOfTerms(numerator) && !isMultiplicationOfTerms(denominator)) { - const numeratorArgs = Node.Type.isParenthesis(numerator) ? - numerator.content.args : numerator.args; + const prioritizedNumerator = prioritizeEqualConstantArgs(numerator, denominator); + const numeratorArgs = Node.Type.isParenthesis(prioritizedNumerator) ? + prioritizedNumerator.content.args : prioritizedNumerator.args; for (let i = 0; i < numeratorArgs.length; i++) { const cancelStatus = cancelTerms(numeratorArgs[i], denominator); if (cancelStatus.hasChanged) { @@ -94,8 +95,9 @@ function cancelLikeTerms(node) { // e.g. x / (x^2*y) => x^(1-2) / y else if (isMultiplicationOfTerms(denominator) && !isMultiplicationOfTerms(numerator)) { - const denominatorArgs = Node.Type.isParenthesis(denominator) ? - denominator.content.args : denominator.args; + const prioritizedDenominator = prioritizeEqualConstantArgs(denominator, numerator); + const denominatorArgs = Node.Type.isParenthesis(prioritizedDenominator) ? + prioritizedDenominator.content.args : prioritizedDenominator.args; for (let i = 0; i < denominatorArgs.length; i++) { const cancelStatus = cancelTerms(numerator, denominatorArgs[i]); if (cancelStatus.hasChanged) { @@ -126,6 +128,43 @@ function cancelLikeTerms(node) { numerator.content.args : numerator.args; const denominatorArgs = Node.Type.isParenthesis(denominator) ? denominator.content.args : denominator.args; + + const likeTerms = getIndicesOfFirstTwoLikeTerms(numeratorArgs, denominatorArgs); + if (likeTerms){ + const cancelStatus = cancelTerms(numeratorArgs[likeTerms.numeratorIndex], + denominatorArgs[likeTerms.denominatorIndex]); + if (cancelStatus.hasChanged) { + if (cancelStatus.numerator) { + numeratorArgs[likeTerms.numeratorIndex] = cancelStatus.numerator; + } + // if the cancelling out got rid of the numerator node, we remove it + // from the list + else { + numeratorArgs.splice(likeTerms.numeratorIndex, 1); + // if the numerator is now a "multiplication" of only one term, + // change it to just that term + if (numeratorArgs.length === 1) { + newNode.args[0] = numeratorArgs[0]; + } + } + if (cancelStatus.denominator) { + denominatorArgs[likeTerms.denominatorIndex] = cancelStatus.denominator; + } + // if the cancelling out got rid of the denominator node, we remove it + // from the list + else { + denominatorArgs.splice(likeTerms.denominatorIndex, 1); + // if the denominator is now a "multiplication" of only one term, + // change it to just that term + if (denominatorArgs.length === 1) { + newNode.args[1] = denominatorArgs[0]; + } + } + return Node.Status.nodeChanged( + ChangeTypes.CANCEL_TERMS, node, newNode); + } + } + for (let i = 0; i < numeratorArgs.length; i++) { for (let j = 0; j < denominatorArgs.length; j++) { const cancelStatus = cancelTerms(numeratorArgs[i], denominatorArgs[j]); @@ -415,4 +454,40 @@ function cancelCoeffs(numerator, denominator){ return new CancelOutStatus(newNumerator, newDenominator, true); } +function prioritizeEqualConstantArgs(multiplicationNode, compareNode){ + let isParens = Node.Type.isParenthesis(multiplicationNode); + let content = multiplicationNode; + if (isParens){ + content = multiplicationNode.content; + } + let multiplicationFactors = content.args; + for (let i=0; i (5*3)/(2*3) let status = findGCD(newNode, gcd, numeratorValue, denominatorValue); @@ -69,15 +75,18 @@ function findGCD(node, gcd, numeratorValue, denominatorValue) { const gcdNode = Node.Creator.constant(gcd); gcdNode.changeGroup = 1; - const intermediateNumerator = Node.Creator.parenthesis(Node.Creator.operator( - '*', [Node.Creator.constant(numeratorValue/gcd), gcdNode])); + let intermediateNumerator = Node.Creator.constant(numeratorValue); + if (numeratorValue / gcd !== 1) { + intermediateNumerator = Node.Creator.parenthesis(Node.Creator.operator( + '*', [Node.Creator.constant(numeratorValue / gcd), gcdNode])); + } const intermediateDenominator = Node.Creator.parenthesis(Node.Creator.operator( - '*', [Node.Creator.constant(denominatorValue/gcd), gcdNode])); + '*', [Node.Creator.constant(denominatorValue / gcd), gcdNode])); newNode = Node.Creator.operator( - '/', [intermediateNumerator, intermediateDenominator]); + '/', [intermediateNumerator, intermediateDenominator]); return Node.Status.nodeChanged( - ChangeTypes.FIND_GCD, node, newNode, false); + ChangeTypes.FIND_GCD, node, newNode, false); } // Returns a substep where the GCD is cancelled out of numerator and denominator From 37822541417b4ab1dd8851f631d6e9eac4f8fd2a Mon Sep 17 00:00:00 2001 From: markus polleryd Date: Wed, 16 May 2018 10:35:45 +0200 Subject: [PATCH 5/6] fixed --- .../fractionsSearch/addConstantFractions.js | 24 +++++++++---------- .../fractionsSearch/cancelLikeTerms.js | 6 ++--- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/lib/simplifyExpression/fractionsSearch/addConstantFractions.js b/lib/simplifyExpression/fractionsSearch/addConstantFractions.js index f1793a6f..82986468 100644 --- a/lib/simplifyExpression/fractionsSearch/addConstantFractions.js +++ b/lib/simplifyExpression/fractionsSearch/addConstantFractions.js @@ -138,22 +138,22 @@ function makeCommonDenominator(node) { const denominators = newNode.args.map(fraction => { return parseFloat(fraction.args[1].value); -}); + }); const commonDenominator = math.lcm(...denominators); newNode.args.forEach((child, i) => { // missingFactor is what we need to multiply the top and bottom by // so that the denominator is the LCD const missingFactor = commonDenominator / denominators[i]; - if (missingFactor !== 1) { - const missingFactorNode = Node.Creator.constant(missingFactor); - const newNumerator = Node.Creator.parenthesis( - Node.Creator.operator('*', [child.args[0], missingFactorNode])); - const newDeominator = Node.Creator.parenthesis( - Node.Creator.operator('*', [child.args[1], missingFactorNode])); - newNode.args[i] = Node.Creator.operator('/', [newNumerator, newDeominator]); - } -}); + if (missingFactor !== 1) { + const missingFactorNode = Node.Creator.constant(missingFactor); + const newNumerator = Node.Creator.parenthesis( + Node.Creator.operator('*', [child.args[0], missingFactorNode])); + const newDeominator = Node.Creator.parenthesis( + Node.Creator.operator('*', [child.args[1], missingFactorNode])); + newNode.args[i] = Node.Creator.operator('/', [newNumerator, newDeominator]); + } + }); return Node.Status.nodeChanged( ChangeTypes.COMMON_DENOMINATOR, node, newNode); @@ -185,7 +185,6 @@ function hasIntegerMultiplicationDenominator(node) { if (!Node.Type.isOperator(node, '/')) { return false; } - const numerator = node.args[0]; var denominator; if (Node.Type.isParenthesis(node.args[1])) { denominator = node.args[1].content; @@ -197,8 +196,7 @@ function hasIntegerMultiplicationDenominator(node) { return false; } if (!denominator.args.every(n => (Node.Type.isConstant(n, true) || - Number.isInteger(parseFloat(n.value))))) - { + Number.isInteger(parseFloat(n.value))))){ return false; } return true; diff --git a/lib/simplifyExpression/fractionsSearch/cancelLikeTerms.js b/lib/simplifyExpression/fractionsSearch/cancelLikeTerms.js index 983ecf18..944e7b53 100644 --- a/lib/simplifyExpression/fractionsSearch/cancelLikeTerms.js +++ b/lib/simplifyExpression/fractionsSearch/cancelLikeTerms.js @@ -455,15 +455,15 @@ function cancelCoeffs(numerator, denominator){ } function prioritizeEqualConstantArgs(multiplicationNode, compareNode){ - let isParens = Node.Type.isParenthesis(multiplicationNode); + const isParens = Node.Type.isParenthesis(multiplicationNode); let content = multiplicationNode; if (isParens){ content = multiplicationNode.content; } - let multiplicationFactors = content.args; + const multiplicationFactors = content.args; for (let i=0; i Date: Mon, 11 Jun 2018 09:49:01 +0200 Subject: [PATCH 6/6] replaced clone() with cloneDeep() --- .../fractionsSearch/addConstantFractions.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/simplifyExpression/fractionsSearch/addConstantFractions.js b/lib/simplifyExpression/fractionsSearch/addConstantFractions.js index c4e017bf..f761c73b 100644 --- a/lib/simplifyExpression/fractionsSearch/addConstantFractions.js +++ b/lib/simplifyExpression/fractionsSearch/addConstantFractions.js @@ -202,8 +202,8 @@ function hasIntegerMultiplicationDenominator(node) { } function hasEqualNumberOfArgs(n1, n2){ - let node1 = clone(n1); - let node2 = clone(n2); + let node1 = n1.cloneDeep(); + let node2 = n2.cloneDeep(); node1 = Node.Type.isParenthesis(node1) ? node1.content : node1; node2 = Node.Type.isParenthesis(node2) ? node2.content : node2; let length1 = 1;