UNPKG

mathsteps-experimental-fork

Version:

Step by step math solutions. Experimental Fork

122 lines (114 loc) 4.46 kB
'use strict'; Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); const clone = require('../newServices/nodeServices/clone.js'); const myNodeToString = require('../newServices/nodeServices/myNodeToString.js'); const nodeCacher = require('../newServices/nodeServices/nodeCacher.js'); const utilMadeFromMathJs = require('./utilMadeFromMathJs.js'); const treeUtil = require('../newServices/treeUtil.js'); const index = require('../node/index.js'); const arrayUtils = require('../util/arrayUtils.js'); function _removeMultiplicationTimesSymbol(node) { if (!node || !node.args) return node if (node.fn !== 'multiply' || node.args.length <= 1) return node // // replace all alone symbols with 1 * symbol // // case first arg is a symbol const firstArg = node.args[0]; if (index.default.Type.isSymbol(firstArg)) { const oneNode = index.default.Creator.constant(1); node.args.unshift(oneNode); } // case repeated symbol alone, then its a single symbol we need to replace const ogLength = node.args.length; for (let i = 0; i < ogLength; i++) { const arg = node.args[i]; const lastArg = node.args[i - 1]; if (lastArg && index.default.Type.isSymbol(arg) && index.default.Type.isSymbol(lastArg)) { const oneNode = index.default.Creator.constant(1); // add right before this arg node.args.splice(i, 0, oneNode); } } // Place their missing symbol as a property for later let lastNode = null; node.args.forEach((arg) => { if (index.default.Type.isSymbol(arg) && lastNode) lastNode.missingSymbol = arg; lastNode = arg; }); // remove symbols node.args = node.args.filter(arg => !index.default.Type.isSymbol(arg)); return node } function _placeBackMultiplicationTimesSymbol(node) { if (!node || !node.args) return node if (node.fn !== 'multiply' || node.args.length <= 1) return node const doSymbolsExist = node.args.some(arg => index.default.Type.isSymbol(arg)); if (doSymbolsExist) { node.args = node.args.map((arg) => { arg.missingSymbol = null; return arg }); return node } const argsWithSymbolsMissing = node.args.filter(arg => arg.missingSymbol); // give them back their symbols argsWithSymbolsMissing.forEach((arg) => { const index = node.args.findIndex(node => node === arg); node.args.splice(index + 1, 0, arg.missingSymbol); }); return node } function _getEveryFirstTwoPermutationOfNode(_node, ogTopNode, context) { if (!_node || !_node.args || _node.args.length < 2) return if (!utilMadeFromMathJs.isCommutative(_node)) return [_node] _node = _removeMultiplicationTimesSymbol(_node); const makeNode = utilMadeFromMathJs.createMakeNodeFunction(_node, context); const combinations = arrayUtils.generateCombinations(_node.args); const uniqueCombos = new Map(); for (const combo of combinations) { // Changes topNode to get the new changed node const newNode = makeNode(combo); treeUtil.setUpNewNodeTree(context, newNode); const resultWithSymbolsBack = _placeBackMultiplicationTimesSymbol(clone(context.topNode)); const nodeString = myNodeToString.myNodeToString(resultWithSymbolsBack); if (!uniqueCombos.has(nodeString)) { uniqueCombos.set(nodeString, resultWithSymbolsBack); } // Reset context topNode to original top node to avoid mutation issues treeUtil.setUpNewNodeTree(context, ogTopNode); } return Array.from(uniqueCombos.values()) } const permCache = new Map(); /** * @description This function returns all the needed permutations of the first two arguments of a node. * Get all permutations of the node but only the first two nodes. * ex. 1 + (2 * 3) + 2 => * [ * 1 + (2 * 3) + 2, * (2 * 3) + 2 + 1, * 2 + 1 + (2 * 3) * ] */ function getFirstOperationChoicePermutations(aNode, doesClone = true) { if (!aNode) return [] if (!aNode.args || aNode.args.length < 2) return [aNode] const key = nodeCacher.makeKeyFromNode(aNode); if (permCache.has(key)) return permCache.get(key) const node = doesClone ? clone(aNode) : aNode; const permutations = _getEveryFirstTwoPermutationOfNode(node, clone(node), { topNode: node }); permCache.set(key, permutations); return permutations } exports.getFirstOperationChoicePermutations = getFirstOperationChoicePermutations;