UNPKG

mathsteps-experimental-fork

Version:

Step by step math solutions. Experimental Fork

87 lines (84 loc) 3.77 kB
import { findAllNextStepOptions } from '../simplifyExpression/stepEvaluationCoreNextStepOptionsHelper.js'; import { isOpEqual, isAnOp } from '../types/changeType/changeAndMistakeUtils.js'; import { cleanString } from '../util/cleanString.js'; function findMatchingAddRemoveTerms(eqProcessedStep) { const isTermMatchingForAddRemoveFn = (termA, termB) => { const tryGetOpFn = (op) => isAnOp(op) ? op : null; const opEqualsFn = (op1, op2) => isOpEqual(tryGetOpFn(op1), tryGetOpFn(op2)); const termAOp = termA?.addedNumOp?.op || termA?.removeNumberOp?.op; const termANumber = termA?.addedNumOp?.number || termA?.removeNumberOp?.number; const termBOp = termB?.addedNumOp?.op || termB?.removeNumberOp?.op; const termBNumber = termB?.removeNumberOp?.number || termB?.addedNumOp?.number; const termAAdded = termA.changeType.includes("ADD_TERM"); const termBRemoved = termB.changeType.includes("REMOVE_TERM"); const termARemoved = termA.changeType.includes("REMOVE_TERM"); const termBAdded = termB.changeType.includes("ADD_TERM"); if (termANumber !== termBNumber) return false; if (termAAdded && termBAdded || termARemoved && termBRemoved) return false; if (!opEqualsFn(termAOp, termBOp)) return false; return true; }; const filterOutNonAddRemoveTermsFn = (options) => options.filter( (option) => option.changeType.includes("ADD_TERM") || option.changeType.includes("REMOVE_TERM") ); const leftOnlyAddRemoveTerms = filterOutNonAddRemoveTermsFn(eqProcessedStep.left); const rightOnlyAddRemoveTerms = filterOutNonAddRemoveTermsFn(eqProcessedStep.right); return leftOnlyAddRemoveTerms.map((leftProcessedStep) => { const matchedRight = rightOnlyAddRemoveTerms.find( (rightProcessedStep) => isTermMatchingForAddRemoveFn(leftProcessedStep, rightProcessedStep) ); return { left: leftProcessedStep, right: matchedRight }; }).filter((option) => option.right !== void 0); } function makeStartingLeftAndRightEqSteps(equation) { const expressions = equation.split("=").map((expression) => cleanString(expression)); return { left: { from: expressions[0], to: expressions[0], changeType: "NO_CHANGE", availableChangeTypes: [], isMistake: false }, right: { from: expressions[1], to: expressions[1], changeType: "NO_CHANGE", availableChangeTypes: [], isMistake: false } }; } function findNonAddRemoveRuleMatches(eqProcessedSteps, starting) { const isNotAddOrRemoveTermFn = (option) => !option.changeType.includes("ADD_TERM") && !option.changeType.includes("REMOVE_TERM"); const nonAddRemoveTermsLeft = eqProcessedSteps.left.filter((option) => isNotAddOrRemoveTermFn(option)); const nonAddRemoveTermsRight = eqProcessedSteps.right.filter((option) => isNotAddOrRemoveTermFn(option)); const newFullEquationsFromLeft = nonAddRemoveTermsLeft.map((option) => ({ left: option, right: starting.right })); const newFullEquationsFromRight = nonAddRemoveTermsRight.map((option) => ({ left: starting.left, right: option })); return newFullEquationsFromLeft.concat(newFullEquationsFromRight); } function makeEquationProcessSteps(equation) { const expressions = equation.split("=").map((expression) => cleanString(expression)); const leftExpression = expressions[0]; const rightExpression = expressions[1]; return { left: findAllNextStepOptions(leftExpression, { otherSide: rightExpression, history: [] }), right: findAllNextStepOptions(rightExpression, { otherSide: leftExpression, history: [] }) }; } export { findMatchingAddRemoveTerms, findNonAddRemoveRuleMatches, makeEquationProcessSteps, makeStartingLeftAndRightEqSteps };