UNPKG

mathsteps-experimental-fork

Version:

Step by step math solutions. Experimental Fork

139 lines (134 loc) 7.09 kB
'use strict'; Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); const index = require('../index.js'); const myNodeToString = require('./nodeServices/myNodeToString.js'); const parseText = require('./nodeServices/parseText.js'); const removeUnnessaryParenthesis = require('./nodeServices/removeUnnessaryParenthesis.js'); const treeUtil = require('./treeUtil.js'); const kemuSimplifyCommonServices = require('../simplifyExpression/kemuSimplifyCommonServices.js'); const mscNormalizeNodeFunctions = require('../simplifyExpression/mscNormalizeNodeFunctions.js'); const arrayUtils = require('../util/arrayUtils.js'); const cleanString = require('../util/cleanString.js'); const regex = require('../util/regex.js'); const kemuSortArgs = require('../simplifyExpression/kemuSortArgs.js'); const getNodeStepsToSolveExpression = (userStep) => index.default.simplifyExpression({ expressionAsText: cleanString.cleanString(userStep), isDebugMode: false, expressionCtx: void 0, getMistakes: false, getAllNextStepPossibilities: false, onStepCb: (step) => { } }); function normalizeNodeForEquality(node_) { let node = typeof node_ === "string" ? parseText.parseText(node_) : node_; node = mscNormalizeNodeFunctions.convertNumParVarDivNumToNumVarDivNum(node); node = removeUnnessaryParenthesis.removeUnnecessaryParentheses(node); node = mscNormalizeNodeFunctions.convertAll1xToX(node); node = kemuSimplifyCommonServices.kemuFlatten(node); node = treeUtil.removeImplicitMultiplicationFromNode(node); node = mscNormalizeNodeFunctions.convertAllSimpleFractionsToDecimals(node); node = mscNormalizeNodeFunctions.normalizeNegativesAndFractions(node); node = kemuSimplifyCommonServices.kemuNormalizeConstantNodes(node); node = mscNormalizeNodeFunctions.convertAll1xToX(node); node = kemuSortArgs(node, true, true); return node; } function normalizeStringExpressionForEquality(stringExpression) { stringExpression = cleanString.cleanString(stringExpression); stringExpression = stringExpression.replace(/\((\d+(\.\d+)?)\)/g, "$1"); stringExpression = stringExpression.replace(/\(-(\d+(\.\d+)?)\)/g, "-$1"); stringExpression = mscNormalizeNodeFunctions.makePlusMinusMinusAndReturnString(`0+${stringExpression}`); stringExpression = stringExpression.replaceAll(/\b0[a-z]\b/gi, "0"); stringExpression = stringExpression.replaceAll(/\b1([a-z])\b/gi, "$1"); stringExpression = stringExpression.replace(/(\d+)\*([a-z])/gi, "$1$2"); const numberRG = "\\b\\d+(?:\\.\\d+)?[a-z]?\\b"; const regexExp = regex.makeExtendedRegExp(String.raw`\b(${numberRG})-\((${numberRG})/(${numberRG})\)`, "gi"); stringExpression = stringExpression.replace(regexExp, "$1+(-$2/$3)"); stringExpression = cleanString.cleanString(stringExpression); return stringExpression; } function areEquationsEqual(eq0, eq1, equalityCache = null) { const sides0 = eq0.split("=").map((side) => cleanString.cleanString(side)); const sides1 = eq1.split("=").map((side) => cleanString.cleanString(side)); return areExpressionEqual(sides0[0], sides1[0], equalityCache) && areExpressionEqual(sides0[1], sides1[1], equalityCache); } function areExpressionEqual(exp0, exp1, equalityCache = null) { if (!exp0 || !exp1) return false; if (exp0 === exp1) return true; if (!equalityCache) { return areExpressionEqualCore(exp0, exp1); } else { const strExp0 = typeof exp0 === "string" ? cleanString.cleanString(exp0) : myNodeToString.myNodeToString(exp0); const strExp1 = typeof exp1 === "string" ? cleanString.cleanString(exp1) : myNodeToString.myNodeToString(exp1); return equalityCache.getCachedEquality(strExp0, strExp1, areExpressionEqualCore); } } function areExpressionEqualCore(exp0, exp1) { if (!exp0 || !exp1) return false; if (exp0 === exp1) return true; const strExp0 = typeof exp0 === "string" ? cleanString.cleanString(exp0) : myNodeToString.myNodeToString(exp0); const strExp1 = typeof exp1 === "string" ? cleanString.cleanString(exp1) : myNodeToString.myNodeToString(exp1); if (strExp0 === strExp1) return true; const normalizedExprString0 = normalizeStringExpressionForEquality(strExp0); const normalizedExprString1 = normalizeStringExpressionForEquality(strExp1); if (normalizedExprString0 === normalizedExprString1) return true; if (canDoEqualityBasedOnEventualAnswer(normalizedExprString0, normalizedExprString1)) { const answer1 = myNodeToString.myNodeToString(getNodeStepsToSolveExpression(normalizedExprString0)); const answer2 = myNodeToString.myNodeToString(getNodeStepsToSolveExpression(normalizedExprString1)); if (answer1 === answer2) return true; const normalizedAnswer1 = normalizeStringExpressionForEquality(answer1); const normalizedAnswer2 = normalizeStringExpressionForEquality(answer2); if (normalizedAnswer1 === normalizedAnswer2) return true; const normalizedAnswerNode0 = normalizeNodeForEquality(parseText.parseText(normalizedAnswer1)); const normalizedAnswerNode1 = normalizeNodeForEquality(parseText.parseText(normalizedAnswer2)); return normalizedAnswerNode0.equals(normalizedAnswerNode1); } else { const normalizedNode0 = normalizeNodeForEquality(parseText.parseText(normalizedExprString0)); const normalizedNode1 = normalizeNodeForEquality(parseText.parseText(normalizedExprString1)); return normalizedNode0.equals(normalizedNode1); } } function canDoEqualityBasedOnEventualAnswer(strExp0, strExp1) { const countMult0 = (strExp0.match(/\*/g) || []).length; const countMult1 = (strExp1.match(/\*/g) || []).length; if (countMult0 !== countMult1) return false; const countDiv0 = (strExp0.match(/\//g) || []).length; const countDiv1 = (strExp1.match(/\//g) || []).length; if (countDiv0 !== countDiv1) return false; if (strExp0.includes("/")) { const fractions0 = strExp0.match(regex.RGFraction) || []; const fractions1 = strExp1.match(regex.RGFraction) || []; if (!arrayUtils.areArraysEqualUnordered(fractions0, fractions1, { isEqualFn: (a, b) => a === b })) return false; } const operators = ["+", "-", "*", "/"]; operators.forEach((op) => { strExp0 = strExp0.replaceAll(op, ` ${op} `); strExp1 = strExp1.replaceAll(op, ` ${op} `); }); strExp0 = strExp0.replace(/\s+/g, " "); strExp1 = strExp1.replace(/\s+/g, " "); strExp0 = strExp0.replaceAll("(", "").replaceAll(")", ""); strExp1 = strExp1.replaceAll("(", "").replaceAll(")", ""); strExp0 = strExp0.replaceAll("+", " ").replaceAll("-", " "); strExp1 = strExp1.replaceAll("+", " ").replaceAll("-", " "); const sortedStrExp0 = strExp0.split(/\s+/).sort().join("$"); const sortedStrExp1 = strExp1.split(/\s+/).sort().join("$"); return sortedStrExp0 === sortedStrExp1; } exports.areEquationsEqual = areEquationsEqual; exports.areExpressionEqual = areExpressionEqual; exports.getNodeStepsToSolveExpression = getNodeStepsToSolveExpression; exports.normalizeNodeForEquality = normalizeNodeForEquality; exports.normalizeStringExpressionForEquality = normalizeStringExpressionForEquality;