math-exercises 3.0.133 → 3.0.135
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/exercises/math/calcul/arithmetics/coprime.d.ts +8 -0
- package/lib/exercises/math/calcul/arithmetics/coprime.d.ts.map +1 -0
- package/lib/exercises/math/calcul/arithmetics/coprime.js +113 -0
- package/lib/exercises/math/calcul/arithmetics/index.d.ts +1 -0
- package/lib/exercises/math/calcul/arithmetics/index.d.ts.map +1 -1
- package/lib/exercises/math/calcul/arithmetics/index.js +1 -0
- package/lib/exercises/math/calcul/decimals/decimalFractionToDecimal.d.ts +11 -0
- package/lib/exercises/math/calcul/decimals/decimalFractionToDecimal.d.ts.map +1 -0
- package/lib/exercises/math/calcul/decimals/decimalFractionToDecimal.js +243 -0
- package/lib/exercises/math/calcul/decimals/index.d.ts +1 -0
- package/lib/exercises/math/calcul/decimals/index.d.ts.map +1 -1
- package/lib/exercises/math/calcul/decimals/index.js +1 -0
- package/lib/exercises/math/calculLitteral/distributivity/doubleDistri.d.ts.map +1 -1
- package/lib/exercises/math/calculLitteral/distributivity/doubleDistri.js +4 -0
- package/lib/exercises/math/calculLitteral/distributivity/doubleDistributivityAdd.d.ts +12 -0
- package/lib/exercises/math/calculLitteral/distributivity/doubleDistributivityAdd.d.ts.map +1 -0
- package/lib/exercises/math/calculLitteral/distributivity/doubleDistributivityAdd.js +173 -0
- package/lib/exercises/math/calculLitteral/distributivity/index.d.ts +1 -0
- package/lib/exercises/math/calculLitteral/distributivity/index.d.ts.map +1 -1
- package/lib/exercises/math/calculLitteral/distributivity/index.js +1 -0
- package/lib/exercises/math/calculLitteral/equation/equationSecondDegreeWithNoB.d.ts +7 -0
- package/lib/exercises/math/calculLitteral/equation/equationSecondDegreeWithNoB.d.ts.map +1 -0
- package/lib/exercises/math/calculLitteral/equation/equationSecondDegreeWithNoB.js +160 -0
- package/lib/exercises/math/calculLitteral/simplifying/compareMinusA.js +1 -1
- package/lib/exercises/math/dataRepresentations/barChartInterpreting.d.ts.map +1 -1
- package/lib/exercises/math/dataRepresentations/barChartInterpreting.js +0 -1
- package/lib/exercises/math/derivation/derivative/composition/functionCompositionDerivative.d.ts +11 -0
- package/lib/exercises/math/derivation/derivative/composition/functionCompositionDerivative.d.ts.map +1 -0
- package/lib/exercises/math/derivation/derivative/composition/functionCompositionDerivative.js +372 -0
- package/lib/exercises/math/derivation/derivative/composition/index.d.ts +2 -0
- package/lib/exercises/math/derivation/derivative/composition/index.d.ts.map +1 -0
- package/lib/exercises/math/derivation/derivative/composition/index.js +1 -0
- package/lib/exercises/math/derivation/derivative/index.d.ts +1 -0
- package/lib/exercises/math/derivation/derivative/index.d.ts.map +1 -1
- package/lib/exercises/math/derivation/derivative/index.js +1 -0
- package/lib/exercises/math/functions/affines/recognizeAffineGraph.d.ts.map +1 -1
- package/lib/exercises/math/functions/affines/recognizeAffineGraph.js +3 -3
- package/lib/exercises/math/functions/affines/recognizeExprAffine.js +2 -2
- package/lib/exercises/math/functions/composition/functionComposition.js +1 -1
- package/lib/exercises/math/functions/composition/functionDecompositionFindPossibleUVs.d.ts +13 -0
- package/lib/exercises/math/functions/composition/functionDecompositionFindPossibleUVs.d.ts.map +1 -0
- package/lib/exercises/math/functions/composition/functionDecompositionFindPossibleUVs.js +223 -0
- package/lib/exercises/math/functions/composition/functionDecompositionFindUOrV.d.ts +9 -0
- package/lib/exercises/math/functions/composition/functionDecompositionFindUOrV.d.ts.map +1 -0
- package/lib/exercises/math/functions/composition/functionDecompositionFindUOrV.js +252 -0
- package/lib/exercises/math/functions/composition/index.d.ts +2 -0
- package/lib/exercises/math/functions/composition/index.d.ts.map +1 -1
- package/lib/exercises/math/functions/composition/index.js +2 -0
- package/lib/exercises/math/functions/trinoms/roots/rootsReading.d.ts +4 -1
- package/lib/exercises/math/functions/trinoms/roots/rootsReading.d.ts.map +1 -1
- package/lib/exercises/math/functions/trinoms/roots/rootsReading.js +29 -9
- package/lib/exercises/math/geometry/cartesian/midpoint.d.ts.map +1 -1
- package/lib/exercises/math/geometry/cartesian/midpoint.js +8 -1
- package/lib/exercises/math/geometry/vectors/constructions/index.d.ts +1 -0
- package/lib/exercises/math/geometry/vectors/constructions/index.d.ts.map +1 -1
- package/lib/exercises/math/geometry/vectors/constructions/index.js +1 -0
- package/lib/exercises/math/geometry/vectors/constructions/traceVectorCL.d.ts +13 -0
- package/lib/exercises/math/geometry/vectors/constructions/traceVectorCL.d.ts.map +1 -0
- package/lib/exercises/math/geometry/vectors/constructions/traceVectorCL.js +178 -0
- package/lib/exercises/math/percent/evolutions/findEndValueAfterEvolution.d.ts.map +1 -1
- package/lib/exercises/math/percent/evolutions/findEndValueAfterEvolution.js +1 -1
- package/lib/exercises/math/powers/powersMixOperations.d.ts +4 -1
- package/lib/exercises/math/powers/powersMixOperations.d.ts.map +1 -1
- package/lib/exercises/math/powers/powersMixOperations.js +17 -7
- package/lib/exercises/math/probaStat/stats1var/plausibilityOfAverage.js +1 -1
- package/lib/exercises/math/sequences/arithmetic/arithmeticFindExplicitFormulaFirstRankOne.d.ts +8 -0
- package/lib/exercises/math/sequences/arithmetic/arithmeticFindExplicitFormulaFirstRankOne.d.ts.map +1 -0
- package/lib/exercises/math/sequences/arithmetic/arithmeticFindExplicitFormulaFirstRankOne.js +105 -0
- package/lib/exercises/math/sequences/arithmetic/arithmeticFindTermFirstRankOne.d.ts +9 -0
- package/lib/exercises/math/sequences/arithmetic/arithmeticFindTermFirstRankOne.d.ts.map +1 -0
- package/lib/exercises/math/sequences/arithmetic/arithmeticFindTermFirstRankOne.js +99 -0
- package/lib/exercises/math/sequences/arithmetic/arithmeticRecurrenceFormulaUsage.d.ts.map +1 -1
- package/lib/exercises/math/sequences/arithmetic/arithmeticRecurrenceFormulaUsage.js +9 -1
- package/lib/exercises/math/sequences/arithmetic/index.d.ts +2 -0
- package/lib/exercises/math/sequences/arithmetic/index.d.ts.map +1 -1
- package/lib/exercises/math/sequences/arithmetic/index.js +2 -0
- package/lib/exercises/math/sequences/genericSequenceVariations.d.ts.map +1 -1
- package/lib/exercises/math/sequences/genericSequenceVariations.js +5 -1
- package/lib/exercises/math/sequences/geometric/geometricExplicitFormulaUsage.d.ts.map +1 -1
- package/lib/exercises/math/sequences/geometric/geometricExplicitFormulaUsage.js +7 -1
- package/lib/exercises/math/sequences/geometric/geometricFindExplicitFormula.d.ts.map +1 -1
- package/lib/exercises/math/sequences/geometric/geometricFindExplicitFormula.js +3 -2
- package/lib/exercises/math/sequences/geometric/geometricFindExplicitFormulaFirstRankOne.d.ts +8 -0
- package/lib/exercises/math/sequences/geometric/geometricFindExplicitFormulaFirstRankOne.d.ts.map +1 -0
- package/lib/exercises/math/sequences/geometric/geometricFindExplicitFormulaFirstRankOne.js +112 -0
- package/lib/exercises/math/sequences/geometric/geometricFindTermFirstRankOne.d.ts +9 -0
- package/lib/exercises/math/sequences/geometric/geometricFindTermFirstRankOne.d.ts.map +1 -0
- package/lib/exercises/math/sequences/geometric/geometricFindTermFirstRankOne.js +97 -0
- package/lib/exercises/math/sequences/geometric/geometricFirstTermsGeneralSum.d.ts +5 -1
- package/lib/exercises/math/sequences/geometric/geometricFirstTermsGeneralSum.d.ts.map +1 -1
- package/lib/exercises/math/sequences/geometric/geometricFirstTermsGeneralSum.js +23 -6
- package/lib/exercises/math/sequences/geometric/geometricReasonUsage.d.ts.map +1 -1
- package/lib/exercises/math/sequences/geometric/geometricReasonUsage.js +3 -1
- package/lib/exercises/math/sequences/geometric/geometricRecurrenceFormulaUsage.d.ts.map +1 -1
- package/lib/exercises/math/sequences/geometric/geometricRecurrenceFormulaUsage.js +9 -1
- package/lib/exercises/math/sequences/geometric/index.d.ts +2 -0
- package/lib/exercises/math/sequences/geometric/index.d.ts.map +1 -1
- package/lib/exercises/math/sequences/geometric/index.js +2 -0
- package/lib/exercises/math/sequences/recurrenceFormulaUsage.d.ts.map +1 -1
- package/lib/exercises/math/sequences/recurrenceFormulaUsage.js +10 -3
- package/lib/index.d.ts +59 -3
- package/lib/index.d.ts.map +1 -1
- package/lib/math/utils/arithmetic/isCoprime.d.ts +2 -0
- package/lib/math/utils/arithmetic/isCoprime.d.ts.map +1 -0
- package/lib/math/utils/arithmetic/isCoprime.js +10 -0
- package/lib/math/utils/arithmetic/primeDecompNode.d.ts +3 -0
- package/lib/math/utils/arithmetic/primeDecompNode.d.ts.map +1 -0
- package/lib/math/utils/arithmetic/primeDecompNode.js +24 -0
- package/lib/math/utils/functions/functionComparison.d.ts +3 -0
- package/lib/math/utils/functions/functionComparison.d.ts.map +1 -0
- package/lib/math/utils/functions/functionComparison.js +58 -0
- package/lib/math/utils/functions/functionComposition.d.ts +13 -0
- package/lib/math/utils/functions/functionComposition.d.ts.map +1 -0
- package/lib/math/utils/functions/functionComposition.js +117 -0
- package/lib/math/utils/functions/functionDecomposition.d.ts +10 -0
- package/lib/math/utils/functions/functionDecomposition.d.ts.map +1 -0
- package/lib/math/utils/functions/functionDecomposition.js +256 -0
- package/lib/server.js +24 -23
- package/lib/tree/nodes/operators/powerNode.d.ts.map +1 -1
- package/lib/tree/nodes/operators/powerNode.js +4 -0
- package/lib/utils/strings/joinanded.d.ts +2 -0
- package/lib/utils/strings/joinanded.d.ts.map +1 -0
- package/lib/utils/strings/joinanded.js +11 -0
- package/package.json +1 -1
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { MultiplyNode } from "../../../tree/nodes/operators/multiplyNode.js";
|
|
2
|
+
import { power } from "../../../tree/nodes/operators/powerNode.js";
|
|
3
|
+
import { operatorComposition } from "../../../tree/utilities/operatorComposition.js";
|
|
4
|
+
import { primeDecomposition } from "./primeDecomposition.js";
|
|
5
|
+
export const primeDecompNode = (nb, asPowers = true) => {
|
|
6
|
+
const decomp = primeDecomposition(nb);
|
|
7
|
+
const nodes = [];
|
|
8
|
+
if (asPowers) {
|
|
9
|
+
for (const d of decomp) {
|
|
10
|
+
if (d.power === 1)
|
|
11
|
+
nodes.push(d.value.toTree());
|
|
12
|
+
else
|
|
13
|
+
nodes.push(power(d.value, d.power));
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
for (const d of decomp) {
|
|
18
|
+
for (let i = 0; i < d.power; i++) {
|
|
19
|
+
nodes.push(d.value.toTree());
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return operatorComposition(MultiplyNode, nodes);
|
|
24
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"functionComparison.d.ts","sourceRoot":"","sources":["../../../../src/math/utils/functions/functionComparison.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAsElE,eAAO,MAAM,iBAAiB,GAC5B,OAAO,aAAa,EACpB,OAAO,aAAa,YAarB,CAAC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { isInfiniteNode } from "../../../tree/nodes/numbers/constantNode.js";
|
|
2
|
+
import { substract } from "../../../tree/nodes/operators/substractNode.js";
|
|
3
|
+
import { randfloat } from "../random/randfloat.js";
|
|
4
|
+
const getSafeEvaluationDictForEqualityCheck = (node1, node2, nbSafeX = 4) => {
|
|
5
|
+
const dict = {};
|
|
6
|
+
let counter = -1;
|
|
7
|
+
while (Object.keys(dict).length < nbSafeX && counter < 1000) {
|
|
8
|
+
counter++;
|
|
9
|
+
const x = randfloat(-20, 100, 3);
|
|
10
|
+
let value1;
|
|
11
|
+
let value2;
|
|
12
|
+
try {
|
|
13
|
+
value1 = node1.evaluate({ x });
|
|
14
|
+
}
|
|
15
|
+
catch (_) {
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
try {
|
|
19
|
+
value2 = node2.evaluate({ x });
|
|
20
|
+
}
|
|
21
|
+
catch (_) {
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
const [isValidValue1, isValidValue2] = [value1, value2].map((value) => value !== undefined && !isNaN(value) && !isInfiniteNode(value.toTree()));
|
|
25
|
+
if (isValidValue1 && isValidValue2) {
|
|
26
|
+
dict[x] = [value1, value2].map((value) => {
|
|
27
|
+
return {
|
|
28
|
+
x,
|
|
29
|
+
value,
|
|
30
|
+
};
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return dict;
|
|
35
|
+
};
|
|
36
|
+
const isEqualFromRandomEvaluations = (node1, node2) => {
|
|
37
|
+
return Object.values(getSafeEvaluationDictForEqualityCheck(node1, node2)).every((arrSafeEval) => {
|
|
38
|
+
// console.log(
|
|
39
|
+
// "arrSafeEval",
|
|
40
|
+
// arrSafeEval.map((safeEval) => safeEval.value),
|
|
41
|
+
// );
|
|
42
|
+
return arrSafeEval
|
|
43
|
+
.slice(1)
|
|
44
|
+
.every((safeEval) => substract(arrSafeEval[0].value, safeEval.value).evaluate() === 0);
|
|
45
|
+
});
|
|
46
|
+
};
|
|
47
|
+
export const isEquivalentNodes = (node1, node2) => {
|
|
48
|
+
let isEqualFromAlgebraicSimplification = false;
|
|
49
|
+
try {
|
|
50
|
+
isEqualFromAlgebraicSimplification =
|
|
51
|
+
substract(node1, node2).simplify().evaluate() === 0;
|
|
52
|
+
}
|
|
53
|
+
catch (_) {
|
|
54
|
+
(() => { })();
|
|
55
|
+
}
|
|
56
|
+
return (isEqualFromAlgebraicSimplification ||
|
|
57
|
+
isEqualFromRandomEvaluations(node1, node2));
|
|
58
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { AlgebraicNode, SimplifyOptions } from "../../../tree/nodes/algebraicNode.js";
|
|
2
|
+
import { VariableNode } from "../../../tree/nodes/variables/variableNode.js";
|
|
3
|
+
export declare const nodeBySubstitutingVar: (nodeCarrier: AlgebraicNode, nodeInjected: AlgebraicNode, variableNode?: VariableNode) => AlgebraicNode;
|
|
4
|
+
export type NodePathWithNodes = {
|
|
5
|
+
arrNode: AlgebraicNode[];
|
|
6
|
+
nodePath: NodePath;
|
|
7
|
+
};
|
|
8
|
+
export declare const getAllNodePaths: (node: AlgebraicNode) => NodePathWithNodes[];
|
|
9
|
+
export type NodePath = {
|
|
10
|
+
keys: ("leftChild" | "rightChild" | "child")[];
|
|
11
|
+
};
|
|
12
|
+
export declare function nodeByReplacingNodeAtPath(nodeCarrier: AlgebraicNode, path: NodePath, nodeInjected: AlgebraicNode, simplifyUpToLevel?: number, simplifyOptions?: SimplifyOptions): AlgebraicNode;
|
|
13
|
+
//# sourceMappingURL=functionComposition.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"functionComposition.d.ts","sourceRoot":"","sources":["../../../../src/math/utils/functions/functionComposition.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,eAAe,EAChB,MAAM,mCAAmC,CAAC;AAU3C,OAAO,EAEL,YAAY,EACb,MAAM,4CAA4C,CAAC;AAEpD,eAAO,MAAM,qBAAqB,GAChC,aAAa,aAAa,EAC1B,cAAc,aAAa,EAC3B,eAAc,YAA2C,kBAiB1D,CAAC;AAMF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,QAAQ,EAAE,QAAQ,CAAC;CACpB,CAAC;AAEF,eAAO,MAAM,eAAe,GAAI,MAAM,aAAa,wBA4ClD,CAAC;AAMF,MAAM,MAAM,QAAQ,GAAG;IACrB,IAAI,EAAE,CAAC,WAAW,GAAG,YAAY,GAAG,OAAO,CAAC,EAAE,CAAC;CAChD,CAAC;AA6BF,wBAAgB,yBAAyB,CACvC,WAAW,EAAE,aAAa,EAC1B,IAAI,EAAE,QAAQ,EACd,YAAY,EAAE,aAAa,EAC3B,iBAAiB,GAAE,MAAW,EAC9B,eAAe,GAAE,eAAoB,iBAiEtC"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { isFunctionNode, } from "../../../tree/nodes/functions/functionNode.js";
|
|
2
|
+
import { NodeConstructor } from "../../../tree/nodes/nodeConstructor.js";
|
|
3
|
+
import { isOperatorNode, } from "../../../tree/nodes/operators/operatorNode.js";
|
|
4
|
+
import { isVariableNode, } from "../../../tree/nodes/variables/variableNode.js";
|
|
5
|
+
export const nodeBySubstitutingVar = (nodeCarrier, nodeInjected, variableNode = "x".toTree()) => {
|
|
6
|
+
function isTargetVariableNode(node) {
|
|
7
|
+
return isVariableNode(node) && node.name === variableNode.name;
|
|
8
|
+
}
|
|
9
|
+
const nodePathsWithVariableAtEnd = getAllNodePaths(nodeCarrier).filter((nodePathWithNodes) => isTargetVariableNode(nodePathWithNodes.arrNode[nodePathWithNodes.arrNode.length - 1]));
|
|
10
|
+
return nodePathsWithVariableAtEnd.reduce((acc, nodePathWithNodes) => nodeByReplacingNodeAtPath(acc, nodePathWithNodes.nodePath, nodeInjected), nodeCarrier);
|
|
11
|
+
};
|
|
12
|
+
export const getAllNodePaths = (node) => {
|
|
13
|
+
const arrNodePaths = [];
|
|
14
|
+
if (isOperatorNode(node)) {
|
|
15
|
+
getAllNodePaths(node.leftChild).forEach((nodePathWithNodes) => {
|
|
16
|
+
arrNodePaths.push({
|
|
17
|
+
arrNode: [node, ...nodePathWithNodes.arrNode],
|
|
18
|
+
nodePath: {
|
|
19
|
+
keys: ["leftChild", ...nodePathWithNodes.nodePath.keys],
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
getAllNodePaths(node.rightChild).forEach((nodePathWithNodes) => {
|
|
24
|
+
arrNodePaths.push({
|
|
25
|
+
arrNode: [node, ...nodePathWithNodes.arrNode],
|
|
26
|
+
nodePath: {
|
|
27
|
+
keys: ["rightChild", ...nodePathWithNodes.nodePath.keys],
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
else if (isFunctionNode(node)) {
|
|
33
|
+
getAllNodePaths(node.child).forEach((nodePathWithNodes) => {
|
|
34
|
+
arrNodePaths.push({
|
|
35
|
+
arrNode: [node, ...nodePathWithNodes.arrNode],
|
|
36
|
+
nodePath: {
|
|
37
|
+
keys: ["child", ...nodePathWithNodes.nodePath.keys],
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
arrNodePaths.push({
|
|
44
|
+
arrNode: [node],
|
|
45
|
+
nodePath: {
|
|
46
|
+
keys: [],
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
return arrNodePaths;
|
|
51
|
+
};
|
|
52
|
+
function functionNodeByReplacingChild(fNode, nodeChildNew) {
|
|
53
|
+
const nodeIds = fNode.toIdentifiers();
|
|
54
|
+
nodeIds.child = nodeChildNew.toIdentifiers();
|
|
55
|
+
return NodeConstructor.fromIdentifiers(nodeIds);
|
|
56
|
+
}
|
|
57
|
+
function operatorNodeByReplacingLeftChild(opNode, nodeLeftChildNew) {
|
|
58
|
+
const nodeIds = opNode.toIdentifiers();
|
|
59
|
+
nodeIds.leftChild = nodeLeftChildNew.toIdentifiers();
|
|
60
|
+
return NodeConstructor.fromIdentifiers(nodeIds);
|
|
61
|
+
}
|
|
62
|
+
function operatorNodeByReplacingRightChild(opNode, nodeRightChildNew) {
|
|
63
|
+
const nodeIds = opNode.toIdentifiers();
|
|
64
|
+
nodeIds.rightChild = nodeRightChildNew.toIdentifiers();
|
|
65
|
+
return NodeConstructor.fromIdentifiers(nodeIds);
|
|
66
|
+
}
|
|
67
|
+
export function nodeByReplacingNodeAtPath(nodeCarrier, path, nodeInjected, simplifyUpToLevel = -1, simplifyOptions = {}) {
|
|
68
|
+
// console.log("nodeByReplacingNodeAtPath", {
|
|
69
|
+
// node: nodeCarrier.toTex(),
|
|
70
|
+
// key: path.keys.join("."),
|
|
71
|
+
// nodeInjected: nodeInjected.toTex(),
|
|
72
|
+
// });
|
|
73
|
+
function getNodeForKey(node, key) {
|
|
74
|
+
if (key === "leftChild" || key === "rightChild") {
|
|
75
|
+
return node[key];
|
|
76
|
+
}
|
|
77
|
+
else if (key === "child") {
|
|
78
|
+
return node[key];
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
throw new Error("Unsupported key in path.keys: " + key);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
function nodeByReplacingChildAtKey(node, key, nodeInjected) {
|
|
85
|
+
// console.log("nodeByReplacingChildAtKey", {
|
|
86
|
+
// node: node.toTex(),
|
|
87
|
+
// key: key,
|
|
88
|
+
// nodeInjected: nodeInjected.toTex(),
|
|
89
|
+
// });
|
|
90
|
+
if (key === "leftChild" && isOperatorNode(node)) {
|
|
91
|
+
return operatorNodeByReplacingLeftChild(node, nodeInjected);
|
|
92
|
+
}
|
|
93
|
+
else if (key === "rightChild" && isOperatorNode(node)) {
|
|
94
|
+
return operatorNodeByReplacingRightChild(node, nodeInjected);
|
|
95
|
+
}
|
|
96
|
+
else if (key === "child" && isFunctionNode(node)) {
|
|
97
|
+
return functionNodeByReplacingChild(node, nodeInjected);
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
throw new Error("Either key and node type are incompatible or Unsupported key: " + key);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
const arrNodeReversed = path.keys
|
|
104
|
+
.slice(0, -1)
|
|
105
|
+
.reduce((acc, key) => {
|
|
106
|
+
return [...acc, getNodeForKey(acc[acc.length - 1], key)];
|
|
107
|
+
}, [nodeCarrier])
|
|
108
|
+
.toReversed();
|
|
109
|
+
return path.keys.toReversed().reduce((acc, key, i) => {
|
|
110
|
+
const carrierNode = arrNodeReversed[i];
|
|
111
|
+
let nodeReplacement = nodeByReplacingChildAtKey(carrierNode, key, acc);
|
|
112
|
+
if (i <= simplifyUpToLevel) {
|
|
113
|
+
nodeReplacement = nodeReplacement.simplify(simplifyOptions);
|
|
114
|
+
}
|
|
115
|
+
return nodeReplacement;
|
|
116
|
+
}, nodeInjected);
|
|
117
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { AlgebraicNode } from "../../../tree/nodes/algebraicNode.js";
|
|
2
|
+
import { VariableNode } from "../../../tree/nodes/variables/variableNode.js";
|
|
3
|
+
export declare const functionDecompositions: (node: AlgebraicNode, variableNode?: VariableNode) => {
|
|
4
|
+
nodeU: AlgebraicNode;
|
|
5
|
+
nodeV: AlgebraicNode;
|
|
6
|
+
}[];
|
|
7
|
+
export declare const nodeBySubstitutingX: (node: AlgebraicNode, strVar: string) => AlgebraicNode;
|
|
8
|
+
export declare function composeNodes(nodeU: AlgebraicNode, nodeV: AlgebraicNode): AlgebraicNode;
|
|
9
|
+
export declare function isContainingFacetiousFrac(node: AlgebraicNode): boolean;
|
|
10
|
+
//# sourceMappingURL=functionDecomposition.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"functionDecomposition.d.ts","sourceRoot":"","sources":["../../../../src/math/utils/functions/functionDecomposition.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAYlE,OAAO,EAEL,YAAY,EACb,MAAM,4CAA4C,CAAC;AAcpD,eAAO,MAAM,sBAAsB,GACjC,MAAM,aAAa,EACnB,eAAc,YAA2C;WAElC,aAAa;WAAS,aAAa;GA8Q3D,CAAC;AAwEF,eAAO,MAAM,mBAAmB,GAAI,MAAM,aAAa,EAAE,QAAQ,MAAM,kBAItE,CAAC;AAEF,wBAAgB,YAAY,CAAC,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,aAAa,iBAMtE;AAMD,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAmBtE"}
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
import { abs } from "../../../tree/nodes/functions/absNode.js";
|
|
2
|
+
import { isFunctionNode } from "../../../tree/nodes/functions/functionNode.js";
|
|
3
|
+
import { isNumberNode } from "../../../tree/nodes/numbers/numberNode.js";
|
|
4
|
+
import { add } from "../../../tree/nodes/operators/addNode.js";
|
|
5
|
+
import { frac, isFractionNode, } from "../../../tree/nodes/operators/fractionNode.js";
|
|
6
|
+
import { multiply } from "../../../tree/nodes/operators/multiplyNode.js";
|
|
7
|
+
import { isOperatorNode } from "../../../tree/nodes/operators/operatorNode.js";
|
|
8
|
+
import { substract } from "../../../tree/nodes/operators/substractNode.js";
|
|
9
|
+
import { isVariableNode, } from "../../../tree/nodes/variables/variableNode.js";
|
|
10
|
+
import { parseAlgebraic } from "../../../tree/parsers/latexParser.js";
|
|
11
|
+
import { randomMany } from "../../../utils/alea/random.js";
|
|
12
|
+
import { getCartesiansProducts } from "../../../utils/arrays/cartesianProducts.js";
|
|
13
|
+
import { getAllNodePaths, nodeByReplacingNodeAtPath, } from "./functionComposition.js";
|
|
14
|
+
//
|
|
15
|
+
// Function decompositions: get all (u,v) so that f = uov
|
|
16
|
+
//
|
|
17
|
+
export const functionDecompositions = (node, variableNode = "x".toTree()) => {
|
|
18
|
+
const outArr = [];
|
|
19
|
+
function isTargetVariableNode(node) {
|
|
20
|
+
return isVariableNode(node) && node.name === variableNode.name;
|
|
21
|
+
}
|
|
22
|
+
const nodePathsWithVariableAtEnd = getAllNodePaths(node).filter((nodePathWithNodes) => isTargetVariableNode(nodePathWithNodes.arrNode[nodePathWithNodes.arrNode.length - 1]));
|
|
23
|
+
function nodePathUpward(nodePathWithNodes, level) {
|
|
24
|
+
return {
|
|
25
|
+
arrNode: nodePathWithNodes.arrNode.slice(0, nodePathWithNodes.arrNode.length - level),
|
|
26
|
+
nodePath: {
|
|
27
|
+
keys: nodePathWithNodes.nodePath.keys.slice(0, nodePathWithNodes.nodePath.keys.length - level),
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
function isNodesAreSame(node1, node2) {
|
|
32
|
+
const value = substract(node1, node2)
|
|
33
|
+
.simplify()
|
|
34
|
+
.evaluate({ [variableNode.name]: 177 });
|
|
35
|
+
return value === 0;
|
|
36
|
+
}
|
|
37
|
+
function isValidNodeU(nodeU) {
|
|
38
|
+
return (!isContainingFacetiousFrac(nodeU) &&
|
|
39
|
+
!nodeU.toTex().includes("NaN") &&
|
|
40
|
+
outArr.every(({ nodeU: nodeUExisting }) => !isNodesAreSame(nodeU, nodeUExisting)));
|
|
41
|
+
}
|
|
42
|
+
let counter = 0;
|
|
43
|
+
const levelPicks = getCartesiansProducts(nodePathsWithVariableAtEnd.map((nodePathWithNodes) => [
|
|
44
|
+
...Array(nodePathWithNodes.nodePath.keys.length).keys(),
|
|
45
|
+
]));
|
|
46
|
+
// console.log("levelPicks", levelPicks.length);
|
|
47
|
+
levelPicks.forEach((levelPick) => {
|
|
48
|
+
if (counter > 1000) {
|
|
49
|
+
return outArr;
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
const nodePathsUpByLevel = nodePathsWithVariableAtEnd.map((nodePathWithNodes, i) => {
|
|
53
|
+
const level = levelPick[i];
|
|
54
|
+
return nodePathUpward(nodePathWithNodes, level);
|
|
55
|
+
});
|
|
56
|
+
// console.log(
|
|
57
|
+
// "nodePathsUpByLevel",
|
|
58
|
+
// nodePathsUpByLevel.map((nodePathWithNodes) => {
|
|
59
|
+
// return {
|
|
60
|
+
// endNode:
|
|
61
|
+
// nodePathWithNodes.arrNode[
|
|
62
|
+
// nodePathWithNodes.arrNode.length - 1
|
|
63
|
+
// ].toTex(),
|
|
64
|
+
// keypath: nodePathWithNodes.nodePath.keys.join("."),
|
|
65
|
+
// };
|
|
66
|
+
// }),
|
|
67
|
+
// );
|
|
68
|
+
//merge wrt collision (collision means that some of the wrappedVariables trees are superimposing, and we don't want that)
|
|
69
|
+
const mergedNodePathsUpByLevel = nodePathsUpByLevel.reduce((acc, incomingNodePathWithNodes) => {
|
|
70
|
+
const incomingNodePathsString = incomingNodePathWithNodes.nodePath.keys.join(".");
|
|
71
|
+
const isIncomingIncluded = acc.some((accumulatedNodePathWithNodes) => {
|
|
72
|
+
const accumulatedNodePathsString = accumulatedNodePathWithNodes.nodePath.keys.join(".");
|
|
73
|
+
return incomingNodePathsString.startsWith(accumulatedNodePathsString);
|
|
74
|
+
});
|
|
75
|
+
const nodesPathsNotIncludedByIncoming = acc.filter((accumulatedNodePathWithNodes) => {
|
|
76
|
+
const accumulatedNodePathsString = accumulatedNodePathWithNodes.nodePath.keys.join(".");
|
|
77
|
+
return !accumulatedNodePathsString.startsWith(incomingNodePathsString);
|
|
78
|
+
});
|
|
79
|
+
if (isIncomingIncluded) {
|
|
80
|
+
return acc;
|
|
81
|
+
}
|
|
82
|
+
else if (nodesPathsNotIncludedByIncoming.length !== acc.length) {
|
|
83
|
+
return [
|
|
84
|
+
...nodesPathsNotIncludedByIncoming,
|
|
85
|
+
incomingNodePathWithNodes,
|
|
86
|
+
];
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
return [...acc, incomingNodePathWithNodes];
|
|
90
|
+
}
|
|
91
|
+
}, []);
|
|
92
|
+
// console.log(
|
|
93
|
+
// "mergedNodePathsUpByLevel",
|
|
94
|
+
// mergedNodePathsUpByLevel.map((nodePathWithNodes) => {
|
|
95
|
+
// return {
|
|
96
|
+
// endNode:
|
|
97
|
+
// nodePathWithNodes.arrNode[
|
|
98
|
+
// nodePathWithNodes.arrNode.length - 1
|
|
99
|
+
// ].toTex(),
|
|
100
|
+
// keypath: nodePathWithNodes.nodePath.keys.join("."),
|
|
101
|
+
// };
|
|
102
|
+
// }),
|
|
103
|
+
// );
|
|
104
|
+
const wrappedVariables = mergedNodePathsUpByLevel.map((nodePathWithNodes) => nodePathWithNodes &&
|
|
105
|
+
nodePathWithNodes.arrNode[nodePathWithNodes.arrNode.length - 1]);
|
|
106
|
+
for (let index = 0; index < wrappedVariables.length; index++) {
|
|
107
|
+
const sameNodeCandidate = wrappedVariables[index];
|
|
108
|
+
const otherWrappedVariables = wrappedVariables.filter((_, i) => i !== index);
|
|
109
|
+
const isSameNode = otherWrappedVariables.every((node) => isNodesAreSame(node, sameNodeCandidate));
|
|
110
|
+
if (isSameNode) {
|
|
111
|
+
const sameNode = sameNodeCandidate;
|
|
112
|
+
//replaces all sameNode with variableNode
|
|
113
|
+
const nodeU = mergedNodePathsUpByLevel.reduce((acc, nodePathWithNodes) => nodeByReplacingNodeAtPath(acc, nodePathWithNodes.nodePath, variableNode), node);
|
|
114
|
+
if (isValidNodeU(nodeU)) {
|
|
115
|
+
const nodeV = sameNode;
|
|
116
|
+
outArr.push({ nodeU, nodeV });
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
//attempt salvation
|
|
121
|
+
const comparisonDicts = otherWrappedVariables.map((node) => getComparisonDict(node, sameNodeCandidate));
|
|
122
|
+
// console.log(
|
|
123
|
+
// "comparisonDicts",
|
|
124
|
+
// comparisonDicts.map((comparisonDict) => {
|
|
125
|
+
// return {
|
|
126
|
+
// sub: comparisonDict?.sub?.toTex(),
|
|
127
|
+
// frac: comparisonDict?.frac?.toTex(),
|
|
128
|
+
// };
|
|
129
|
+
// }),
|
|
130
|
+
// );
|
|
131
|
+
const isSalvationPossible = comparisonDicts.every((comparisonDict) => comparisonDict?.sub !== undefined ||
|
|
132
|
+
comparisonDict?.frac !== undefined);
|
|
133
|
+
if (isSalvationPossible) {
|
|
134
|
+
const nodeGaskets = comparisonDicts.map((comparisonDict) => {
|
|
135
|
+
if (comparisonDict.sub !== undefined) {
|
|
136
|
+
return add(variableNode, comparisonDict.sub);
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
return multiply(comparisonDict.frac, variableNode);
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
// console.log(
|
|
143
|
+
// "nodeGaskets",
|
|
144
|
+
// nodeGaskets.map((node) => node.toTex()),
|
|
145
|
+
// );
|
|
146
|
+
const nodeUEnds = [...Array(wrappedVariables.length).keys()].map((i) => {
|
|
147
|
+
if (i === index) {
|
|
148
|
+
return variableNode;
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
return nodeGaskets[i < index ? i : i - 1];
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
let nodeU;
|
|
155
|
+
try {
|
|
156
|
+
nodeU = mergedNodePathsUpByLevel.reduce((acc, nodePathWithNodes, i) => nodeByReplacingNodeAtPath(acc, nodePathWithNodes.nodePath, nodeUEnds[i], 1, {}), node);
|
|
157
|
+
}
|
|
158
|
+
catch (_) {
|
|
159
|
+
try {
|
|
160
|
+
nodeU = mergedNodePathsUpByLevel.reduce((acc, nodePathWithNodes, i) => nodeByReplacingNodeAtPath(acc, nodePathWithNodes.nodePath, nodeUEnds[i], 0, {}), node);
|
|
161
|
+
}
|
|
162
|
+
catch (_) {
|
|
163
|
+
nodeU = mergedNodePathsUpByLevel.reduce((acc, nodePathWithNodes, i) => nodeByReplacingNodeAtPath(acc, nodePathWithNodes.nodePath, nodeUEnds[i]), node);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
if (isValidNodeU(nodeU)) {
|
|
167
|
+
const nodeV = sameNodeCandidate;
|
|
168
|
+
outArr.push({ nodeU, nodeV });
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
counter++;
|
|
175
|
+
});
|
|
176
|
+
return outArr;
|
|
177
|
+
};
|
|
178
|
+
//
|
|
179
|
+
// Function comparison
|
|
180
|
+
//
|
|
181
|
+
function getComparisonDict(node1, node2) {
|
|
182
|
+
const pool = [...Array(1000).keys()].map((i) => i - 500);
|
|
183
|
+
const evals = randomMany(pool, 5).map((x) => {
|
|
184
|
+
let v1;
|
|
185
|
+
try {
|
|
186
|
+
v1 = node1.evaluate({ x });
|
|
187
|
+
}
|
|
188
|
+
catch (_) {
|
|
189
|
+
v1 = undefined;
|
|
190
|
+
}
|
|
191
|
+
let v2;
|
|
192
|
+
try {
|
|
193
|
+
v2 = node2.evaluate({ x });
|
|
194
|
+
}
|
|
195
|
+
catch (_) {
|
|
196
|
+
v2 = undefined;
|
|
197
|
+
}
|
|
198
|
+
return { v1, v2 };
|
|
199
|
+
});
|
|
200
|
+
const successfulEvals = evals.filter(({ v1, v2 }) => v1 !== undefined && v2 !== undefined);
|
|
201
|
+
if (successfulEvals.length > 4) {
|
|
202
|
+
return {
|
|
203
|
+
sub: successfulEvals
|
|
204
|
+
.slice(1)
|
|
205
|
+
.every(({ v1, v2 }) => v1 - v2 === successfulEvals[0].v1 - successfulEvals[0].v2)
|
|
206
|
+
? substract(successfulEvals[0].v1, successfulEvals[0].v2).simplify()
|
|
207
|
+
: undefined,
|
|
208
|
+
frac: (() => {
|
|
209
|
+
const successfulEvalsWithoutZeroV2 = successfulEvals.filter(({ v2 }) => v2 !== 0);
|
|
210
|
+
// console.log(
|
|
211
|
+
// "successfulEvalsWithoutZeroV2",
|
|
212
|
+
// successfulEvalsWithoutZeroV2,
|
|
213
|
+
// );
|
|
214
|
+
return successfulEvalsWithoutZeroV2
|
|
215
|
+
.slice(1)
|
|
216
|
+
.every(({ v1, v2 }) => substract(frac(v1, v2), frac(successfulEvalsWithoutZeroV2[0].v1, successfulEvalsWithoutZeroV2[0].v2)).evaluate() === 0)
|
|
217
|
+
? frac(successfulEvalsWithoutZeroV2[0].v1, successfulEvalsWithoutZeroV2[0].v2).simplify({ towardsDistribute: true })
|
|
218
|
+
: undefined;
|
|
219
|
+
})(),
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
else {
|
|
223
|
+
return undefined;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
//
|
|
227
|
+
// Function composition
|
|
228
|
+
//
|
|
229
|
+
export const nodeBySubstitutingX = (node, strVar) => {
|
|
230
|
+
return parseAlgebraic(node.toTex({ forceParenthesis: true }).replaceAll("x", `("${strVar}")`));
|
|
231
|
+
};
|
|
232
|
+
export function composeNodes(nodeU, nodeV) {
|
|
233
|
+
const nodeUOV = nodeBySubstitutingX(nodeU.simplify(), nodeV.simplify().toTex()).simplify();
|
|
234
|
+
return nodeUOV;
|
|
235
|
+
}
|
|
236
|
+
//
|
|
237
|
+
// facetious fracs
|
|
238
|
+
//
|
|
239
|
+
export function isContainingFacetiousFrac(node) {
|
|
240
|
+
if (isOperatorNode(node)) {
|
|
241
|
+
if (isFractionNode(node)) {
|
|
242
|
+
return [node.leftChild, node.rightChild].every((nodeChild) => isNumberNode(nodeChild) &&
|
|
243
|
+
abs(nodeChild).evaluate() > Math.pow(10, 10));
|
|
244
|
+
}
|
|
245
|
+
else {
|
|
246
|
+
return (isContainingFacetiousFrac(node.leftChild) ||
|
|
247
|
+
isContainingFacetiousFrac(node.rightChild));
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
else if (isFunctionNode(node)) {
|
|
251
|
+
return isContainingFacetiousFrac(node.child);
|
|
252
|
+
}
|
|
253
|
+
else {
|
|
254
|
+
return false;
|
|
255
|
+
}
|
|
256
|
+
}
|
package/lib/server.js
CHANGED
|
@@ -30,6 +30,7 @@ const runServer = () => {
|
|
|
30
30
|
console.log("math exos", mathExercises.length);
|
|
31
31
|
console.log("math hints", mathExercises.filter((exo) => exo.hasHintAndCorrection).length);
|
|
32
32
|
console.log("pc exos", `${pcExercises.length}`);
|
|
33
|
+
console.log("pc hints", pcExercises.filter((exo) => exo.hasHintAndCorrection).length);
|
|
33
34
|
playground();
|
|
34
35
|
logIdentifiers();
|
|
35
36
|
app.get("/", (_req, res) => {
|
|
@@ -45,7 +46,7 @@ const runServer = () => {
|
|
|
45
46
|
const n = Number(req.query.n);
|
|
46
47
|
const exoId = req.query.exoId;
|
|
47
48
|
const options = req.query.options
|
|
48
|
-
? JSON.parse(req.query.options)
|
|
49
|
+
? JSON.parse(decodeURIComponent(req.query.options))
|
|
49
50
|
: undefined;
|
|
50
51
|
const exo = allExercises.find((exo) => exo.id == exoId);
|
|
51
52
|
if (!exo) {
|
|
@@ -63,10 +64,10 @@ const runServer = () => {
|
|
|
63
64
|
return;
|
|
64
65
|
}
|
|
65
66
|
const identifiers = req.query.identifiers
|
|
66
|
-
? JSON.parse(req.query.identifiers)
|
|
67
|
+
? JSON.parse(decodeURIComponent(req.query.identifiers))
|
|
67
68
|
: undefined;
|
|
68
69
|
const options = req.query.options
|
|
69
|
-
? JSON.parse(req.query.options)
|
|
70
|
+
? JSON.parse(decodeURIComponent(req.query.options))
|
|
70
71
|
: undefined;
|
|
71
72
|
const question = exo?.getQuestionFromIdentifiers(identifiers, options);
|
|
72
73
|
res.json({
|
|
@@ -78,12 +79,12 @@ const runServer = () => {
|
|
|
78
79
|
const n = Number(req.query.n) || 4;
|
|
79
80
|
const exoId = req.query.exoId;
|
|
80
81
|
const options = req.query.options
|
|
81
|
-
? JSON.parse(req.query.options)
|
|
82
|
+
? JSON.parse(decodeURIComponent(req.query.options))
|
|
82
83
|
: undefined;
|
|
83
84
|
const identifiers = req.query.identifiers
|
|
84
|
-
? JSON.parse(req.query.identifiers)
|
|
85
|
+
? JSON.parse(decodeURIComponent(req.query.identifiers))
|
|
85
86
|
: undefined;
|
|
86
|
-
const answer = req.query.answer;
|
|
87
|
+
const answer = JSON.parse(decodeURIComponent(req.query.answer));
|
|
87
88
|
const exo = allExercises.find((exo) => exo.id == exoId);
|
|
88
89
|
if (!exo) {
|
|
89
90
|
res.send("Exo not found");
|
|
@@ -99,13 +100,13 @@ const runServer = () => {
|
|
|
99
100
|
app.get("/isAnswerTableValid", (req, res) => {
|
|
100
101
|
const exoId = req.query.exoId;
|
|
101
102
|
const options = req.query.options
|
|
102
|
-
? JSON.parse(req.query.options)
|
|
103
|
+
? JSON.parse(decodeURIComponent(req.query.options))
|
|
103
104
|
: undefined;
|
|
104
105
|
const identifiers = req.query.identifiers
|
|
105
|
-
? JSON.parse(req.query.identifiers)
|
|
106
|
+
? JSON.parse(decodeURIComponent(req.query.identifiers))
|
|
106
107
|
: undefined;
|
|
107
|
-
const studentAnswer = JSON.parse(req.query.studentAnswer);
|
|
108
|
-
const answerTable = JSON.parse(req.query.answerTable);
|
|
108
|
+
const studentAnswer = JSON.parse(decodeURIComponent(req.query.studentAnswer));
|
|
109
|
+
const answerTable = JSON.parse(decodeURIComponent(req.query.answerTable));
|
|
109
110
|
const exo = allExercises.find((exo) => exo.id == exoId);
|
|
110
111
|
if (!exo) {
|
|
111
112
|
res.send("Exo not found");
|
|
@@ -121,13 +122,13 @@ const runServer = () => {
|
|
|
121
122
|
app.get("/isAnswerValid", (req, res) => {
|
|
122
123
|
const exoId = req.query.exoId;
|
|
123
124
|
const options = req.query.options
|
|
124
|
-
? JSON.parse(req.query.options)
|
|
125
|
+
? JSON.parse(decodeURIComponent(req.query.options))
|
|
125
126
|
: undefined;
|
|
126
127
|
const identifiers = req.query.identifiers
|
|
127
|
-
? JSON.parse(req.query.identifiers)
|
|
128
|
+
? JSON.parse(decodeURIComponent(req.query.identifiers))
|
|
128
129
|
: undefined;
|
|
129
|
-
const studentAnswer = JSON.parse(req.query.studentAnswer);
|
|
130
|
-
const answer = JSON.parse(req.query.answer);
|
|
130
|
+
const studentAnswer = JSON.parse(decodeURIComponent(req.query.studentAnswer));
|
|
131
|
+
const answer = JSON.parse(decodeURIComponent(req.query.answer));
|
|
131
132
|
const exo = allExercises.find((exo) => exo.id == exoId);
|
|
132
133
|
if (!exo) {
|
|
133
134
|
res.send("Exo not found");
|
|
@@ -143,13 +144,13 @@ const runServer = () => {
|
|
|
143
144
|
app.get("/isGGBAnswerValid", (req, res) => {
|
|
144
145
|
const exoId = req.query.exoId;
|
|
145
146
|
const options = req.query.options
|
|
146
|
-
? JSON.parse(req.query.options)
|
|
147
|
+
? JSON.parse(decodeURIComponent(req.query.options))
|
|
147
148
|
: undefined;
|
|
148
149
|
const identifiers = req.query.identifiers
|
|
149
|
-
? JSON.parse(req.query.identifiers)
|
|
150
|
+
? JSON.parse(decodeURIComponent(req.query.identifiers))
|
|
150
151
|
: undefined;
|
|
151
|
-
const studentAnswer = JSON.parse(req.query.studentAnswer);
|
|
152
|
-
const ggbAnswer = JSON.parse(req.query.ggbAnswer);
|
|
152
|
+
const studentAnswer = JSON.parse(decodeURIComponent(req.query.studentAnswer));
|
|
153
|
+
const ggbAnswer = JSON.parse(decodeURIComponent(req.query.ggbAnswer));
|
|
153
154
|
const exo = allExercises.find((exo) => exo.id == exoId);
|
|
154
155
|
if (!exo) {
|
|
155
156
|
res.send("Exo not found");
|
|
@@ -165,7 +166,7 @@ const runServer = () => {
|
|
|
165
166
|
app.get("/question", (req, res) => {
|
|
166
167
|
const exoId = req.query.exoId;
|
|
167
168
|
const options = req.query.options
|
|
168
|
-
? JSON.parse(req.query.options)
|
|
169
|
+
? JSON.parse(decodeURIComponent(req.query.options))
|
|
169
170
|
: undefined;
|
|
170
171
|
const exoIndex = allExercises.findIndex((exo) => exo.id == exoId);
|
|
171
172
|
const exo = allExercises[exoIndex];
|
|
@@ -180,7 +181,7 @@ const runServer = () => {
|
|
|
180
181
|
app.get("/exo", (req, res) => {
|
|
181
182
|
const exoId = req.query.exoId;
|
|
182
183
|
const options = req.query.options
|
|
183
|
-
? JSON.parse(req.query.options)
|
|
184
|
+
? JSON.parse(decodeURIComponent(req.query.options))
|
|
184
185
|
: undefined;
|
|
185
186
|
const exoIndex = allExercises.findIndex((exo) => exo.id == exoId);
|
|
186
187
|
const exo = allExercises[exoIndex];
|
|
@@ -198,7 +199,7 @@ const runServer = () => {
|
|
|
198
199
|
app.get("/qcmExo", (req, res) => {
|
|
199
200
|
const exoId = req.query.exoId;
|
|
200
201
|
const options = req.query.options
|
|
201
|
-
? JSON.parse(req.query.options)
|
|
202
|
+
? JSON.parse(decodeURIComponent(req.query.options))
|
|
202
203
|
: undefined;
|
|
203
204
|
const exoIndex = allExercises.findIndex((exo) => exo.id == exoId);
|
|
204
205
|
const exo = allExercises[exoIndex];
|
|
@@ -225,7 +226,7 @@ const runServer = () => {
|
|
|
225
226
|
app.post("/vea", jsonParser, (req, res) => {
|
|
226
227
|
const exoId = req.query.exoId;
|
|
227
228
|
const options = req.query.options
|
|
228
|
-
? JSON.parse(req.query.options)
|
|
229
|
+
? JSON.parse(decodeURIComponent(req.query.options))
|
|
229
230
|
: undefined;
|
|
230
231
|
const { ans, veaProps } = req.body;
|
|
231
232
|
const exoIndex = allExercises.findIndex((exo) => exo.id == exoId);
|
|
@@ -246,7 +247,7 @@ const runServer = () => {
|
|
|
246
247
|
app.post("/tableVea", jsonParser, (req, res) => {
|
|
247
248
|
const exoId = req.query.exoId;
|
|
248
249
|
const options = req.query.options
|
|
249
|
-
? JSON.parse(req.query.options)
|
|
250
|
+
? JSON.parse(decodeURIComponent(req.query.options))
|
|
250
251
|
: undefined;
|
|
251
252
|
const { ans, veaProps } = req.body;
|
|
252
253
|
const exoIndex = allExercises.findIndex((exo) => exo.id == exoId);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"powerNode.d.ts","sourceRoot":"","sources":["../../../../src/tree/nodes/operators/powerNode.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAChF,OAAO,EAAE,WAAW,EAAE,YAAY,EAAkB,MAAM,mBAAmB,CAAC;AAG9E,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"powerNode.d.ts","sourceRoot":"","sources":["../../../../src/tree/nodes/operators/powerNode.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAChF,OAAO,EAAE,WAAW,EAAE,YAAY,EAAkB,MAAM,mBAAmB,CAAC;AAG9E,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAMrE,wBAAgB,WAAW,CAAC,CAAC,EAAE,IAAI,GAAG,CAAC,IAAI,SAAS,CAEnD;AAED,wBAAgB,YAAY,CAAC,CAAC,EAAE,IAAI,GAAG,CAAC,IAAI,UAAU,CAErD;AACD,eAAO,MAAM,MAAM,GAAI,GAAG,aAAa,GAAG,MAAM,GAAG,MAAM,eAKxD,CAAC;AAEF,eAAO,MAAM,KAAK,GAChB,GAAG,aAAa,GAAG,MAAM,GAAG,MAAM,EAClC,GAAG,aAAa,GAAG,MAAM,GAAG,MAAM,EAClC,OAAO,WAAW,cAOnB,CAAC;AAEF,qBAAa,SAAU,YAAW,YAAY;IAC5C,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,EAAE,EAAE,WAAW,CAAC;IAChB,SAAS,EAAE,aAAa,CAAC;IACzB,UAAU,EAAE,aAAa,CAAC;IAC1B,IAAI,EAAE,QAAQ,CAAC;IACf,SAAS,EAAE,OAAO,CAAC;gBAEjB,SAAS,EAAE,aAAa,EACxB,UAAU,EAAE,aAAa,EACzB,IAAI,CAAC,EAAE,WAAW;IAUpB,YAAY,IAAI,MAAM;IAGtB,aAAa;;;;;;;;;IAOb,iBAAiB;IAqBjB,cAAc,IAAI,MAAM,EAAE;IAI1B,KAAK,CAAC,IAAI,CAAC,EAAE,YAAY,GAAG,MAAM;IA0BlC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAMtC,oBAAoB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC;IAOxD,QAAQ,CAAC,IAAI,CAAC,EAAE,eAAe,EAAE,IAAI,UAAQ,GAAG,aAAa;IA6D7D,MAAM,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO;IAOpC,UAAU,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,aAAa;CAcxD;AAED,qBAAa,UAAW,SAAQ,SAAS;gBAC3B,KAAK,EAAE,aAAa,EAAE,IAAI,CAAC,EAAE,WAAW;CAIrD"}
|