UNPKG

mathsteps-experimental-fork

Version:

Step by step math solutions. Experimental Fork

93 lines (90 loc) 4.6 kB
import { makeStartingLeftAndRightEqSteps, makeEquationProcessSteps, findMatchingAddRemoveTerms, findNonAddRemoveRuleMatches } from './utils.js'; import { getAssessSolvedProblemSteps } from '../kemuEquation/SimpleSolveEquationFunction.js'; import { areEquationsEqual } from '../newServices/expressionEqualsAndNormalization.js'; import { isRemoveTermChangeType, isAddTermChangeType } from '../types/changeType/changeAndMistakeUtils.js'; import { ChangeTypes } from '../types/changeType/ChangeTypes.js'; import { getChangesTypesForRule } from '../types/changeType/MathRuleTypes.js'; import { UndoableString } from '../util/UndoableString.js'; function getEquationMatches(currentEquation) { const startingLeftRight = makeStartingLeftAndRightEqSteps(currentEquation); const eqProcessedSteps = makeEquationProcessSteps(currentEquation); const addRemoveCombo = findMatchingAddRemoveTerms(eqProcessedSteps); const nonAddRemoveRuleMatches = findNonAddRemoveRuleMatches( eqProcessedSteps, startingLeftRight ); const allRuleMatches = addRemoveCombo.concat(nonAddRemoveRuleMatches).map((option) => ({ left: option.left, right: option.right, newTo: `${option.left.to}=${option.right.to}` // full equation after applying that step })); return allRuleMatches; } const getFastestAmountOfStepsToSolveEquation = (assessedSteps) => { const removeNoChangeTypeStepsFn = (side) => side.filter((s) => s.attemptedChangeType !== ChangeTypes.NO_CHANGE); const removeStuffFromRightFn = (side) => { return side.filter((s) => !isRemoveTermChangeType(s.attemptedChangeType)).filter((s) => !isAddTermChangeType(s.attemptedChangeType)).filter((s) => s.attemptedChangeType !== ChangeTypes.EQ_SWAP_SIDES).filter((s) => s.attemptedChangeType !== ChangeTypes.EQ_MULTIPLY_BOTH_SIDES_BY_NEGATIVE_ONE); }; const removeRemoveAddingZeroFn = (side) => side.filter((s) => s.attemptedChangeType !== ChangeTypes.REMOVE_ADDING_ZERO); assessedSteps = assessedSteps.map((step) => { const left = removeRemoveAddingZeroFn(removeNoChangeTypeStepsFn(step.left)); const right = removeRemoveAddingZeroFn(removeNoChangeTypeStepsFn(removeStuffFromRightFn(step.right))); return { ...step, left, right }; }); let count = 0; for (const step of assessedSteps) { count += step.left.length; count += step.right.length; } return count; }; class EquationCommander { equationHistory; finalCorrectAnswer; correctAnswerSteps; assessedSteps; constructor(initialValue = "") { this.equationHistory = new UndoableString(initialValue); const { steps, assessedSteps } = getAssessSolvedProblemSteps(initialValue); this.correctAnswerSteps = steps; this.assessedSteps = assessedSteps; this.finalCorrectAnswer = steps[steps.length - 1].equationString; } redo = () => this.equationHistory.redo(); undo = () => this.equationHistory.undo(); setValue = (newValue) => this.equationHistory.setValue(newValue); getValue = () => this.equationHistory.getValue(); isSolved = () => areEquationsEqual(this.finalCorrectAnswer, this.getValue()); // TODO add cache getHistory = () => this.equationHistory.getHistory(); getFuture = () => this.equationHistory.getFuture(); swap() { const currentEquation = this.getValue(); const [left, right] = currentEquation.split("="); this.setValue(`${right}=${left}`); } getAssessedSteps = () => this.assessedSteps; getCorrectAnswerSteps = () => this.correctAnswerSteps; getFastestAmountOfStepsToSolve = () => getFastestAmountOfStepsToSolveEquation(this.assessedSteps); getCurrentNumberOfSteps = () => this.assessedSteps.length; getCurrentMatches() { const allRuleMatches = getEquationMatches(this.getValue()); const skippedZeroPlusMatches = allRuleMatches.map((match) => { const cleanStartingZeroToFn = (to) => to.replace(/^0[a-z]*[\+\-]/gmi, ""); const left = cleanStartingZeroToFn(match.left.to); const right = cleanStartingZeroToFn(match.right.to); match.left.to = left; match.right.to = right; match.newTo = `${left}=${right}`; return match; }); return skippedZeroPlusMatches; } getMatchesForRule(rule) { const matches = this.getCurrentMatches(); const changeTypesForGivenRule = rule !== "all" ? getChangesTypesForRule(rule) : Object.values(ChangeTypes).flat(); return matches.filter((match) => changeTypesForGivenRule.includes(match.left.changeType) || changeTypesForGivenRule.includes(match.right.changeType)); } } export { EquationCommander, EquationCommander as default, getFastestAmountOfStepsToSolveEquation };