math-exercises 3.0.124 → 3.0.125
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/primeNumbers.d.ts +1 -1
- package/lib/exercises/math/calcul/arithmetics/primeNumbers.d.ts.map +1 -1
- package/lib/exercises/math/calcul/arithmetics/primeNumbers.js +20 -14
- package/lib/exercises/math/calcul/fractions/fractionsMix.js +1 -1
- package/lib/exercises/math/conversion/volumeConversion.d.ts.map +1 -1
- package/lib/exercises/math/conversion/volumeConversion.js +7 -1
- package/lib/exercises/math/derivation/derivative/exp/expDerivativeFour.d.ts.map +1 -1
- package/lib/exercises/math/derivation/derivative/exp/expDerivativeFour.js +9 -3
- package/lib/exercises/math/functions/affines/drawAffineFromLitExp.js +5 -5
- package/lib/exercises/math/functions/basics/findZeroesProductQuotient.d.ts.map +1 -1
- package/lib/exercises/math/functions/basics/findZeroesProductQuotient.js +29 -2
- package/lib/exercises/math/functions/basics/inverseImageFunctionGeogebra.d.ts.map +1 -1
- package/lib/exercises/math/functions/basics/inverseImageFunctionGeogebra.js +72 -61
- package/lib/exercises/math/functions/trinoms/roots/rootsFromDevForm.d.ts.map +1 -1
- package/lib/exercises/math/functions/trinoms/roots/rootsFromDevForm.js +41 -16
- package/lib/exercises/math/functions/trinoms/roots/rootsReading.d.ts.map +1 -1
- package/lib/exercises/math/functions/trinoms/roots/rootsReading.js +3 -2
- package/lib/exercises/math/functions/trinoms/sign/trinomSignFromFacto.d.ts +1 -0
- package/lib/exercises/math/functions/trinoms/sign/trinomSignFromFacto.d.ts.map +1 -1
- package/lib/exercises/math/functions/trinoms/sign/trinomSignFromFacto.js +21 -13
- package/lib/exercises/math/geometry/perimeters/circleCircumference.d.ts.map +1 -1
- package/lib/exercises/math/geometry/perimeters/circleCircumference.js +15 -7
- package/lib/exercises/math/geometry/shapes/basicShapesNaming.d.ts.map +1 -1
- package/lib/exercises/math/geometry/shapes/basicShapesNaming.js +5 -3
- package/lib/exercises/math/percent/evolutions/evolutionToCM.js +2 -2
- package/lib/exercises/math/percent/findProportion.d.ts +6 -1
- package/lib/exercises/math/percent/findProportion.d.ts.map +1 -1
- package/lib/exercises/math/percent/findProportion.js +162 -45
- package/lib/exercises/math/powers/calculateNegativePower.d.ts +5 -1
- package/lib/exercises/math/powers/calculateNegativePower.d.ts.map +1 -1
- package/lib/exercises/math/powers/calculateNegativePower.js +93 -29
- package/lib/exercises/math/probaStat/probaFromTableNoContext.d.ts.map +1 -1
- package/lib/exercises/math/probaStat/probaFromTableNoContext.js +10 -2
- package/lib/exercises/math/probaStat/probaFromTableWithContext.d.ts.map +1 -1
- package/lib/exercises/math/probaStat/probaFromTableWithContext.js +2 -1
- package/lib/exercises/math/probaStat/stats1var/quartilesList.d.ts +4 -1
- package/lib/exercises/math/probaStat/stats1var/quartilesList.d.ts.map +1 -1
- package/lib/exercises/math/probaStat/stats1var/quartilesList.js +46 -27
- package/lib/exercises/math/sequences/geometric/geometricFindExplicitFormula.d.ts.map +1 -1
- package/lib/exercises/math/sequences/geometric/geometricFindExplicitFormula.js +14 -2
- package/lib/exercises/math/sequences/geometric/geometricReasonUsage.d.ts +1 -0
- package/lib/exercises/math/sequences/geometric/geometricReasonUsage.d.ts.map +1 -1
- package/lib/exercises/math/sequences/geometric/geometricReasonUsage.js +43 -19
- package/lib/exercises/math/sequences/sequenceEvaluation.d.ts.map +1 -1
- package/lib/exercises/math/sequences/sequenceEvaluation.js +18 -1
- package/lib/exercises/pc/chemicalReactions/chemicalEquations.d.ts.map +1 -1
- package/lib/exercises/pc/chemicalReactions/chemicalEquations.js +17 -2
- package/lib/exercises/pc/mole/molarMass.d.ts.map +1 -1
- package/lib/exercises/pc/mole/molarMass.js +7 -1
- package/lib/exercises/pc/motion/averageSpeed.d.ts +9 -4
- package/lib/exercises/pc/motion/averageSpeed.d.ts.map +1 -1
- package/lib/exercises/pc/motion/averageSpeed.js +132 -61
- package/lib/exercises/pc/motion/averageSpeedCalculation.d.ts.map +1 -1
- package/lib/exercises/pc/motion/averageSpeedCalculation.js +10 -4
- package/lib/exercises/pc/recognizeRefractionOrReflectionAngles.d.ts +2 -2
- package/lib/exercises/pc/recognizeRefractionOrReflectionAngles.js +15 -15
- package/lib/exercises/utils/geogebra/toolBarConstructor.d.ts +1 -0
- package/lib/exercises/utils/geogebra/toolBarConstructor.d.ts.map +1 -1
- package/lib/exercises/utils/geogebra/toolBarConstructor.js +3 -1
- package/lib/index.d.ts +46 -11
- package/lib/index.d.ts.map +1 -1
- package/lib/pc/units/timeUnits.d.ts +5 -3
- package/lib/pc/units/timeUnits.d.ts.map +1 -1
- package/lib/pc/units/timeUnits.js +25 -19
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"primeNumbers.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/calcul/arithmetics/primeNumbers.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,QAAQ,EAkBT,MAAM,sBAAsB,CAAC;AAmB9B,KAAK,WAAW,GAAG;IACjB,EAAE,EAAE,MAAM,CAAC;CACZ,CAAC;
|
|
1
|
+
{"version":3,"file":"primeNumbers.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/calcul/arithmetics/primeNumbers.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,QAAQ,EAkBT,MAAM,sBAAsB,CAAC;AAmB9B,KAAK,WAAW,GAAG;IACjB,EAAE,EAAE,MAAM,CAAC;CACZ,CAAC;AAsMF,KAAK,OAAO,GAAG;IACb,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAcF,eAAO,MAAM,YAAY,EAAE,QAAQ,CAAC,WAAW,EAAE,OAAO,CAgBvD,CAAC"}
|
|
@@ -26,14 +26,16 @@ const getInstruction = (identifiers) => {
|
|
|
26
26
|
|
|
27
27
|
$$
|
|
28
28
|
${getStartStatement(identifiers)}
|
|
29
|
-
|
|
29
|
+
$$
|
|
30
|
+
|
|
31
|
+
`;
|
|
30
32
|
};
|
|
31
33
|
const getAnswer = (identifiers, opts) => {
|
|
32
34
|
const { nb } = identifiers;
|
|
33
35
|
const decomp = primeDecomposition(nb);
|
|
34
|
-
const
|
|
36
|
+
const asPowers = opts?.asPowers;
|
|
35
37
|
const nodes = [];
|
|
36
|
-
if (
|
|
38
|
+
if (asPowers) {
|
|
37
39
|
for (const d of decomp) {
|
|
38
40
|
if (d.power === 1)
|
|
39
41
|
nodes.push(d.value.toTree());
|
|
@@ -50,7 +52,8 @@ const getAnswer = (identifiers, opts) => {
|
|
|
50
52
|
}
|
|
51
53
|
return operatorComposition(MultiplyNode, nodes).toTex();
|
|
52
54
|
};
|
|
53
|
-
const getPrimeNumbers = (
|
|
55
|
+
const getPrimeNumbers = (optsIn) => {
|
|
56
|
+
const opts = optsIn ?? optsDefault;
|
|
54
57
|
const rand = randint(2, 5);
|
|
55
58
|
let nb = 0;
|
|
56
59
|
let counter = 0;
|
|
@@ -71,16 +74,16 @@ const getPrimeNumbers = (opts) => {
|
|
|
71
74
|
const getHint = (identifiers) => {
|
|
72
75
|
return `Les premiers nombres premiers sont : $2$, $3$, $5$, $7$, $11$.
|
|
73
76
|
|
|
74
|
-
|
|
77
|
+
On peut essayer de diviser le nombre $${identifiers.nb}$ par ces nombres.`;
|
|
75
78
|
};
|
|
76
79
|
const getCorrection = (identifiers, opts) => {
|
|
77
80
|
const { nb } = identifiers;
|
|
78
81
|
let n = nb;
|
|
79
82
|
const list = [];
|
|
80
|
-
const
|
|
81
|
-
const answerPowers =
|
|
82
|
-
const answerNoPowers = getAnswer(identifiers, {
|
|
83
|
-
const powerIsDifferent = !
|
|
83
|
+
const asPowers = opts?.asPowers;
|
|
84
|
+
const answerPowers = asPowers ? getAnswer(identifiers, opts) : undefined;
|
|
85
|
+
const answerNoPowers = getAnswer(identifiers, { asPowers: false });
|
|
86
|
+
const powerIsDifferent = !asPowers ? false : answerPowers !== answerNoPowers;
|
|
84
87
|
for (const k of [2, 3, 5, 7, 11]) {
|
|
85
88
|
let counter = 0;
|
|
86
89
|
while (n % k === 0) {
|
|
@@ -98,7 +101,7 @@ ${alignTex(list)}
|
|
|
98
101
|
On prend alors la liste des quotients :
|
|
99
102
|
|
|
100
103
|
$$
|
|
101
|
-
${nb.frenchify()} = ${answerNoPowers} ${powerIsDifferent ? `=${answerPowers}` : ""}
|
|
104
|
+
${nb.frenchify()} = ${answerNoPowers} ${powerIsDifferent && asPowers ? `=${answerPowers}` : ""}
|
|
102
105
|
$$
|
|
103
106
|
`;
|
|
104
107
|
};
|
|
@@ -152,7 +155,7 @@ const isAnswerValid = (ans, { nb }) => {
|
|
|
152
155
|
try {
|
|
153
156
|
//? aucune idée de comment, mais les élèves envoient parfois des espaces
|
|
154
157
|
const parsed = parseAlgebraic(ans.replaceAll("\\ ", ""));
|
|
155
|
-
if (!isMultiplyNode(parsed))
|
|
158
|
+
if (!(isMultiplyNode(parsed) || isPowerNode(parsed)))
|
|
156
159
|
return false;
|
|
157
160
|
const externals = [];
|
|
158
161
|
const recur = (node) => {
|
|
@@ -192,13 +195,16 @@ const isAnswerValid = (ans, { nb }) => {
|
|
|
192
195
|
return handleVEAError(err);
|
|
193
196
|
}
|
|
194
197
|
};
|
|
198
|
+
const optsDefault = {
|
|
199
|
+
asPowers: true,
|
|
200
|
+
};
|
|
195
201
|
const options = [
|
|
196
202
|
{
|
|
197
|
-
id: "
|
|
198
|
-
label: "
|
|
203
|
+
id: "asPowers",
|
|
204
|
+
label: "correction avec des puissances",
|
|
199
205
|
target: GeneratorOptionTarget.answer,
|
|
200
206
|
type: GeneratorOptionType.checkbox,
|
|
201
|
-
defaultValue:
|
|
207
|
+
defaultValue: optsDefault.asPowers,
|
|
202
208
|
},
|
|
203
209
|
];
|
|
204
210
|
export const primeNumbers = {
|
|
@@ -44,7 +44,7 @@ const getAnswer = (identifiers) => {
|
|
|
44
44
|
return statement.simplify().toTex();
|
|
45
45
|
};
|
|
46
46
|
const getInstruction = (identifiers) => {
|
|
47
|
-
return `Écrire sous la forme d'une fraction irréductible :
|
|
47
|
+
return `Écrire sous la forme d'une fraction irréductible ou d'un entier :
|
|
48
48
|
|
|
49
49
|
$$
|
|
50
50
|
${getStatement(identifiers).toTex()}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"volumeConversion.d.ts","sourceRoot":"","sources":["../../../../src/exercises/math/conversion/volumeConversion.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"volumeConversion.d.ts","sourceRoot":"","sources":["../../../../src/exercises/math/conversion/volumeConversion.ts"],"names":[],"mappings":"AAYA,OAAO,EACL,QAAQ,EAcT,MAAM,mBAAmB,CAAC;AAE3B,KAAK,WAAW,GAAG;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,0BAA0B,EAAE,MAAM,CAAC;IACnC,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAwIF,eAAO,MAAM,gBAAgB,EAAE,QAAQ,CAAC,WAAW,CAclD,CAAC"}
|
|
@@ -2,6 +2,8 @@ import { Decimal, DecimalConstructor, } from "../../../math/numbers/decimals/dec
|
|
|
2
2
|
import { randint } from "../../../math/utils/random/randint.js";
|
|
3
3
|
import { frac } from "../../../tree/nodes/operators/fractionNode.js";
|
|
4
4
|
import { multiply } from "../../../tree/nodes/operators/multiplyNode.js";
|
|
5
|
+
import { substract } from "../../../tree/nodes/operators/substractNode.js";
|
|
6
|
+
import { parseAlgebraic } from "../../../tree/parsers/latexParser.js";
|
|
5
7
|
import { shuffle } from "../../../utils/alea/shuffle.js";
|
|
6
8
|
import { doWhile } from "../../../utils/doWhile.js";
|
|
7
9
|
import { alignTex } from "../../../utils/latex/alignTex.js";
|
|
@@ -99,7 +101,11 @@ const getPropositions = (n, { answer, randomUnitIndex, randomUnitInstructionInde
|
|
|
99
101
|
return shuffle(propositions);
|
|
100
102
|
};
|
|
101
103
|
const isAnswerValid = (ans, { answer }) => {
|
|
102
|
-
return ans === answer
|
|
104
|
+
return (ans === answer ||
|
|
105
|
+
(() => {
|
|
106
|
+
const [nodeAns, nodeAnswer] = [ans, answer].map((tex) => parseAlgebraic(tex));
|
|
107
|
+
return substract(nodeAns, nodeAnswer).evaluate() === 0;
|
|
108
|
+
})());
|
|
103
109
|
};
|
|
104
110
|
export const volumeConversion = {
|
|
105
111
|
id: "volumeConversion",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"expDerivativeFour.d.ts","sourceRoot":"","sources":["../../../../../../src/exercises/math/derivation/derivative/exp/expDerivativeFour.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAaT,MAAM,6BAA6B,CAAC;AAQrC,KAAK,WAAW,GAAG;IACjB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB,CAAC;
|
|
1
|
+
{"version":3,"file":"expDerivativeFour.d.ts","sourceRoot":"","sources":["../../../../../../src/exercises/math/derivation/derivative/exp/expDerivativeFour.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAaT,MAAM,6BAA6B,CAAC;AAQrC,KAAK,WAAW,GAAG;IACjB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB,CAAC;AA2FF,eAAO,MAAM,iBAAiB,EAAE,QAAQ,CAAC,WAAW,CAenD,CAAC"}
|
|
@@ -18,12 +18,15 @@ f(x) = ${fct.toTex()}
|
|
|
18
18
|
$$`;
|
|
19
19
|
};
|
|
20
20
|
const getAnswer = (identifiers) => {
|
|
21
|
+
return getAnswerNode(identifiers).toTex();
|
|
22
|
+
};
|
|
23
|
+
const getAnswerNode = (identifiers) => {
|
|
21
24
|
const { affine1Coeffs, affine2Coeffs } = identifiers;
|
|
22
25
|
const affine1 = new Affine(affine1Coeffs[1], affine1Coeffs[0]);
|
|
23
26
|
const affine2 = new Affine(affine2Coeffs[1], affine2Coeffs[0]);
|
|
24
27
|
const exp = new ExpNode(affine2.toTree());
|
|
25
28
|
const deriv = new MultiplyNode(new Affine(affine2.a * affine1.a, affine1.a + affine2.a * affine1.b).toTree(), exp);
|
|
26
|
-
return deriv.simplify()
|
|
29
|
+
return deriv.simplify();
|
|
27
30
|
};
|
|
28
31
|
const getExpDerivativeFourQuestion = () => {
|
|
29
32
|
const affine1 = AffineConstructor.random();
|
|
@@ -53,12 +56,15 @@ const getPropositions = (n, { answer }) => {
|
|
|
53
56
|
});
|
|
54
57
|
return shuffleProps(propositions, n);
|
|
55
58
|
};
|
|
56
|
-
const isAnswerValid = (ans, { answer }) => {
|
|
59
|
+
const isAnswerValid = (ans, { answer, ...identifiers }) => {
|
|
57
60
|
try {
|
|
58
61
|
const parsed = parseAlgebraic(ans);
|
|
59
62
|
if (!parsed)
|
|
60
63
|
return false;
|
|
61
|
-
return parsed.simplify().toTex() === answer;
|
|
64
|
+
// return parsed.simplify().toTex() === answer;
|
|
65
|
+
const ansTex = parsed.simplify().toTex();
|
|
66
|
+
const ansNode = getAnswerNode(identifiers);
|
|
67
|
+
return ansNode.toAllValidTexs().includes(ansTex);
|
|
62
68
|
}
|
|
63
69
|
catch (err) {
|
|
64
70
|
return handleVEAError(err);
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { isGGBLine } from "../../../../exercises/utils/geogebra/isGGBLine.js";
|
|
2
|
-
import { isGGBPoint } from "../../../../exercises/utils/geogebra/isGGBPoint.js";
|
|
3
1
|
import { toolBarConstructor } from "../../../../exercises/utils/geogebra/toolBarConstructor.js";
|
|
4
2
|
import { getDistinctQuestions } from "../../../../exercises/utils/getDistinctQuestions.js";
|
|
5
|
-
import { deleteObjectNamesFromAnswer } from "../../../../geogebra/deleteObjectNamesFromAnswer.js";
|
|
6
3
|
import { GeogebraConstructor } from "../../../../geogebra/geogebraConstructor.js";
|
|
7
|
-
import { approxEqual } from "../../../../geogebra/parsers/approxEqual.js";
|
|
8
|
-
import { Point } from "../../../../math/geometry/point.js";
|
|
9
4
|
import { Affine, AffineConstructor } from "../../../../math/polynomials/affine.js";
|
|
10
5
|
import { random } from "../../../../utils/alea/random.js";
|
|
6
|
+
import { isGGBLine } from "../../../../exercises/utils/geogebra/isGGBLine.js";
|
|
7
|
+
import { isGGBPoint } from "../../../../exercises/utils/geogebra/isGGBPoint.js";
|
|
8
|
+
import { deleteObjectNamesFromAnswer } from "../../../../geogebra/deleteObjectNamesFromAnswer.js";
|
|
9
|
+
import { approxEqual } from "../../../../geogebra/parsers/approxEqual.js";
|
|
10
|
+
import { Point } from "../../../../math/geometry/point.js";
|
|
11
11
|
import { arrayEqual } from "../../../../utils/arrays/arrayEqual.js";
|
|
12
12
|
const getInstruction = (identifiers) => {
|
|
13
13
|
const { correctA, correctB, nameFunc } = identifiers;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"findZeroesProductQuotient.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/functions/basics/findZeroesProductQuotient.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAeT,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"findZeroesProductQuotient.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/functions/basics/findZeroesProductQuotient.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAeT,MAAM,6BAA6B,CAAC;AAuBrC,KAAK,WAAW,GAAG;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,CAAC,CAAC,EAAE,MAAM,CAAC;CACZ,CAAC;AA6QF,eAAO,MAAM,yBAAyB,EAAE,QAAQ,CAAC,WAAW,CAkB3D,CAAC"}
|
|
@@ -153,17 +153,44 @@ $$
|
|
|
153
153
|
const getKeys = () => {
|
|
154
154
|
return ["S", "equal", "lbrace", "semicolon", "rbrace"];
|
|
155
155
|
};
|
|
156
|
-
const isAnswerValid = (ans, { answer }) => {
|
|
156
|
+
const isAnswerValid = (ans, { answer, ...identifiers }) => {
|
|
157
157
|
try {
|
|
158
158
|
const parsed = discreteSetParser(ans);
|
|
159
159
|
if (!parsed)
|
|
160
160
|
return false;
|
|
161
|
-
|
|
161
|
+
const roots = getRoots(identifiers).map((r) => r.simplify());
|
|
162
|
+
return isArrayOfNodesValid(parsed.elements, roots);
|
|
162
163
|
}
|
|
163
164
|
catch (err) {
|
|
164
165
|
return handleVEAError(err);
|
|
165
166
|
}
|
|
166
167
|
};
|
|
168
|
+
const isArrayOfNodesValid = (arrAns, arrAnswer) => {
|
|
169
|
+
//tried with toAllValidTexs() but there is always an unhandled case
|
|
170
|
+
function isNodesEqual(node1, node2) {
|
|
171
|
+
return [1, 1_000, 1_000_000].every((factor) => substract(multiply(factor, node1), multiply(factor, node2)).evaluate() === 0);
|
|
172
|
+
}
|
|
173
|
+
const dictAnswer = Object.fromEntries(arrAnswer.map((node, i) => [i, node]));
|
|
174
|
+
let isValid = true;
|
|
175
|
+
for (let i = 0; i < arrAns.length; i++) {
|
|
176
|
+
const nodeAns = arrAns[i];
|
|
177
|
+
let isFound = false;
|
|
178
|
+
const keys = Object.keys(dictAnswer);
|
|
179
|
+
for (let j = 0; j < keys.length; j++) {
|
|
180
|
+
const key = keys[j];
|
|
181
|
+
const answerNode = dictAnswer[key];
|
|
182
|
+
if (isNodesEqual(nodeAns, answerNode)) {
|
|
183
|
+
isFound = true;
|
|
184
|
+
delete dictAnswer[key]; //one-to-one correspondence
|
|
185
|
+
break;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
isValid = isValid && isFound;
|
|
189
|
+
if (!isValid)
|
|
190
|
+
break;
|
|
191
|
+
}
|
|
192
|
+
return isValid;
|
|
193
|
+
};
|
|
167
194
|
const getFindZeroesProductQuotientQuestion = () => {
|
|
168
195
|
const type = randint(0, 3);
|
|
169
196
|
let a = 0;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inverseImageFunctionGeogebra.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/functions/basics/inverseImageFunctionGeogebra.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAeT,MAAM,6BAA6B,CAAC;AAcrC,KAAK,WAAW,GAAG;IAEjB,MAAM,EAAE,MAAM,CAAC;IAIf,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC;CACpB,CAAC;
|
|
1
|
+
{"version":3,"file":"inverseImageFunctionGeogebra.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/functions/basics/inverseImageFunctionGeogebra.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAeT,MAAM,6BAA6B,CAAC;AAcrC,KAAK,WAAW,GAAG;IAEjB,MAAM,EAAE,MAAM,CAAC;IAIf,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC;CACpB,CAAC;AAyOF,eAAO,MAAM,4BAA4B,EAAE,QAAQ,CAAC,WAAW,CAkB9D,CAAC"}
|
|
@@ -56,74 +56,85 @@ const getGGBOptions = (identifiers) => {
|
|
|
56
56
|
});
|
|
57
57
|
};
|
|
58
58
|
const getInverseImageFunctionGeogebra = () => {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
if (
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
else {
|
|
76
|
-
yValue = randint(-6, 7, [0]);
|
|
77
|
-
const constante = randint(-6, 7, [yValue]);
|
|
78
|
-
points.push([0, constante], [1, constante]);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
else {
|
|
82
|
-
if (hasAntecedent) {
|
|
83
|
-
yValue = randint(-6, 7);
|
|
84
|
-
const xIsDecimal = coinFlip();
|
|
85
|
-
const xValue = xIsDecimal
|
|
86
|
-
? randfloat(-6, 7, 2, [yValue])
|
|
87
|
-
: randint(-6, 7, [yValue]);
|
|
88
|
-
const hasTwoAntecedents = probaFlip(0.8);
|
|
89
|
-
if (hasTwoAntecedents) {
|
|
90
|
-
const wrongY = randint(-6, 7, [yValue]);
|
|
91
|
-
const secondAntecedentPoint = [
|
|
92
|
-
randint(-6, 7, [xValue, yValue]),
|
|
93
|
-
yValue,
|
|
94
|
-
];
|
|
95
|
-
points.push([xValue, yValue], [yValue, wrongY], secondAntecedentPoint);
|
|
59
|
+
function generateIdentifiers() {
|
|
60
|
+
const isLine = coinFlip();
|
|
61
|
+
const hasAntecedent = probaFlip(0.8);
|
|
62
|
+
// const isLine = false;
|
|
63
|
+
// const hasAntecedent = true;
|
|
64
|
+
let yValue;
|
|
65
|
+
const points = [];
|
|
66
|
+
if (isLine) {
|
|
67
|
+
if (hasAntecedent) {
|
|
68
|
+
yValue = randint(-6, 7);
|
|
69
|
+
const xIsDecimal = probaFlip(0.3);
|
|
70
|
+
const xValue = xIsDecimal
|
|
71
|
+
? randfloat(-6, 7, 2, [yValue])
|
|
72
|
+
: randint(-6, 7, [yValue]);
|
|
73
|
+
const wrongY = randint(-6, 7);
|
|
74
|
+
points.push([xValue, yValue], [yValue, wrongY]);
|
|
96
75
|
}
|
|
97
76
|
else {
|
|
98
|
-
|
|
99
|
-
const
|
|
100
|
-
points.push([
|
|
77
|
+
yValue = randint(-6, 7, [0]);
|
|
78
|
+
const constante = randint(-6, 7, [yValue]);
|
|
79
|
+
points.push([0, constante], [1, constante]);
|
|
101
80
|
}
|
|
102
81
|
}
|
|
103
82
|
else {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
83
|
+
if (hasAntecedent) {
|
|
84
|
+
yValue = randint(-6, 7);
|
|
85
|
+
const xIsDecimal = coinFlip();
|
|
86
|
+
const xValue = xIsDecimal
|
|
87
|
+
? randfloat(-6, 7, 2, [yValue])
|
|
88
|
+
: randint(-6, 7, [yValue]);
|
|
89
|
+
const hasTwoAntecedents = probaFlip(0.8);
|
|
90
|
+
if (hasTwoAntecedents) {
|
|
91
|
+
const wrongY = randint(-6, 7, [yValue]);
|
|
92
|
+
const secondAntecedentPoint = [
|
|
93
|
+
randint(-6, 7, [xValue, yValue]),
|
|
94
|
+
yValue,
|
|
95
|
+
];
|
|
96
|
+
points.push([xValue, yValue], [yValue, wrongY], secondAntecedentPoint);
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
//(x,y) is summit
|
|
100
|
+
const wrongY = randint(-6, 7, [yValue]);
|
|
101
|
+
points.push([xValue, yValue], [yValue, wrongY], [2 * xValue - yValue, wrongY]);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
yValue = randint(-8, 9);
|
|
106
|
+
const wrongY = randint(-3, 4, [yValue, yValue - 1, yValue + 1]);
|
|
107
|
+
const below = wrongY < yValue;
|
|
108
|
+
const summit = [
|
|
109
|
+
randint(-6, 7, [yValue]),
|
|
110
|
+
below
|
|
111
|
+
? randint(wrongY + 1, yValue, [wrongY])
|
|
112
|
+
: randint(yValue + 1, wrongY, [wrongY]),
|
|
113
|
+
];
|
|
114
|
+
const thirdPoint = [2 * summit[0] - yValue, wrongY];
|
|
115
|
+
//construire deux autrs points au pif avec y sous/audssu yValus
|
|
116
|
+
points.push([yValue, wrongY], summit, thirdPoint);
|
|
117
|
+
}
|
|
116
118
|
}
|
|
119
|
+
points.sort((p1, p2) => p1[0] - p2[0]);
|
|
120
|
+
const identifiers = {
|
|
121
|
+
// xValue,
|
|
122
|
+
// affineCoeffs: isAffine ? affine!.coefficients : undefined,
|
|
123
|
+
// trinomCoeffs: isAffine ? undefined : trinom!.coefficients,
|
|
124
|
+
yValue,
|
|
125
|
+
points,
|
|
126
|
+
// isAffine,
|
|
127
|
+
};
|
|
128
|
+
return identifiers;
|
|
117
129
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
};
|
|
130
|
+
function isInfinityOfSolutions(identifiers) {
|
|
131
|
+
const { yValue, points } = identifiers;
|
|
132
|
+
return points.every((point) => point[1] === yValue);
|
|
133
|
+
}
|
|
134
|
+
let identifiers;
|
|
135
|
+
do {
|
|
136
|
+
identifiers = generateIdentifiers();
|
|
137
|
+
} while (isInfinityOfSolutions(identifiers));
|
|
127
138
|
return getQuestionFromIdentifiers(identifiers);
|
|
128
139
|
};
|
|
129
140
|
const getHint = (identifiers) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rootsFromDevForm.d.ts","sourceRoot":"","sources":["../../../../../../src/exercises/math/functions/trinoms/roots/rootsFromDevForm.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAYT,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"rootsFromDevForm.d.ts","sourceRoot":"","sources":["../../../../../../src/exercises/math/functions/trinoms/roots/rootsFromDevForm.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAYT,MAAM,6BAA6B,CAAC;AAYrC,KAAK,WAAW,GAAG;IACjB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX,CAAC;AA4GF,eAAO,MAAM,gBAAgB,EAAE,QAAQ,CAAC,WAAW,CAalD,CAAC"}
|
|
@@ -2,9 +2,11 @@ import { addValidProp, propWhile, tryToAddWrongProp, } from "../../../../../exer
|
|
|
2
2
|
import { getDistinctQuestions } from "../../../../../exercises/utils/getDistinctQuestions.js";
|
|
3
3
|
import { Trinom, TrinomConstructor } from "../../../../../math/polynomials/trinom.js";
|
|
4
4
|
import { randint } from "../../../../../math/utils/random/randint.js";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
5
|
+
import { multiply } from "../../../../../tree/nodes/operators/multiplyNode.js";
|
|
6
|
+
import { substract } from "../../../../../tree/nodes/operators/substractNode.js";
|
|
7
|
+
import { discreteSetParser } from "../../../../../tree/parsers/discreteSetParser.js";
|
|
7
8
|
import { shuffle } from "../../../../../utils/alea/shuffle.js";
|
|
9
|
+
import { handleVEAError } from "../../../../../utils/errors/handleVEAError.js";
|
|
8
10
|
const getInstruction = (identifiers) => {
|
|
9
11
|
const { a, b, c } = identifiers;
|
|
10
12
|
const trinom = new Trinom(a, b, c);
|
|
@@ -49,20 +51,43 @@ const getPropositions = (n, { answer }) => {
|
|
|
49
51
|
return shuffle(propositions);
|
|
50
52
|
};
|
|
51
53
|
const isAnswerValid = (ans, { a, b, c }) => {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
54
|
+
try {
|
|
55
|
+
const parsed = discreteSetParser(ans);
|
|
56
|
+
if (!parsed)
|
|
57
|
+
return false;
|
|
58
|
+
const trinom = new Trinom(a, b, c);
|
|
59
|
+
const roots = trinom.getRootsNode();
|
|
60
|
+
return isArrayOfNodesValid(parsed.elements, roots);
|
|
61
|
+
}
|
|
62
|
+
catch (err) {
|
|
63
|
+
return handleVEAError(err);
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
const isArrayOfNodesValid = (arrAns, arrAnswer) => {
|
|
67
|
+
//tried with toAllValidTexs() but there is always an unhandled case
|
|
68
|
+
function isNodesEqual(node1, node2) {
|
|
69
|
+
return [1, 1_000, 1_000_000].every((factor) => substract(multiply(factor, node1), multiply(factor, node2)).evaluate() === 0);
|
|
70
|
+
}
|
|
71
|
+
const dictAnswer = Object.fromEntries(arrAnswer.map((node, i) => [i, node]));
|
|
72
|
+
let isValid = true;
|
|
73
|
+
for (let i = 0; i < arrAns.length; i++) {
|
|
74
|
+
const nodeAns = arrAns[i];
|
|
75
|
+
let isFound = false;
|
|
76
|
+
const keys = Object.keys(dictAnswer);
|
|
77
|
+
for (let j = 0; j < keys.length; j++) {
|
|
78
|
+
const key = keys[j];
|
|
79
|
+
const answerNode = dictAnswer[key];
|
|
80
|
+
if (isNodesEqual(nodeAns, answerNode)) {
|
|
81
|
+
isFound = true;
|
|
82
|
+
delete dictAnswer[key]; //one-to-one correspondence
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
isValid = isValid && isFound;
|
|
87
|
+
if (!isValid)
|
|
88
|
+
break;
|
|
89
|
+
}
|
|
90
|
+
return isValid;
|
|
66
91
|
};
|
|
67
92
|
export const rootsFromDevForm = {
|
|
68
93
|
id: "rootsFromDevForm",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rootsReading.d.ts","sourceRoot":"","sources":["../../../../../../src/exercises/math/functions/trinoms/roots/rootsReading.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAcT,MAAM,6BAA6B,CAAC;AAUrC,KAAK,WAAW,GAAG;IACjB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX,CAAC;
|
|
1
|
+
{"version":3,"file":"rootsReading.d.ts","sourceRoot":"","sources":["../../../../../../src/exercises/math/functions/trinoms/roots/rootsReading.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAcT,MAAM,6BAA6B,CAAC;AAUrC,KAAK,WAAW,GAAG;IACjB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX,CAAC;AAoGF,eAAO,MAAM,YAAY,EAAE,QAAQ,CAAC,WAAW,CAY9C,CAAC"}
|
|
@@ -80,8 +80,9 @@ const isAnswerValid = (ans, { a, b, c }) => {
|
|
|
80
80
|
return ans === "\\text{Aucun}";
|
|
81
81
|
}
|
|
82
82
|
const studentNumbers = ans
|
|
83
|
-
.replaceAll("\\text{
|
|
84
|
-
.
|
|
83
|
+
.replaceAll("\\text{", "")
|
|
84
|
+
.replaceAll("}", "") //as long as there's no \\frac{}{} involved, it's ok
|
|
85
|
+
.split("et")
|
|
85
86
|
.map((n) => Number(n.replace(",", ".")))
|
|
86
87
|
.filter((n) => !isNaN(n))
|
|
87
88
|
.sort((a, b) => a - b);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"trinomSignFromFacto.d.ts","sourceRoot":"","sources":["../../../../../../src/exercises/math/functions/trinoms/sign/trinomSignFromFacto.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAgBT,MAAM,6BAA6B,CAAC;AAkBrC,KAAK,WAAW,GAAG;IACjB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,gBAAgB,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"trinomSignFromFacto.d.ts","sourceRoot":"","sources":["../../../../../../src/exercises/math/functions/trinoms/sign/trinomSignFromFacto.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAgBT,MAAM,6BAA6B,CAAC;AAkBrC,KAAK,WAAW,GAAG;IACjB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,QAAQ,EAAE,OAAO,CAAC;CACnB,CAAC;AAgJF,eAAO,MAAM,mBAAmB,EAAE,QAAQ,CAAC,WAAW,CAqBrD,CAAC"}
|
|
@@ -8,11 +8,12 @@ import { UnionIntervalNode } from "../../../../../tree/nodes/sets/unionIntervalN
|
|
|
8
8
|
import { coinFlip } from "../../../../../utils/alea/coinFlip.js";
|
|
9
9
|
import { unionIntervalParser } from "../../../../../tree/parsers/unionIntervalParser.js";
|
|
10
10
|
import { handleVEAError } from "../../../../../utils/errors/handleVEAError.js";
|
|
11
|
-
const getPropositions = (n, { answer, trinomCoeffs, isAskingPositive }) => {
|
|
11
|
+
const getPropositions = (n, { answer, trinomCoeffs, isAskingPositive, isStrict }) => {
|
|
12
12
|
const propositions = [];
|
|
13
13
|
addValidProp(propositions, answer);
|
|
14
14
|
const trinom = TrinomNodeConstructor.fromCoeffs(trinomCoeffs);
|
|
15
|
-
tryToAddWrongProp(propositions, getAnswer({ trinomCoeffs, isAskingPositive: !isAskingPositive }));
|
|
15
|
+
tryToAddWrongProp(propositions, getAnswer({ trinomCoeffs, isAskingPositive: !isAskingPositive, isStrict }));
|
|
16
|
+
tryToAddWrongProp(propositions, getAnswer({ trinomCoeffs, isAskingPositive, isStrict: !isStrict }));
|
|
16
17
|
tryToAddWrongProp(propositions, new IntervalNode(trinom.a, trinom.b, ClosureType.FF).toTex());
|
|
17
18
|
propWhile(propositions, n, () => {
|
|
18
19
|
const interval = IntervalNodeConstructor.random();
|
|
@@ -21,36 +22,41 @@ const getPropositions = (n, { answer, trinomCoeffs, isAskingPositive }) => {
|
|
|
21
22
|
return shuffleProps(propositions, n);
|
|
22
23
|
};
|
|
23
24
|
const getAnswerNode = (identifiers) => {
|
|
24
|
-
const
|
|
25
|
+
const { trinomCoeffs, isAskingPositive, isStrict } = identifiers;
|
|
26
|
+
const trinom = TrinomNodeConstructor.fromCoeffs(trinomCoeffs);
|
|
25
27
|
const roots = trinom.getRoots();
|
|
26
|
-
const a =
|
|
27
|
-
return a > 0 ===
|
|
28
|
+
const a = trinomCoeffs[2];
|
|
29
|
+
return a > 0 === isAskingPositive
|
|
28
30
|
? new UnionIntervalNode([
|
|
29
|
-
new IntervalNode(MinusInfinityNode, roots[0], ClosureType.OF),
|
|
30
|
-
new IntervalNode(roots[1], PlusInfinityNode, ClosureType.FO),
|
|
31
|
+
new IntervalNode(MinusInfinityNode, roots[0], isStrict ? ClosureType.OO : ClosureType.OF),
|
|
32
|
+
new IntervalNode(roots[1], PlusInfinityNode, isStrict ? ClosureType.OO : ClosureType.FO),
|
|
31
33
|
])
|
|
32
|
-
: new IntervalNode(roots[0], roots[1], ClosureType.FF);
|
|
34
|
+
: new IntervalNode(roots[0], roots[1], isStrict ? ClosureType.OO : ClosureType.FF);
|
|
33
35
|
};
|
|
34
36
|
const getAnswer = (identifiers) => {
|
|
35
37
|
return getAnswerNode(identifiers).toTex();
|
|
36
38
|
};
|
|
37
39
|
const getInstruction = (identifiers) => {
|
|
38
|
-
const
|
|
40
|
+
const { trinomCoeffs, isAskingPositive, isStrict } = identifiers;
|
|
41
|
+
const trinom = TrinomNodeConstructor.fromCoeffs(trinomCoeffs);
|
|
39
42
|
return `Soit $f$ une fonction polynôme de degré $2$ définie sur $\\mathbb{R}$ par :
|
|
40
43
|
|
|
41
44
|
$$
|
|
42
45
|
f(x) = ${trinom.toFactorized().toTex()}
|
|
43
46
|
$$
|
|
44
47
|
|
|
45
|
-
Sur quel(s) intervalle(s) les valeurs de la fonction $f$ sont-elles
|
|
48
|
+
Sur quel(s) intervalle(s) les valeurs de la fonction $f$ sont-elles
|
|
49
|
+
${isStrict ? "strictement" : ""} ${isAskingPositive ? "positives" : "négatives"}
|
|
50
|
+
?`;
|
|
46
51
|
};
|
|
47
52
|
const getHint = () => {
|
|
48
53
|
return `Une fonction polynôme de degré $2$ est du signe de son coefficient $a$, sauf entre ses racines.`;
|
|
49
54
|
};
|
|
50
55
|
const getCorrection = (identifiers) => {
|
|
51
|
-
const
|
|
56
|
+
const { trinomCoeffs, isAskingPositive, isStrict } = identifiers;
|
|
57
|
+
const trinom = TrinomNodeConstructor.fromCoeffs(trinomCoeffs);
|
|
52
58
|
const roots = trinom.getRoots();
|
|
53
|
-
const a =
|
|
59
|
+
const a = trinomCoeffs[2];
|
|
54
60
|
const answer = getAnswer(identifiers);
|
|
55
61
|
const ineqSign = a > 0 ? ">" : "<";
|
|
56
62
|
const sign = a > 0 ? "positive" : "négative";
|
|
@@ -60,7 +66,7 @@ Ici, $a = ${a}${ineqSign}0$, et les racines de $f$ sont $${roots[0].toTex()}$ et
|
|
|
60
66
|
|
|
61
67
|
$f$ est donc ${sign} sauf sur l'intervalle $${new IntervalNode(roots[0], roots[1], ClosureType.FF).toTex()}$.
|
|
62
68
|
|
|
63
|
-
On en déduit que $f$ est ${
|
|
69
|
+
On en déduit que $f$ est ${isStrict ? "strictement" : ""} ${isAskingPositive ? "positive" : "négative"} sur :
|
|
64
70
|
|
|
65
71
|
$$
|
|
66
72
|
${answer}
|
|
@@ -83,8 +89,10 @@ const isAnswerValid = (ans, { answer }) => {
|
|
|
83
89
|
const getTrinomSignFromFactoQuestion = () => {
|
|
84
90
|
const trinom = TrinomNodeConstructor.randomNiceRoots(2);
|
|
85
91
|
const isAskingPositive = coinFlip();
|
|
92
|
+
const isStrict = coinFlip();
|
|
86
93
|
const identifiers = {
|
|
87
94
|
isAskingPositive,
|
|
95
|
+
isStrict,
|
|
88
96
|
trinomCoeffs: trinom.getCoeffs(),
|
|
89
97
|
};
|
|
90
98
|
return getQuestionFromIdentifiers(identifiers);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"circleCircumference.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/geometry/perimeters/circleCircumference.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAcT,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"circleCircumference.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/geometry/perimeters/circleCircumference.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAcT,MAAM,6BAA6B,CAAC;AAQrC,KAAK,WAAW,GAAG;IACjB,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AA2GF,eAAO,MAAM,mBAAmB,EAAE,QAAQ,CAAC,WAAW,CAcrD,CAAC"}
|