math-exercises 3.0.199 → 3.0.200
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/exercise.d.ts +14 -1
- package/lib/exercises/exercise.d.ts.map +1 -1
- package/lib/exercises/math/_debug/debugReorder1.d.ts +8 -0
- package/lib/exercises/math/_debug/debugReorder1.d.ts.map +1 -0
- package/lib/exercises/math/_debug/debugReorder1.js +81 -0
- package/lib/exercises/math/_debug/debugReorder2.d.ts +10 -0
- package/lib/exercises/math/_debug/debugReorder2.d.ts.map +1 -0
- package/lib/exercises/math/_debug/debugReorder2.js +88 -0
- package/lib/exercises/math/_debug/debugReorder3.d.ts +10 -0
- package/lib/exercises/math/_debug/debugReorder3.d.ts.map +1 -0
- package/lib/exercises/math/_debug/debugReorder3.js +81 -0
- package/lib/exercises/math/_debug/index.d.ts +3 -1
- package/lib/exercises/math/_debug/index.d.ts.map +1 -1
- package/lib/exercises/math/_debug/index.js +3 -1
- package/lib/exercises/math/calcul/factorial/index.d.ts +2 -0
- package/lib/exercises/math/calcul/factorial/index.d.ts.map +1 -0
- package/lib/exercises/math/calcul/factorial/index.js +1 -0
- package/lib/exercises/math/calcul/factorial/simplifyQuotientOfFactorialToProduct.d.ts +8 -0
- package/lib/exercises/math/calcul/factorial/simplifyQuotientOfFactorialToProduct.d.ts.map +1 -0
- package/lib/exercises/math/calcul/factorial/simplifyQuotientOfFactorialToProduct.js +199 -0
- package/lib/exercises/math/combinatory/combination/index.d.ts +3 -0
- package/lib/exercises/math/combinatory/combination/index.d.ts.map +1 -0
- package/lib/exercises/math/combinatory/combination/index.js +2 -0
- package/lib/exercises/math/combinatory/combination/mentalCalculateCombination.d.ts +11 -0
- package/lib/exercises/math/combinatory/combination/mentalCalculateCombination.d.ts.map +1 -0
- package/lib/exercises/math/combinatory/combination/mentalCalculateCombination.js +225 -0
- package/lib/exercises/math/combinatory/combination/writeCombinationFormulaUsingFactorial.d.ts +13 -0
- package/lib/exercises/math/combinatory/combination/writeCombinationFormulaUsingFactorial.d.ts.map +1 -0
- package/lib/exercises/math/combinatory/combination/writeCombinationFormulaUsingFactorial.js +285 -0
- package/lib/exercises/math/dataRepresentations/scatterPlot/scatterPlotInterpreting.d.ts.map +1 -1
- package/lib/exercises/math/dataRepresentations/scatterPlot/scatterPlotInterpreting.js +1 -1
- package/lib/exercises/math/derivation/derivative/trigo/productOfSinAXPlusBCosCXPlusDDerivative.d.ts +9 -0
- package/lib/exercises/math/derivation/derivative/trigo/productOfSinAXPlusBCosCXPlusDDerivative.d.ts.map +1 -0
- package/lib/exercises/math/derivation/derivative/trigo/productOfSinAXPlusBCosCXPlusDDerivative.js +209 -0
- package/lib/exercises/math/derivation/derivative/trigo/sinAndCosMixedWithSquareDerivative.d.ts +9 -0
- package/lib/exercises/math/derivation/derivative/trigo/sinAndCosMixedWithSquareDerivative.d.ts.map +1 -0
- package/lib/exercises/math/derivation/derivative/trigo/sinAndCosMixedWithSquareDerivative.js +359 -0
- package/lib/exercises/math/derivation/derivative/trigo/sinCosDerivativeRewriteUsingCos2PlusSin2Equals1.d.ts +11 -0
- package/lib/exercises/math/derivation/derivative/trigo/sinCosDerivativeRewriteUsingCos2PlusSin2Equals1.d.ts.map +1 -0
- package/lib/exercises/math/derivation/derivative/trigo/sinCosDerivativeRewriteUsingCos2PlusSin2Equals1.js +445 -0
- package/lib/exercises/math/functions/affines/affineVarTableOnBoundedInterval.d.ts.map +1 -1
- package/lib/exercises/math/functions/affines/affineVarTableOnBoundedInterval.js +2 -3
- package/lib/exercises/math/index.d.ts +1 -0
- package/lib/exercises/math/index.d.ts.map +1 -1
- package/lib/exercises/math/index.js +1 -1
- package/lib/exercises/math/limits/sequenceGeometricLimit.d.ts.map +1 -1
- package/lib/exercises/math/limits/sequenceGeometricLimit.js +9 -0
- package/lib/exercises/math/primitive/constantPrimitive.d.ts +8 -5
- package/lib/exercises/math/primitive/constantPrimitive.d.ts.map +1 -1
- package/lib/exercises/math/primitive/constantPrimitive.js +40 -21
- package/lib/exercises/math/probaStat/stats2var/averagePoint.d.ts.map +1 -1
- package/lib/exercises/math/probaStat/stats2var/averagePoint.js +34 -2
- package/lib/exercises/math/sequences/geometric/graph/geometricFindThresholdFromGraph.d.ts +15 -0
- package/lib/exercises/math/sequences/geometric/graph/geometricFindThresholdFromGraph.d.ts.map +1 -0
- package/lib/exercises/math/sequences/geometric/graph/geometricFindThresholdFromGraph.js +255 -0
- package/lib/exercises/math/sequences/geometric/graph/geometricFindThresholdUsingCalculator.d.ts +15 -0
- package/lib/exercises/math/sequences/geometric/graph/geometricFindThresholdUsingCalculator.d.ts.map +1 -0
- package/lib/exercises/math/sequences/geometric/graph/geometricFindThresholdUsingCalculator.js +242 -0
- package/lib/exercises/math/sequences/geometric/graph/geometricPlaceFirstPoints.js +4 -4
- package/lib/exercises/math/sequences/geometric/graph/geometricSignOfReasonFromGraph.d.ts +12 -0
- package/lib/exercises/math/sequences/geometric/graph/geometricSignOfReasonFromGraph.d.ts.map +1 -0
- package/lib/exercises/math/sequences/geometric/graph/geometricSignOfReasonFromGraph.js +161 -0
- package/lib/exercises/math/sets/cartesianProduct/findCardinalOfCartesianProductOfFiniteSets.d.ts +10 -0
- package/lib/exercises/math/sets/cartesianProduct/findCardinalOfCartesianProductOfFiniteSets.d.ts.map +1 -0
- package/lib/exercises/math/sets/cartesianProduct/findCardinalOfCartesianProductOfFiniteSets.js +224 -0
- package/lib/exercises/math/sets/cartesianProduct/findCardinalOfCartesianProductOfFiniteSetsFromSituation.d.ts +18 -0
- package/lib/exercises/math/sets/cartesianProduct/findCardinalOfCartesianProductOfFiniteSetsFromSituation.d.ts.map +1 -0
- package/lib/exercises/math/sets/cartesianProduct/findCardinalOfCartesianProductOfFiniteSetsFromSituation.js +198 -0
- package/lib/exercises/math/sets/cartesianProduct/findCardinalOfPowEK.d.ts +10 -0
- package/lib/exercises/math/sets/cartesianProduct/findCardinalOfPowEK.d.ts.map +1 -0
- package/lib/exercises/math/sets/cartesianProduct/findCardinalOfPowEK.js +231 -0
- package/lib/exercises/math/sets/cartesianProduct/findNumberOfPasswordsWithLettersAndNumbers.d.ts +19 -0
- package/lib/exercises/math/sets/cartesianProduct/findNumberOfPasswordsWithLettersAndNumbers.d.ts.map +1 -0
- package/lib/exercises/math/sets/cartesianProduct/findNumberOfPasswordsWithLettersAndNumbers.js +187 -0
- package/lib/exercises/math/sets/cartesianProduct/index.d.ts +7 -0
- package/lib/exercises/math/sets/cartesianProduct/index.d.ts.map +1 -0
- package/lib/exercises/math/sets/cartesianProduct/index.js +6 -0
- package/lib/exercises/math/sets/cartesianProduct/proposeElementInCartesianProductOfFiniteSets.d.ts +15 -0
- package/lib/exercises/math/sets/cartesianProduct/proposeElementInCartesianProductOfFiniteSets.d.ts.map +1 -0
- package/lib/exercises/math/sets/cartesianProduct/proposeElementInCartesianProductOfFiniteSets.js +291 -0
- package/lib/exercises/math/sets/cartesianProduct/proposeElementInPowEK.d.ts +15 -0
- package/lib/exercises/math/sets/cartesianProduct/proposeElementInPowEK.d.ts.map +1 -0
- package/lib/exercises/math/sets/cartesianProduct/proposeElementInPowEK.js +274 -0
- package/lib/exercises/math/sets/combinations/findNumberOfCombinationsFromSituation.d.ts +17 -0
- package/lib/exercises/math/sets/combinations/findNumberOfCombinationsFromSituation.d.ts.map +1 -0
- package/lib/exercises/math/sets/combinations/findNumberOfCombinationsFromSituation.js +228 -0
- package/lib/exercises/math/sets/combinations/findNumberOfProductsOfCombinationsFromSituation.d.ts +17 -0
- package/lib/exercises/math/sets/combinations/findNumberOfProductsOfCombinationsFromSituation.d.ts.map +1 -0
- package/lib/exercises/math/sets/combinations/findNumberOfProductsOfCombinationsFromSituation.js +388 -0
- package/lib/exercises/math/sets/combinations/index.d.ts +4 -0
- package/lib/exercises/math/sets/combinations/index.d.ts.map +1 -0
- package/lib/exercises/math/sets/combinations/index.js +3 -0
- package/lib/exercises/math/sets/combinations/proposeCombination.d.ts +15 -0
- package/lib/exercises/math/sets/combinations/proposeCombination.d.ts.map +1 -0
- package/lib/exercises/math/sets/combinations/proposeCombination.js +347 -0
- package/lib/exercises/math/sets/partialPermutations/findNumberOfPartialPermutationsFromSituation.d.ts +16 -0
- package/lib/exercises/math/sets/partialPermutations/findNumberOfPartialPermutationsFromSituation.d.ts.map +1 -0
- package/lib/exercises/math/sets/partialPermutations/findNumberOfPartialPermutationsFromSituation.js +186 -0
- package/lib/exercises/math/sets/partialPermutations/findNumberOfPermutationsFromSituation.d.ts +17 -0
- package/lib/exercises/math/sets/partialPermutations/findNumberOfPermutationsFromSituation.d.ts.map +1 -0
- package/lib/exercises/math/sets/partialPermutations/findNumberOfPermutationsFromSituation.js +232 -0
- package/lib/exercises/math/sets/partialPermutations/index.d.ts +4 -0
- package/lib/exercises/math/sets/partialPermutations/index.d.ts.map +1 -0
- package/lib/exercises/math/sets/partialPermutations/index.js +3 -0
- package/lib/exercises/math/sets/partialPermutations/proposePartialPermutation.d.ts +15 -0
- package/lib/exercises/math/sets/partialPermutations/proposePartialPermutation.d.ts.map +1 -0
- package/lib/exercises/math/sets/partialPermutations/proposePartialPermutation.js +343 -0
- package/lib/exercises/math/trigonometry/functions/parityOfCosAXTimesSinBX.d.ts +8 -0
- package/lib/exercises/math/trigonometry/functions/parityOfCosAXTimesSinBX.d.ts.map +1 -0
- package/lib/exercises/math/trigonometry/functions/parityOfCosAXTimesSinBX.js +193 -0
- package/lib/index.d.ts +15 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/math/sets/setOperations.d.ts +9 -0
- package/lib/math/sets/setOperations.d.ts.map +1 -0
- package/lib/math/sets/setOperations.js +84 -0
- package/lib/math/sets/tuple.d.ts +12 -0
- package/lib/math/sets/tuple.d.ts.map +1 -0
- package/lib/math/sets/tuple.js +17 -0
- package/lib/server.js +25 -0
- package/lib/tree/utilities/nodePrinter.d.ts +7 -0
- package/lib/tree/utilities/nodePrinter.d.ts.map +1 -0
- package/lib/tree/utilities/nodePrinter.js +36 -0
- package/package.json +1 -1
|
@@ -3,7 +3,10 @@ import { getDistinctQuestions } from "../../../../exercises/utils/getDistinctQue
|
|
|
3
3
|
import { frenchify } from "../../../../math/utils/latex/frenchify.js";
|
|
4
4
|
import { distinctRandTupleInt } from "../../../../math/utils/random/randTupleInt.js";
|
|
5
5
|
import { randint } from "../../../../math/utils/random/randint.js";
|
|
6
|
+
import { AddNode } from "../../../../tree/nodes/operators/addNode.js";
|
|
7
|
+
import { frac } from "../../../../tree/nodes/operators/fractionNode.js";
|
|
6
8
|
import { pointParser } from "../../../../tree/parsers/pointParser.js";
|
|
9
|
+
import { operatorComposition } from "../../../../tree/utilities/operatorComposition.js";
|
|
7
10
|
import { average } from "../../../../utils/average.js";
|
|
8
11
|
import { handleVEAError } from "../../../../utils/errors/handleVEAError.js";
|
|
9
12
|
import { dollarize } from "../../../../utils/latex/dollarize.js";
|
|
@@ -13,9 +16,9 @@ const getInstruction = ({ xValues, yValues }) => {
|
|
|
13
16
|
["$x$", ...xValues.map((el) => dollarize(el))],
|
|
14
17
|
["$y$", ...yValues.map((el) => dollarize(el))],
|
|
15
18
|
]);
|
|
16
|
-
return `On considère la liste de points suivante : ${tab}
|
|
19
|
+
return `On considère la liste de points de coordonnées $(x;y)$ suivante : ${tab}
|
|
17
20
|
|
|
18
|
-
Déterminer les coordonnées du point moyen $G
|
|
21
|
+
Déterminer les coordonnées du point moyen $G$ de ce nuage de points.
|
|
19
22
|
`;
|
|
20
23
|
};
|
|
21
24
|
const getAnswer = (identifiers) => {
|
|
@@ -25,6 +28,32 @@ const getAnswer = (identifiers) => {
|
|
|
25
28
|
const answer = `\\left(${xG};${yG}\\right)`;
|
|
26
29
|
return answer;
|
|
27
30
|
};
|
|
31
|
+
const getHint = () => {
|
|
32
|
+
return `Le point moyen $G$ d'un nuage de points est le point de coordonnées $(x;y)$ où $x$ est la moyenne des abscisses des points du nuage, et $y$ est la moyenne des ordonnées des points du nuage. `;
|
|
33
|
+
};
|
|
34
|
+
const getCorrection = (identifiers) => {
|
|
35
|
+
const { xValues, yValues } = identifiers;
|
|
36
|
+
const n = xValues.length;
|
|
37
|
+
const xG = frenchify(average(xValues) + "");
|
|
38
|
+
const yG = frenchify(average(yValues) + "");
|
|
39
|
+
return `On calcule la moyenne des abscisses :
|
|
40
|
+
|
|
41
|
+
$$
|
|
42
|
+
${frac(operatorComposition(AddNode, xValues.map((x) => x.toTree())), n).toTex()} = ${xG}
|
|
43
|
+
$$
|
|
44
|
+
|
|
45
|
+
Puis on calcule la moyenne des ordonnées :
|
|
46
|
+
|
|
47
|
+
$$
|
|
48
|
+
${frac(operatorComposition(AddNode, yValues.map((x) => x.toTree())), n).toTex()} = ${yG}
|
|
49
|
+
$$
|
|
50
|
+
|
|
51
|
+
Le point moyen $G$ de ce nuage de points a donc pour coordonnées :
|
|
52
|
+
|
|
53
|
+
$$
|
|
54
|
+
${getAnswer(identifiers)}
|
|
55
|
+
$$`;
|
|
56
|
+
};
|
|
28
57
|
const getAveragePointQuestion = () => {
|
|
29
58
|
const points = distinctRandTupleInt(4, 2, { from: -9, to: 10 });
|
|
30
59
|
const sortedPoints = points.sort((a, b) => a[0] - b[0]);
|
|
@@ -48,6 +77,8 @@ const getQuestionFromIdentifiers = (identifiers) => {
|
|
|
48
77
|
firstRowIsHeader: false,
|
|
49
78
|
},
|
|
50
79
|
},
|
|
80
|
+
hint: getHint(identifiers),
|
|
81
|
+
correction: getCorrection(identifiers),
|
|
51
82
|
};
|
|
52
83
|
return question;
|
|
53
84
|
};
|
|
@@ -84,4 +115,5 @@ export const averagePoint = {
|
|
|
84
115
|
subject: "Mathématiques",
|
|
85
116
|
getInstruction,
|
|
86
117
|
getQuestionFromIdentifiers,
|
|
118
|
+
hasHintAndCorrection: true,
|
|
87
119
|
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Exercise } from "../../../../../exercises/exercise.js";
|
|
2
|
+
import { OptionFirstTermRankOne } from "../../../../../exercises/options/optionFirstTermRankOne.js";
|
|
3
|
+
import { InegalitySymbols } from "../../../../../math/inequations/inequation.js";
|
|
4
|
+
import { NodeIdentifiers } from "../../../../../tree/nodes/nodeConstructor.js";
|
|
5
|
+
type Identifiers = {
|
|
6
|
+
nodeIdsInitial: NodeIdentifiers;
|
|
7
|
+
nodeIdsReason: NodeIdentifiers;
|
|
8
|
+
firstRank: number;
|
|
9
|
+
nodeIdsValueThreshold: NodeIdentifiers;
|
|
10
|
+
inegSymbol: InegalitySymbols;
|
|
11
|
+
};
|
|
12
|
+
type Options = OptionFirstTermRankOne;
|
|
13
|
+
export declare const geometricFindThresholdFromGraph: Exercise<Identifiers, Options>;
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=geometricFindThresholdFromGraph.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"geometricFindThresholdFromGraph.d.ts","sourceRoot":"","sources":["../../../../../../src/exercises/math/sequences/geometric/graph/geometricFindThresholdFromGraph.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAgBT,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAEL,sBAAsB,EACvB,MAAM,mDAAmD,CAAC;AAO3D,OAAO,EACL,gBAAgB,EAEjB,MAAM,sCAAsC,CAAC;AAM9C,OAAO,EAEL,eAAe,EAChB,MAAM,qCAAqC,CAAC;AA6B7C,KAAK,WAAW,GAAG;IACjB,cAAc,EAAE,eAAe,CAAC;IAChC,aAAa,EAAE,eAAe,CAAC;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,qBAAqB,EAAE,eAAe,CAAC;IACvC,UAAU,EAAE,gBAAgB,CAAC;CAC9B,CAAC;AA+QF,KAAK,OAAO,GAAG,sBAAsB,CAAC;AAMtC,eAAO,MAAM,+BAA+B,EAAE,QAAQ,CAAC,WAAW,EAAE,OAAO,CAuB1E,CAAC"}
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
import { addValidProp, tryToAddWrongProp, shuffleProps, propWhile, } from "../../../../../exercises/exercise.js";
|
|
2
|
+
import { getOptionFirstTermRankOneStuff, } from "../../../../../exercises/options/optionFirstTermRankOne.js";
|
|
3
|
+
import { toolBarConstructor } from "../../../../../exercises/utils/geogebra/toolBarConstructor.js";
|
|
4
|
+
import { getDistinctQuestions } from "../../../../../exercises/utils/getDistinctQuestions.js";
|
|
5
|
+
import { numberVEA } from "../../../../../exercises/vea/numberVEA.js";
|
|
6
|
+
import { greenMain, orange } from "../../../../../geogebra/colors.js";
|
|
7
|
+
import { GeogebraConstructor } from "../../../../../geogebra/geogebraConstructor.js";
|
|
8
|
+
import { Point } from "../../../../../math/geometry/point.js";
|
|
9
|
+
import { InequationSymbol, } from "../../../../../math/inequations/inequation.js";
|
|
10
|
+
import { randfloat } from "../../../../../math/utils/random/randfloat.js";
|
|
11
|
+
import { randint } from "../../../../../math/utils/random/randint.js";
|
|
12
|
+
import { round } from "../../../../../math/utils/round.js";
|
|
13
|
+
import { InequationNode } from "../../../../../tree/nodes/inequations/inequationNode.js";
|
|
14
|
+
import { NodeConstructor, } from "../../../../../tree/nodes/nodeConstructor.js";
|
|
15
|
+
import { multiply } from "../../../../../tree/nodes/operators/multiplyNode.js";
|
|
16
|
+
import { power } from "../../../../../tree/nodes/operators/powerNode.js";
|
|
17
|
+
import { coinFlip } from "../../../../../utils/alea/coinFlip.js";
|
|
18
|
+
import { random } from "../../../../../utils/alea/random.js";
|
|
19
|
+
const getArrPoint = (nodeInitial, nodeReason, firstRank) => {
|
|
20
|
+
const arrNodeTerm = [...Array(nbPoints).keys()].map((i) => multiply(nodeInitial, power(nodeReason, i))
|
|
21
|
+
.simplify({
|
|
22
|
+
towardsDistribute: true,
|
|
23
|
+
calculatePowers: true,
|
|
24
|
+
distributePowersOnFrac: true,
|
|
25
|
+
})
|
|
26
|
+
.simplify({ towardsDistribute: false }));
|
|
27
|
+
const arrPoint = arrNodeTerm.map((nodeTerm, i) => {
|
|
28
|
+
const nodeX = (firstRank + i).toTree();
|
|
29
|
+
return new Point(`P${firstRank + i}`, nodeX, nodeTerm);
|
|
30
|
+
});
|
|
31
|
+
return arrPoint;
|
|
32
|
+
};
|
|
33
|
+
const nbPoints = 10;
|
|
34
|
+
const getInstruction = (identifiers) => {
|
|
35
|
+
const { nodeIdsValueThreshold, inegSymbol } = identifiers;
|
|
36
|
+
const nodeValueThreshold = NodeConstructor.fromIdentifiers(nodeIdsValueThreshold);
|
|
37
|
+
return `Dans le repère ci-dessous, on a placé les points représentant les $${nbPoints}$ premiers termes d'une suite géométrique $u$.
|
|
38
|
+
|
|
39
|
+
Quel est le rang $N$, tel que pour tout $n \\geq N$, on a :
|
|
40
|
+
|
|
41
|
+
$$
|
|
42
|
+
u_{n} ${inegSymbol} ${nodeValueThreshold.toTex()}
|
|
43
|
+
$$
|
|
44
|
+
|
|
45
|
+
`;
|
|
46
|
+
};
|
|
47
|
+
const getAnswerStuff = (identifiers) => {
|
|
48
|
+
const { nodeIdsInitial, nodeIdsReason, nodeIdsValueThreshold, firstRank, inegSymbol, } = identifiers;
|
|
49
|
+
const [nodeInitial, nodeReason, nodeValueThreshold] = [
|
|
50
|
+
nodeIdsInitial,
|
|
51
|
+
nodeIdsReason,
|
|
52
|
+
nodeIdsValueThreshold,
|
|
53
|
+
].map((nodeIds) => NodeConstructor.fromIdentifiers(nodeIds));
|
|
54
|
+
const arrPoint = getArrPoint(nodeInitial, nodeReason, firstRank);
|
|
55
|
+
const pointValid = arrPoint.find((point) => {
|
|
56
|
+
const inequationNode = new InequationNode([point.y, nodeValueThreshold], inegSymbol);
|
|
57
|
+
return inequationNode.isVerified();
|
|
58
|
+
});
|
|
59
|
+
return { pointValid };
|
|
60
|
+
};
|
|
61
|
+
const getAnswer = (identifiers) => {
|
|
62
|
+
return getAnswerStuff(identifiers).pointValid.x.toTex();
|
|
63
|
+
};
|
|
64
|
+
const getHint = (identifiers) => {
|
|
65
|
+
const { nodeIdsValueThreshold } = identifiers;
|
|
66
|
+
const nodeValueThreshold = NodeConstructor.fromIdentifiers(nodeIdsValueThreshold);
|
|
67
|
+
return `Dans le nuage de point qui représente la suite, l'abscisse de chaque point est le rang du terme, et l'ordonnée est le terme en lui-même.
|
|
68
|
+
Trace mentalement la droite d'équation $y=${nodeValueThreshold.toTex()}$ pour déterminer le rang demandé.`;
|
|
69
|
+
};
|
|
70
|
+
const getCorrection = (identifiers) => {
|
|
71
|
+
const { nodeIdsValueThreshold, inegSymbol } = identifiers;
|
|
72
|
+
const nodeValueThreshold = NodeConstructor.fromIdentifiers(nodeIdsValueThreshold);
|
|
73
|
+
const answer = getAnswer(identifiers);
|
|
74
|
+
return `Dans le nuage de point qui représente la suite, l'abscisse de chaque point est le rang du terme, et l'ordonnée est le terme en lui-même.
|
|
75
|
+
|
|
76
|
+
On cherche le rang du premier terme ${(() => {
|
|
77
|
+
switch (inegSymbol) {
|
|
78
|
+
case "\\ge":
|
|
79
|
+
return `au-dessus`;
|
|
80
|
+
case ">":
|
|
81
|
+
return `strictement au-dessus`;
|
|
82
|
+
case "\\le":
|
|
83
|
+
return `en dessous`;
|
|
84
|
+
case "<":
|
|
85
|
+
return `strictement en dessous`;
|
|
86
|
+
}
|
|
87
|
+
})()} de la droite d'équation $y=${nodeValueThreshold.toTex()}$.
|
|
88
|
+
|
|
89
|
+
Le rang recherché est $${answer}$.
|
|
90
|
+
|
|
91
|
+
`;
|
|
92
|
+
};
|
|
93
|
+
const getCorrectionGGBOptions = (identifiers) => {
|
|
94
|
+
const { nodeIdsInitial, nodeIdsReason, nodeIdsValueThreshold, firstRank } = identifiers;
|
|
95
|
+
const [nodeInitial, nodeReason, nodeValueThreshold] = [
|
|
96
|
+
nodeIdsInitial,
|
|
97
|
+
nodeIdsReason,
|
|
98
|
+
nodeIdsValueThreshold,
|
|
99
|
+
].map((nodeIds) => NodeConstructor.fromIdentifiers(nodeIds));
|
|
100
|
+
const arrPoint = getArrPoint(nodeInitial, nodeReason, firstRank);
|
|
101
|
+
const values = arrPoint.map((point) => point.y.evaluate());
|
|
102
|
+
const valueThreshold = nodeValueThreshold.evaluate();
|
|
103
|
+
const { pointValid } = getAnswerStuff(identifiers);
|
|
104
|
+
const ggb = new GeogebraConstructor({
|
|
105
|
+
commands: [
|
|
106
|
+
`l = Line((0,${valueThreshold}), (1, ${valueThreshold}))`,
|
|
107
|
+
`SetColor(l, "${orange}")`,
|
|
108
|
+
...arrPoint.flatMap((point) => point.toGGBCommand({ color: `#000000`, showLabel: false })),
|
|
109
|
+
`v2 = Vector(${pointValid.toMathString()},(${pointValid.x.toMathString()},0))`,
|
|
110
|
+
`SetColor(v2, "${greenMain}")`,
|
|
111
|
+
],
|
|
112
|
+
customToolBar: toolBarConstructor({
|
|
113
|
+
point: true,
|
|
114
|
+
}),
|
|
115
|
+
});
|
|
116
|
+
const yMin = Math.min(...values);
|
|
117
|
+
const yMax = Math.max(...values);
|
|
118
|
+
return ggb.getOptions({
|
|
119
|
+
coords: [-1, nbPoints, Math.min(yMin, 0) - 1, Math.max(yMax, 1) + 1],
|
|
120
|
+
});
|
|
121
|
+
};
|
|
122
|
+
const getGGBOptions = (identifiers) => {
|
|
123
|
+
const { nodeIdsInitial, nodeIdsReason, firstRank } = identifiers;
|
|
124
|
+
const [nodeInitial, nodeReason] = [nodeIdsInitial, nodeIdsReason].map((nodeIds) => NodeConstructor.fromIdentifiers(nodeIds));
|
|
125
|
+
const arrPoint = getArrPoint(nodeInitial, nodeReason, firstRank);
|
|
126
|
+
const values = arrPoint.map((point) => point.y.evaluate());
|
|
127
|
+
const ggb = new GeogebraConstructor({
|
|
128
|
+
commands: [
|
|
129
|
+
...arrPoint.flatMap((point) => point.toGGBCommand({ color: `#000000`, showLabel: false })),
|
|
130
|
+
],
|
|
131
|
+
customToolBar: toolBarConstructor({
|
|
132
|
+
point: true,
|
|
133
|
+
}),
|
|
134
|
+
});
|
|
135
|
+
const yMin = Math.min(...values);
|
|
136
|
+
const yMax = Math.max(...values);
|
|
137
|
+
return ggb.getOptions({
|
|
138
|
+
coords: [-1, nbPoints, Math.min(yMin, 0) - 1, Math.max(yMax, 1) + 1],
|
|
139
|
+
});
|
|
140
|
+
};
|
|
141
|
+
const getPropositions = (n, { answer }) => {
|
|
142
|
+
const propositions = [];
|
|
143
|
+
addValidProp(propositions, answer);
|
|
144
|
+
propWhile(propositions, n, () => {
|
|
145
|
+
const indexThreshold = randint(3, 10);
|
|
146
|
+
tryToAddWrongProp(propositions, indexThreshold.frenchify());
|
|
147
|
+
});
|
|
148
|
+
return shuffleProps(propositions, n);
|
|
149
|
+
};
|
|
150
|
+
const isAnswerValid = (ans, { answer }) => {
|
|
151
|
+
return numberVEA(ans, answer);
|
|
152
|
+
};
|
|
153
|
+
const getGeometricFindThresholdFromGraphQuestion = (optsIn) => {
|
|
154
|
+
const opts = optsIn ?? optsDefault;
|
|
155
|
+
const firstRank = opts?.firstTermRankOne ? 1 : 0;
|
|
156
|
+
const { isDivergent: _isDivergent, nodeInitialAbs, nodeReasonAbs, nodeValueThresholdAbs, inegSymbolAbs, } = (() => {
|
|
157
|
+
const isDivergent = coinFlip();
|
|
158
|
+
const { nodeInitialAbs, nodeReasonAbs } = (() => {
|
|
159
|
+
if (isDivergent) {
|
|
160
|
+
return {
|
|
161
|
+
nodeInitialAbs: randfloat(1.3, 2, 2).toTree(),
|
|
162
|
+
nodeReasonAbs: randfloat(1.15, 1.2, 3).toTree(),
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
return {
|
|
167
|
+
nodeInitialAbs: randfloat(7, 10, 2).toTree(),
|
|
168
|
+
nodeReasonAbs: randfloat(0.77, 0.85, 3).toTree(),
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
})();
|
|
172
|
+
const arrPointAbs = getArrPoint(nodeInitialAbs, nodeReasonAbs, firstRank);
|
|
173
|
+
const { nodeValueThresholdAbs, inegSymbolAbs } = (() => {
|
|
174
|
+
const isValueThresholdEqualToTerm = coinFlip();
|
|
175
|
+
const nodeValueThresholdAbs = (() => {
|
|
176
|
+
const indexThresholdLow = randint(3, 8);
|
|
177
|
+
const progress = randfloat(0.3, 0.7, 1);
|
|
178
|
+
const [v1, v2] = [indexThresholdLow, indexThresholdLow + 1].map((index) => arrPointAbs[index].y.evaluate());
|
|
179
|
+
return round(v1 + (v2 - v1) * progress, 2).toTree();
|
|
180
|
+
})();
|
|
181
|
+
const inegSymbolAbs = (() => {
|
|
182
|
+
if (isDivergent) {
|
|
183
|
+
return isValueThresholdEqualToTerm ? "\\ge" : random(["\\ge", ">"]);
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
return isValueThresholdEqualToTerm ? "\\le" : random(["\\le", "<"]);
|
|
187
|
+
}
|
|
188
|
+
})();
|
|
189
|
+
return { nodeValueThresholdAbs, inegSymbolAbs };
|
|
190
|
+
})();
|
|
191
|
+
return {
|
|
192
|
+
isDivergent,
|
|
193
|
+
nodeInitialAbs,
|
|
194
|
+
nodeReasonAbs,
|
|
195
|
+
nodeValueThresholdAbs,
|
|
196
|
+
inegSymbolAbs,
|
|
197
|
+
};
|
|
198
|
+
})();
|
|
199
|
+
const { nodeInitial, nodeReason, nodeValueThreshold, inegSymbol } = (() => {
|
|
200
|
+
const signInitial = coinFlip() ? +1 : -1;
|
|
201
|
+
const nodeInitial = multiply(signInitial, nodeInitialAbs).simplify({
|
|
202
|
+
towardsDistribute: true,
|
|
203
|
+
});
|
|
204
|
+
const nodeReason = nodeReasonAbs; //reason is always positive
|
|
205
|
+
const nodeValueThreshold = multiply(signInitial, nodeValueThresholdAbs).simplify({
|
|
206
|
+
towardsDistribute: true,
|
|
207
|
+
});
|
|
208
|
+
const inegSymbol = signInitial === +1
|
|
209
|
+
? inegSymbolAbs
|
|
210
|
+
: new InequationSymbol(inegSymbolAbs).reversed();
|
|
211
|
+
return { nodeInitial, nodeReason, nodeValueThreshold, inegSymbol };
|
|
212
|
+
})();
|
|
213
|
+
const identifiers = {
|
|
214
|
+
firstRank,
|
|
215
|
+
nodeIdsInitial: nodeInitial.toIdentifiers(),
|
|
216
|
+
nodeIdsReason: nodeReason.toIdentifiers(),
|
|
217
|
+
nodeIdsValueThreshold: nodeValueThreshold.toIdentifiers(),
|
|
218
|
+
inegSymbol: inegSymbol,
|
|
219
|
+
};
|
|
220
|
+
return getQuestionFromIdentifiers(identifiers, opts);
|
|
221
|
+
};
|
|
222
|
+
const getQuestionFromIdentifiers = (identifiers) => {
|
|
223
|
+
return {
|
|
224
|
+
answer: getAnswer(identifiers),
|
|
225
|
+
instruction: getInstruction(identifiers),
|
|
226
|
+
ggbOptions: getGGBOptions(identifiers),
|
|
227
|
+
keys: [],
|
|
228
|
+
identifiers,
|
|
229
|
+
hint: getHint(identifiers),
|
|
230
|
+
correction: getCorrection(identifiers),
|
|
231
|
+
correctionGgbOptions: getCorrectionGGBOptions(identifiers),
|
|
232
|
+
};
|
|
233
|
+
};
|
|
234
|
+
const { optsDefaultFirstTermRankOne, generatorOptionFirstTermRankOne } = getOptionFirstTermRankOneStuff(false);
|
|
235
|
+
const optsDefault = Object.assign({}, optsDefaultFirstTermRankOne, {});
|
|
236
|
+
const options = [generatorOptionFirstTermRankOne];
|
|
237
|
+
export const geometricFindThresholdFromGraph = {
|
|
238
|
+
id: "geometricFindThresholdFromGraph",
|
|
239
|
+
label: "À partir d'un nuage de point d'une suite géométrique, déterminer un seuil",
|
|
240
|
+
isSingleStep: true,
|
|
241
|
+
generator: (nb, opts) => getDistinctQuestions(() => getGeometricFindThresholdFromGraphQuestion(opts), nb),
|
|
242
|
+
ggbTimer: 60,
|
|
243
|
+
subject: "Mathématiques",
|
|
244
|
+
getHint,
|
|
245
|
+
getCorrection,
|
|
246
|
+
hasHintAndCorrection: true,
|
|
247
|
+
getInstruction,
|
|
248
|
+
getGGBOptions,
|
|
249
|
+
hasGeogebra: true,
|
|
250
|
+
isAnswerValid,
|
|
251
|
+
getAnswer,
|
|
252
|
+
getPropositions,
|
|
253
|
+
getQuestionFromIdentifiers,
|
|
254
|
+
options,
|
|
255
|
+
};
|
package/lib/exercises/math/sequences/geometric/graph/geometricFindThresholdUsingCalculator.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Exercise } from "../../../../../exercises/exercise.js";
|
|
2
|
+
import { OptionFirstTermRankOne } from "../../../../../exercises/options/optionFirstTermRankOne.js";
|
|
3
|
+
import { InegalitySymbols } from "../../../../../math/inequations/inequation.js";
|
|
4
|
+
import { NodeIdentifiers } from "../../../../../tree/nodes/nodeConstructor.js";
|
|
5
|
+
type Identifiers = {
|
|
6
|
+
nodeIdsInitial: NodeIdentifiers;
|
|
7
|
+
nodeIdsReason: NodeIdentifiers;
|
|
8
|
+
firstRank: number;
|
|
9
|
+
nodeIdsValueThreshold: NodeIdentifiers;
|
|
10
|
+
inegSymbol: InegalitySymbols;
|
|
11
|
+
};
|
|
12
|
+
type Options = OptionFirstTermRankOne;
|
|
13
|
+
export declare const geometricFindThresholdUsingCalculator: Exercise<Identifiers, Options>;
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=geometricFindThresholdUsingCalculator.d.ts.map
|
package/lib/exercises/math/sequences/geometric/graph/geometricFindThresholdUsingCalculator.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"geometricFindThresholdUsingCalculator.d.ts","sourceRoot":"","sources":["../../../../../../src/exercises/math/sequences/geometric/graph/geometricFindThresholdUsingCalculator.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAeT,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAEL,sBAAsB,EACvB,MAAM,mDAAmD,CAAC;AAI3D,OAAO,EACL,gBAAgB,EAEjB,MAAM,sCAAsC,CAAC;AAM9C,OAAO,EAEL,eAAe,EAChB,MAAM,qCAAqC,CAAC;AA8B7C,KAAK,WAAW,GAAG;IACjB,cAAc,EAAE,eAAe,CAAC;IAChC,aAAa,EAAE,eAAe,CAAC;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,qBAAqB,EAAE,eAAe,CAAC;IACvC,UAAU,EAAE,gBAAgB,CAAC;CAC9B,CAAC;AA4QF,KAAK,OAAO,GAAG,sBAAsB,CAAC;AAMtC,eAAO,MAAM,qCAAqC,EAAE,QAAQ,CAC1D,WAAW,EACX,OAAO,CAsBR,CAAC"}
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
import { addValidProp, tryToAddWrongProp, shuffleProps, propWhile, } from "../../../../../exercises/exercise.js";
|
|
2
|
+
import { getOptionFirstTermRankOneStuff, } from "../../../../../exercises/options/optionFirstTermRankOne.js";
|
|
3
|
+
import { getDistinctQuestions } from "../../../../../exercises/utils/getDistinctQuestions.js";
|
|
4
|
+
import { numberVEA } from "../../../../../exercises/vea/numberVEA.js";
|
|
5
|
+
import { Point } from "../../../../../math/geometry/point.js";
|
|
6
|
+
import { InequationSymbol, } from "../../../../../math/inequations/inequation.js";
|
|
7
|
+
import { randfloat } from "../../../../../math/utils/random/randfloat.js";
|
|
8
|
+
import { randint } from "../../../../../math/utils/random/randint.js";
|
|
9
|
+
import { round } from "../../../../../math/utils/round.js";
|
|
10
|
+
import { InequationNode } from "../../../../../tree/nodes/inequations/inequationNode.js";
|
|
11
|
+
import { NodeConstructor, } from "../../../../../tree/nodes/nodeConstructor.js";
|
|
12
|
+
import { multiply } from "../../../../../tree/nodes/operators/multiplyNode.js";
|
|
13
|
+
import { power } from "../../../../../tree/nodes/operators/powerNode.js";
|
|
14
|
+
import { coinFlip } from "../../../../../utils/alea/coinFlip.js";
|
|
15
|
+
import { random } from "../../../../../utils/alea/random.js";
|
|
16
|
+
import { mdTable } from "../../../../../utils/markdown/mdTable.js";
|
|
17
|
+
const getArrPoint = (nodeInitial, nodeReason, firstRank) => {
|
|
18
|
+
const arrNodeTerm = [...Array(nbPoints).keys()].map((i) => multiply(nodeInitial, power(nodeReason, i))
|
|
19
|
+
.simplify({
|
|
20
|
+
towardsDistribute: true,
|
|
21
|
+
calculatePowers: true,
|
|
22
|
+
distributePowersOnFrac: true,
|
|
23
|
+
})
|
|
24
|
+
.simplify({ towardsDistribute: false }));
|
|
25
|
+
const arrPoint = arrNodeTerm.map((nodeTerm, i) => {
|
|
26
|
+
const nodeX = (firstRank + i).toTree();
|
|
27
|
+
return new Point(`P${firstRank + i}`, nodeX, nodeTerm);
|
|
28
|
+
});
|
|
29
|
+
return arrPoint;
|
|
30
|
+
};
|
|
31
|
+
const nbPoints = 15;
|
|
32
|
+
const getInstruction = (identifiers) => {
|
|
33
|
+
const { nodeIdsValueThreshold, inegSymbol, firstRank, nodeIdsInitial, nodeIdsReason, } = identifiers;
|
|
34
|
+
const [nodeInitial, nodeReason, nodeValueThreshold] = [
|
|
35
|
+
nodeIdsInitial,
|
|
36
|
+
nodeIdsReason,
|
|
37
|
+
nodeIdsValueThreshold,
|
|
38
|
+
].map((nodeIds) => NodeConstructor.fromIdentifiers(nodeIds));
|
|
39
|
+
return `Soit une suite géométrique $u$ de premier terme $u_{${firstRank}}=${nodeInitial.toTex()}$ et de raison $${nodeReason.toTex()}$.
|
|
40
|
+
|
|
41
|
+
À l'aide de la calculatrice, déterminer le rang $N$, tel que pour tout $n \\geq N$, on a :
|
|
42
|
+
|
|
43
|
+
$$
|
|
44
|
+
u_{n} ${inegSymbol} ${nodeValueThreshold.toTex()}
|
|
45
|
+
$$
|
|
46
|
+
|
|
47
|
+
`;
|
|
48
|
+
};
|
|
49
|
+
const getAnswerStuff = (identifiers) => {
|
|
50
|
+
const { nodeIdsInitial, nodeIdsReason, nodeIdsValueThreshold, firstRank, inegSymbol, } = identifiers;
|
|
51
|
+
const [nodeInitial, nodeReason, nodeValueThreshold] = [
|
|
52
|
+
nodeIdsInitial,
|
|
53
|
+
nodeIdsReason,
|
|
54
|
+
nodeIdsValueThreshold,
|
|
55
|
+
].map((nodeIds) => NodeConstructor.fromIdentifiers(nodeIds));
|
|
56
|
+
const arrPoint = getArrPoint(nodeInitial, nodeReason, firstRank);
|
|
57
|
+
const [pointValid, indexPointValid] = arrPoint
|
|
58
|
+
.map((point, i) => [point, i])
|
|
59
|
+
.find(([point, _i]) => {
|
|
60
|
+
const inequationNode = new InequationNode([point.y, nodeValueThreshold], inegSymbol);
|
|
61
|
+
return inequationNode.isVerified();
|
|
62
|
+
});
|
|
63
|
+
return { arrPoint, pointValid, indexPointValid };
|
|
64
|
+
};
|
|
65
|
+
const getAnswer = (identifiers) => {
|
|
66
|
+
return getAnswerStuff(identifiers).pointValid.x.toTex();
|
|
67
|
+
};
|
|
68
|
+
const getHint = (identifiers) => {
|
|
69
|
+
const { nodeIdsValueThreshold, nodeIdsInitial, nodeIdsReason, inegSymbol, firstRank, } = identifiers;
|
|
70
|
+
const [nodeInitial, nodeReason, nodeValueThreshold] = [
|
|
71
|
+
nodeIdsInitial,
|
|
72
|
+
nodeIdsReason,
|
|
73
|
+
nodeIdsValueThreshold,
|
|
74
|
+
].map((nodeIds) => NodeConstructor.fromIdentifiers(nodeIds));
|
|
75
|
+
return `Avec la calculatrice, à partir du menu, sélectionne le mode correspondant aux suites.
|
|
76
|
+
Entre les paramètres de la suite : $u_{${firstRank}}=${nodeInitial.toTex()}$ et raison: $${nodeReason.toTex()}$.
|
|
77
|
+
Demande d'afficher le tableau de valeurs.
|
|
78
|
+
Cherche alors le rang du premier terme ${(() => {
|
|
79
|
+
switch (inegSymbol) {
|
|
80
|
+
case "\\ge":
|
|
81
|
+
return `supérieur ou égal`;
|
|
82
|
+
case ">":
|
|
83
|
+
return `supérieur`;
|
|
84
|
+
case "\\le":
|
|
85
|
+
return `inférieur ou égal`;
|
|
86
|
+
case "<":
|
|
87
|
+
return `inférieur`;
|
|
88
|
+
}
|
|
89
|
+
})()} à $${nodeValueThreshold.toTex()}$.
|
|
90
|
+
`;
|
|
91
|
+
};
|
|
92
|
+
const getCorrection = (identifiers) => {
|
|
93
|
+
const { nodeIdsValueThreshold, nodeIdsInitial, nodeIdsReason, inegSymbol, firstRank, } = identifiers;
|
|
94
|
+
const [nodeInitial, nodeReason, nodeValueThreshold] = [
|
|
95
|
+
nodeIdsInitial,
|
|
96
|
+
nodeIdsReason,
|
|
97
|
+
nodeIdsValueThreshold,
|
|
98
|
+
].map((nodeIds) => NodeConstructor.fromIdentifiers(nodeIds));
|
|
99
|
+
const { arrPoint, pointValid, indexPointValid } = getAnswerStuff(identifiers);
|
|
100
|
+
function highlighted(str) {
|
|
101
|
+
return `{ \\color{green} ${str} }`;
|
|
102
|
+
}
|
|
103
|
+
return `On cherche le rang du premier terme ${(() => {
|
|
104
|
+
switch (inegSymbol) {
|
|
105
|
+
case "\\ge":
|
|
106
|
+
return `supérieur ou égal`;
|
|
107
|
+
case ">":
|
|
108
|
+
return `supérieur`;
|
|
109
|
+
case "\\le":
|
|
110
|
+
return `inférieur ou égal`;
|
|
111
|
+
case "<":
|
|
112
|
+
return `inférieur`;
|
|
113
|
+
}
|
|
114
|
+
})()} à $${nodeValueThreshold.toTex()}$.
|
|
115
|
+
|
|
116
|
+
Avec la calculatrice, à partir du menu, on sélectionne le mode correspondant aux suites.
|
|
117
|
+
On entre les paramètres de la suite : $u_{${firstRank}}=${nodeInitial.toTex()}$ et raison: $${nodeReason.toTex()}$.
|
|
118
|
+
On demande d'afficher le tableau de valeurs.
|
|
119
|
+
On obtient alors :
|
|
120
|
+
|
|
121
|
+
${mdTable([
|
|
122
|
+
["n", "u_{n}"],
|
|
123
|
+
...arrPoint.map((point, i) => i === indexPointValid
|
|
124
|
+
? [point.x.toTex(), round(point.y.evaluate(), 2).frenchify()].map((tex) => highlighted(tex))
|
|
125
|
+
: [point.x.toTex(), round(point.y.evaluate(), 2).frenchify()]),
|
|
126
|
+
], true)}
|
|
127
|
+
|
|
128
|
+
Le rang recherché est $${pointValid.x.toTex()}$.
|
|
129
|
+
|
|
130
|
+
`;
|
|
131
|
+
};
|
|
132
|
+
const getPropositions = (n, { answer }) => {
|
|
133
|
+
const propositions = [];
|
|
134
|
+
addValidProp(propositions, answer);
|
|
135
|
+
propWhile(propositions, n, () => {
|
|
136
|
+
const indexThreshold = randint(7, 15);
|
|
137
|
+
tryToAddWrongProp(propositions, indexThreshold.frenchify());
|
|
138
|
+
});
|
|
139
|
+
return shuffleProps(propositions, n);
|
|
140
|
+
};
|
|
141
|
+
const isAnswerValid = (ans, { answer }) => {
|
|
142
|
+
return numberVEA(ans, answer);
|
|
143
|
+
};
|
|
144
|
+
const getGeometricFindThresholdUsingCalculatorQuestion = (optsIn) => {
|
|
145
|
+
const opts = optsIn ?? optsDefault;
|
|
146
|
+
const firstRank = opts?.firstTermRankOne ? 1 : 0;
|
|
147
|
+
const { isDivergent: _isDivergent, nodeInitialAbs, nodeReasonAbs, nodeValueThresholdAbs, inegSymbolAbs, } = (() => {
|
|
148
|
+
const isDivergent = coinFlip();
|
|
149
|
+
const { nodeInitialAbs, nodeReasonAbs } = (() => {
|
|
150
|
+
if (isDivergent) {
|
|
151
|
+
return {
|
|
152
|
+
nodeInitialAbs: randfloat(1, 10, 1).toTree(),
|
|
153
|
+
nodeReasonAbs: randfloat(2, 3, 1).toTree(),
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
return {
|
|
158
|
+
nodeInitialAbs: randfloat(1000, 2000, 0).toTree(),
|
|
159
|
+
nodeReasonAbs: randfloat(0.5, 0.85, 1).toTree(),
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
})();
|
|
163
|
+
const arrPointAbs = getArrPoint(nodeInitialAbs, nodeReasonAbs, firstRank);
|
|
164
|
+
const { nodeValueThresholdAbs, inegSymbolAbs } = (() => {
|
|
165
|
+
const isValueThresholdEqualToTerm = coinFlip();
|
|
166
|
+
const nodeValueThresholdAbs = (() => {
|
|
167
|
+
const indexThresholdLow = randint(8, 14);
|
|
168
|
+
const progress = randfloat(0.3, 0.7, 1);
|
|
169
|
+
const [v1, v2] = [indexThresholdLow, indexThresholdLow + 1].map((index) => arrPointAbs[index].y.evaluate());
|
|
170
|
+
return round(v1 + (v2 - v1) * progress, 2).toTree();
|
|
171
|
+
})();
|
|
172
|
+
const inegSymbolAbs = (() => {
|
|
173
|
+
if (isDivergent) {
|
|
174
|
+
return isValueThresholdEqualToTerm ? "\\ge" : random(["\\ge", ">"]);
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
return isValueThresholdEqualToTerm ? "\\le" : random(["\\le", "<"]);
|
|
178
|
+
}
|
|
179
|
+
})();
|
|
180
|
+
return { nodeValueThresholdAbs, inegSymbolAbs };
|
|
181
|
+
})();
|
|
182
|
+
return {
|
|
183
|
+
isDivergent,
|
|
184
|
+
nodeInitialAbs,
|
|
185
|
+
nodeReasonAbs,
|
|
186
|
+
nodeValueThresholdAbs,
|
|
187
|
+
inegSymbolAbs,
|
|
188
|
+
};
|
|
189
|
+
})();
|
|
190
|
+
const { nodeInitial, nodeReason, nodeValueThreshold, inegSymbol } = (() => {
|
|
191
|
+
const signInitial = coinFlip() ? +1 : -1;
|
|
192
|
+
const nodeInitial = multiply(signInitial, nodeInitialAbs).simplify({
|
|
193
|
+
towardsDistribute: true,
|
|
194
|
+
});
|
|
195
|
+
const nodeReason = nodeReasonAbs; //reason is always positive
|
|
196
|
+
const nodeValueThreshold = multiply(signInitial, nodeValueThresholdAbs).simplify({
|
|
197
|
+
towardsDistribute: true,
|
|
198
|
+
});
|
|
199
|
+
const inegSymbol = signInitial === +1
|
|
200
|
+
? inegSymbolAbs
|
|
201
|
+
: new InequationSymbol(inegSymbolAbs).reversed();
|
|
202
|
+
return { nodeInitial, nodeReason, nodeValueThreshold, inegSymbol };
|
|
203
|
+
})();
|
|
204
|
+
const identifiers = {
|
|
205
|
+
firstRank,
|
|
206
|
+
nodeIdsInitial: nodeInitial.toIdentifiers(),
|
|
207
|
+
nodeIdsReason: nodeReason.toIdentifiers(),
|
|
208
|
+
nodeIdsValueThreshold: nodeValueThreshold.toIdentifiers(),
|
|
209
|
+
inegSymbol: inegSymbol,
|
|
210
|
+
};
|
|
211
|
+
return getQuestionFromIdentifiers(identifiers, opts);
|
|
212
|
+
};
|
|
213
|
+
const getQuestionFromIdentifiers = (identifiers) => {
|
|
214
|
+
return {
|
|
215
|
+
answer: getAnswer(identifiers),
|
|
216
|
+
instruction: getInstruction(identifiers),
|
|
217
|
+
keys: [],
|
|
218
|
+
identifiers,
|
|
219
|
+
hint: getHint(identifiers),
|
|
220
|
+
correction: getCorrection(identifiers),
|
|
221
|
+
};
|
|
222
|
+
};
|
|
223
|
+
const { optsDefaultFirstTermRankOne, generatorOptionFirstTermRankOne } = getOptionFirstTermRankOneStuff(false);
|
|
224
|
+
const optsDefault = Object.assign({}, optsDefaultFirstTermRankOne, {});
|
|
225
|
+
const options = [generatorOptionFirstTermRankOne];
|
|
226
|
+
export const geometricFindThresholdUsingCalculator = {
|
|
227
|
+
id: "geometricFindThresholdUsingCalculator",
|
|
228
|
+
label: "Déterminer un seuil d'une suite géométrique en utilisant la calculatrice",
|
|
229
|
+
isSingleStep: true,
|
|
230
|
+
generator: (nb, opts) => getDistinctQuestions(() => getGeometricFindThresholdUsingCalculatorQuestion(opts), nb),
|
|
231
|
+
ggbTimer: 60,
|
|
232
|
+
subject: "Mathématiques",
|
|
233
|
+
getHint,
|
|
234
|
+
getCorrection,
|
|
235
|
+
hasHintAndCorrection: true,
|
|
236
|
+
getInstruction,
|
|
237
|
+
isAnswerValid,
|
|
238
|
+
getAnswer,
|
|
239
|
+
getPropositions,
|
|
240
|
+
getQuestionFromIdentifiers,
|
|
241
|
+
options,
|
|
242
|
+
};
|
|
@@ -20,7 +20,7 @@ const getInstruction = (identifiers) => {
|
|
|
20
20
|
const { firstRank, nodeIdsInitial, nodeIdsReason } = identifiers;
|
|
21
21
|
const [nodeInitial, nodeReason] = [nodeIdsInitial, nodeIdsReason].map((nodeIds) => NodeConstructor.fromIdentifiers(nodeIds));
|
|
22
22
|
return `On considère une suite géométrique $u$ de premier rang $u_{${firstRank}}=${nodeInitial.toTex()}$ et de raison $${nodeReason.toTex()}$.
|
|
23
|
-
Dans le repère ci-dessous, placer les points représentant les $${nbPoints}$ premiers termes de
|
|
23
|
+
Dans le repère ci-dessous, placer les points représentant les $${nbPoints}$ premiers termes de $u$.`;
|
|
24
24
|
};
|
|
25
25
|
const getAnswerStuff = (identifiers) => {
|
|
26
26
|
const { firstRank, nodeIdsInitial, nodeIdsReason } = identifiers;
|
|
@@ -99,7 +99,7 @@ const isGGBAnswerValid = (ans, { ggbAnswer: _ggbAnswer, ...identifiers }) => {
|
|
|
99
99
|
return points.every((p, i) => Math.abs(p.x - validPoints[i].x.evaluate()) < 0.4 &&
|
|
100
100
|
Math.abs(p.y - validPoints[i].y.evaluate()) < 0.4);
|
|
101
101
|
};
|
|
102
|
-
const
|
|
102
|
+
const getGeometricPlaceFirstPointsQuestion = (optsIn) => {
|
|
103
103
|
const opts = optsIn ?? optsDefault;
|
|
104
104
|
const firstRank = opts?.firstTermRankOne ? 1 : 0;
|
|
105
105
|
const typeSignReason = opts?.typeSignReason
|
|
@@ -172,8 +172,8 @@ export const geometricPlaceFirstPoints = {
|
|
|
172
172
|
label: "Placer les premiers termes d'une suite géométrique dans un repère",
|
|
173
173
|
isSingleStep: true,
|
|
174
174
|
generator: (nb, opts) =>
|
|
175
|
-
// getDistinctQuestions(() =>
|
|
176
|
-
[...Array(nb).keys()].map(() =>
|
|
175
|
+
// getDistinctQuestions(() => getGeometricPlaceFirstPointsQuestion(opts), nb),
|
|
176
|
+
[...Array(nb).keys()].map(() => getGeometricPlaceFirstPointsQuestion(opts)),
|
|
177
177
|
ggbTimer: 60,
|
|
178
178
|
isGGBAnswerValid,
|
|
179
179
|
subject: "Mathématiques",
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Exercise } from "../../../../../exercises/exercise.js";
|
|
2
|
+
import { OptionFirstTermRankOne } from "../../../../../exercises/options/optionFirstTermRankOne.js";
|
|
3
|
+
import { NodeIdentifiers } from "../../../../../tree/nodes/nodeConstructor.js";
|
|
4
|
+
type Identifiers = {
|
|
5
|
+
nodeIdsInitial: NodeIdentifiers;
|
|
6
|
+
nodeIdsReason: NodeIdentifiers;
|
|
7
|
+
firstRank: number;
|
|
8
|
+
};
|
|
9
|
+
type Options = OptionFirstTermRankOne;
|
|
10
|
+
export declare const geometricSignOfReasonFromGraph: Exercise<Identifiers, Options>;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=geometricSignOfReasonFromGraph.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"geometricSignOfReasonFromGraph.d.ts","sourceRoot":"","sources":["../../../../../../src/exercises/math/sequences/geometric/graph/geometricSignOfReasonFromGraph.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAaT,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAEL,sBAAsB,EACvB,MAAM,mDAAmD,CAAC;AAM3D,OAAO,EAEL,eAAe,EAChB,MAAM,qCAAqC,CAAC;AAS7C,KAAK,WAAW,GAAG;IACjB,cAAc,EAAE,eAAe,CAAC;IAChC,aAAa,EAAE,eAAe,CAAC;IAC/B,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAiKF,KAAK,OAAO,GAAG,sBAAsB,CAAC;AAMtC,eAAO,MAAM,8BAA8B,EAAE,QAAQ,CAAC,WAAW,EAAE,OAAO,CAuBzE,CAAC"}
|