math-exercises 3.0.173 → 3.0.175
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/functions/trinoms/parabole/parabolaVarTable.js +2 -2
- package/lib/exercises/math/functions/trinoms/parabole/paraboleSolveGraphEquation.js +1 -1
- package/lib/exercises/math/functions/trinoms/roots/rootsFromDevForm.d.ts.map +1 -1
- package/lib/exercises/math/functions/trinoms/roots/rootsFromDevForm.js +0 -1
- package/lib/exercises/math/probaStat/trees/buildTreeFromSituation.d.ts +2 -0
- package/lib/exercises/math/probaStat/trees/buildTreeFromSituation.d.ts.map +1 -0
- package/lib/exercises/math/probaStat/trees/buildTreeFromSituation.js +68 -0
- package/lib/exercises/math/probaStat/trees/fillProbaTreeWithComplementaryProbabilities.d.ts +15 -0
- package/lib/exercises/math/probaStat/trees/fillProbaTreeWithComplementaryProbabilities.d.ts.map +1 -0
- package/lib/exercises/math/probaStat/trees/fillProbaTreeWithComplementaryProbabilities.js +206 -0
- package/lib/exercises/math/probaStat/trees/probaTreeSituations.d.ts +2 -0
- package/lib/exercises/math/probaStat/trees/probaTreeSituations.d.ts.map +1 -0
- package/lib/exercises/math/probaStat/trees/probaTreeSituations.js +108 -0
- package/lib/exercises/math/probaStat/trees/probabilityTree.d.ts +25 -0
- package/lib/exercises/math/probaStat/trees/probabilityTree.d.ts.map +1 -0
- package/lib/exercises/math/probaStat/trees/probabilityTree.js +625 -0
- package/lib/exercises/math/probaStat/trees/treeInAnswer.d.ts +9 -0
- package/lib/exercises/math/probaStat/trees/treeInAnswer.d.ts.map +1 -0
- package/lib/exercises/math/probaStat/trees/treeInAnswer.js +107 -0
- package/lib/exercises/math/sequences/geometric/geometricFindExplicitFormula.js +1 -1
- package/lib/exercises/math/sequences/geometric/geometricFindExplicitFormulaFirstRankOne.js +1 -1
- package/lib/exercises/math/sequences/geometric/geometricFindExplicitFormulaFirstTermRandom.d.ts +4 -1
- package/lib/exercises/math/sequences/geometric/geometricFindExplicitFormulaFirstTermRandom.d.ts.map +1 -1
- package/lib/exercises/math/sequences/geometric/geometricFindExplicitFormulaFirstTermRandom.js +66 -24
- package/lib/exercises/math/trigonometry/circle/index.d.ts +1 -0
- package/lib/exercises/math/trigonometry/circle/index.d.ts.map +1 -1
- package/lib/exercises/math/trigonometry/circle/index.js +1 -0
- package/lib/exercises/math/trigonometry/circle/selectQuadrantOnTrigoCircle.d.ts +2 -0
- package/lib/exercises/math/trigonometry/circle/selectQuadrantOnTrigoCircle.d.ts.map +1 -0
- package/lib/exercises/math/trigonometry/circle/selectQuadrantOnTrigoCircle.js +94 -0
- package/lib/exercises/math/trigonometry/circle/trigoFunctionsFundamentalEquation.d.ts +10 -0
- package/lib/exercises/math/trigonometry/circle/trigoFunctionsFundamentalEquation.d.ts.map +1 -0
- package/lib/exercises/math/trigonometry/circle/trigoFunctionsFundamentalEquation.js +223 -0
- package/lib/exercises/math/trigonometry/functions/basicEquationCos.d.ts.map +1 -1
- package/lib/exercises/math/trigonometry/functions/basicEquationCos.js +2 -1
- package/lib/exercises/math/trigonometry/functions/cosInequationMainInterval.d.ts +10 -0
- package/lib/exercises/math/trigonometry/functions/cosInequationMainInterval.d.ts.map +1 -0
- package/lib/exercises/math/trigonometry/functions/cosInequationMainInterval.js +208 -0
- package/lib/exercises/math/trigonometry/functions/equationSinOnRandomInterval.d.ts +0 -6
- package/lib/exercises/math/trigonometry/functions/equationSinOnRandomInterval.d.ts.map +1 -1
- package/lib/exercises/math/trigonometry/functions/equationSinOnRandomInterval.js +162 -99
- package/lib/exercises/math/trigonometry/functions/index.d.ts +3 -0
- package/lib/exercises/math/trigonometry/functions/index.d.ts.map +1 -1
- package/lib/exercises/math/trigonometry/functions/index.js +3 -0
- package/lib/exercises/math/trigonometry/functions/readPeriodicityOnFunctionGraph.d.ts +12 -0
- package/lib/exercises/math/trigonometry/functions/readPeriodicityOnFunctionGraph.d.ts.map +1 -0
- package/lib/exercises/math/trigonometry/functions/readPeriodicityOnFunctionGraph.js +159 -0
- package/lib/exercises/math/trigonometry/functions/sinInequationMainInterval.d.ts +10 -0
- package/lib/exercises/math/trigonometry/functions/sinInequationMainInterval.d.ts.map +1 -0
- package/lib/exercises/math/trigonometry/functions/sinInequationMainInterval.js +224 -0
- package/lib/exercises/math/trigonometry/trigoFundamentalEquation.js +1 -1
- package/lib/exercises/vea/treeTableVEA.d.ts +2 -0
- package/lib/exercises/vea/treeTableVEA.d.ts.map +1 -0
- package/lib/exercises/vea/treeTableVEA.js +7 -0
- package/lib/exercises/vea/varLineVEA.d.ts.map +1 -1
- package/lib/exercises/vea/varLineVEA.js +9 -6
- package/lib/index.d.ts +19 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/tree/nodes/inequations/inequationNode.d.ts +1 -0
- package/lib/tree/nodes/inequations/inequationNode.d.ts.map +1 -1
- package/lib/tree/nodes/inequations/inequationNode.js +16 -0
- package/lib/utils/latex/poundify.d.ts +2 -0
- package/lib/utils/latex/poundify.d.ts.map +1 -0
- package/lib/utils/latex/poundify.js +3 -0
- package/package.json +1 -1
|
@@ -0,0 +1,625 @@
|
|
|
1
|
+
import { rationalVEA } from "../../../../exercises/vea/rationalVEA.js";
|
|
2
|
+
import { RationalConstructor } from "../../../../math/numbers/rationals/rational.js";
|
|
3
|
+
import { randfloat } from "../../../../math/utils/random/randfloat.js";
|
|
4
|
+
import { randint } from "../../../../math/utils/random/randint.js";
|
|
5
|
+
import { round } from "../../../../math/utils/round.js";
|
|
6
|
+
import { NodeConstructor, } from "../../../../tree/nodes/nodeConstructor.js";
|
|
7
|
+
import { add } from "../../../../tree/nodes/operators/addNode.js";
|
|
8
|
+
import { frac } from "../../../../tree/nodes/operators/fractionNode.js";
|
|
9
|
+
import { multiply } from "../../../../tree/nodes/operators/multiplyNode.js";
|
|
10
|
+
import { substract } from "../../../../tree/nodes/operators/substractNode.js";
|
|
11
|
+
import { random } from "../../../../utils/alea/random.js";
|
|
12
|
+
import { shuffle } from "../../../../utils/alea/shuffle.js";
|
|
13
|
+
import { handleVEAError } from "../../../../utils/errors/handleVEAError.js";
|
|
14
|
+
import { GeneratorOptionTarget, GeneratorOptionType, addValidProp, propWhile, tryToAddWrongProp, } from "../../../exercise.js";
|
|
15
|
+
import { getDistinctQuestions } from "../../../utils/getDistinctQuestions.js";
|
|
16
|
+
const optionValues = [
|
|
17
|
+
"Probabilité d'intersection $P(A\\cap C)$",
|
|
18
|
+
"Probabilité totale $P(C)$",
|
|
19
|
+
"Probabilité conditionnelle $P_B(A)$",
|
|
20
|
+
"Probabilité 'simple' $P(A)$",
|
|
21
|
+
"Probabilité d'inversion de causalité $P_B(A)$",
|
|
22
|
+
];
|
|
23
|
+
const defaultOptionValues = [
|
|
24
|
+
"Probabilité d'intersection $P(A\\cap C)$",
|
|
25
|
+
"Probabilité totale $P(C)$",
|
|
26
|
+
"Probabilité conditionnelle $P_B(A)$",
|
|
27
|
+
"Probabilité 'simple' $P(A)$",
|
|
28
|
+
];
|
|
29
|
+
const getProbaType = (identifiers) => {
|
|
30
|
+
const { probaName } = identifiers;
|
|
31
|
+
return probaName.includes("\\cap")
|
|
32
|
+
? "inter"
|
|
33
|
+
: ["P(C)", "P(D)"].includes(probaName)
|
|
34
|
+
? "totale"
|
|
35
|
+
: ["P(A)", "P(B)"].includes(probaName)
|
|
36
|
+
? "simple"
|
|
37
|
+
: ["P_A(C)", "P_A(D)", "P_B(C)", "P_B(D)"].includes(probaName)
|
|
38
|
+
? "conditionnelle"
|
|
39
|
+
: "inversion";
|
|
40
|
+
};
|
|
41
|
+
const buildAll = (identifiers) => {
|
|
42
|
+
return {
|
|
43
|
+
pA: NodeConstructor.fromIdentifiers(identifiers.A),
|
|
44
|
+
pAC: NodeConstructor.fromIdentifiers(identifiers.AC),
|
|
45
|
+
pAD: NodeConstructor.fromIdentifiers(identifiers.AD),
|
|
46
|
+
pB: NodeConstructor.fromIdentifiers(identifiers.B),
|
|
47
|
+
pBC: NodeConstructor.fromIdentifiers(identifiers.BC),
|
|
48
|
+
pBD: NodeConstructor.fromIdentifiers(identifiers.BD),
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
const getAnswerNode = (identifiers) => {
|
|
52
|
+
const probas = buildAll(identifiers);
|
|
53
|
+
switch (identifiers.probaName) {
|
|
54
|
+
case "P(A)":
|
|
55
|
+
return probas.pA;
|
|
56
|
+
case "P(B)":
|
|
57
|
+
return probas.pB;
|
|
58
|
+
case "P(A\\cap C)":
|
|
59
|
+
return multiply(probas.pA, probas.pAC).simplify();
|
|
60
|
+
case "P(A\\cap D)":
|
|
61
|
+
return multiply(probas.pA, probas.pAD).simplify();
|
|
62
|
+
case "P(B\\cap C)":
|
|
63
|
+
return multiply(probas.pB, probas.pBC).simplify();
|
|
64
|
+
case "P(B\\cap D)":
|
|
65
|
+
return multiply(probas.pB, probas.pBD).simplify();
|
|
66
|
+
case "P_A(C)":
|
|
67
|
+
return probas.pAC;
|
|
68
|
+
case "P_A(D)":
|
|
69
|
+
return probas.pAD;
|
|
70
|
+
case "P_B(C)":
|
|
71
|
+
return probas.pBC;
|
|
72
|
+
case "P_B(D)":
|
|
73
|
+
return probas.pBD;
|
|
74
|
+
case "P(C)":
|
|
75
|
+
return add(multiply(probas.pA, probas.pAC), multiply(probas.pB, probas.pBC)).simplify();
|
|
76
|
+
case "P(D)":
|
|
77
|
+
default:
|
|
78
|
+
return add(multiply(probas.pA, probas.pAD), multiply(probas.pB, probas.pBD)).simplify();
|
|
79
|
+
case "P_C(A)": {
|
|
80
|
+
//anc / c
|
|
81
|
+
const pc = add(multiply(probas.pA, probas.pAC), multiply(probas.pB, probas.pBC)).simplify();
|
|
82
|
+
return frac(multiply(probas.pA, probas.pAC), pc).simplify();
|
|
83
|
+
}
|
|
84
|
+
case "P_C(B)": {
|
|
85
|
+
//cnb / c
|
|
86
|
+
const pc = add(multiply(probas.pA, probas.pAC), multiply(probas.pB, probas.pBC)).simplify();
|
|
87
|
+
return frac(multiply(probas.pB, probas.pBC), pc).simplify();
|
|
88
|
+
}
|
|
89
|
+
case "P_D(A)": {
|
|
90
|
+
//and / d
|
|
91
|
+
const pd = add(multiply(probas.pA, probas.pAD), multiply(probas.pB, probas.pBD)).simplify();
|
|
92
|
+
return frac(multiply(probas.pA, probas.pAD), pd).simplify();
|
|
93
|
+
}
|
|
94
|
+
case "P_D(B)": {
|
|
95
|
+
//cnb / c
|
|
96
|
+
const pd = add(multiply(probas.pA, probas.pAD), multiply(probas.pB, probas.pBD)).simplify();
|
|
97
|
+
return frac(multiply(probas.pB, probas.pBD), pd).simplify();
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
const getAnswer = (identifiers) => {
|
|
102
|
+
return getAnswerNode(identifiers).toTex();
|
|
103
|
+
};
|
|
104
|
+
const getTrueProbaName = (identifiers) => {
|
|
105
|
+
const { probaName, useContraryNames } = identifiers;
|
|
106
|
+
if (!useContraryNames)
|
|
107
|
+
return probaName;
|
|
108
|
+
return probaName
|
|
109
|
+
.replaceAll("_B", "_{\\overline{A}}")
|
|
110
|
+
.replaceAll("B", "\\overline{A}")
|
|
111
|
+
.replaceAll("_D", "_{\\overline{B}}")
|
|
112
|
+
.replaceAll("C", "B")
|
|
113
|
+
.replaceAll("D", "\\overline{B}");
|
|
114
|
+
};
|
|
115
|
+
const getInstruction = (identifiers, options) => {
|
|
116
|
+
const probas = buildAll(identifiers);
|
|
117
|
+
const type = getProbaType(identifiers);
|
|
118
|
+
const { useContraryNames } = identifiers;
|
|
119
|
+
const trueProbaName = getTrueProbaName(identifiers);
|
|
120
|
+
const tree = [
|
|
121
|
+
[
|
|
122
|
+
[
|
|
123
|
+
[`£${probas.pA.toTex()}£`, "£A£"],
|
|
124
|
+
[
|
|
125
|
+
`£${probas.pB.toTex()}£`,
|
|
126
|
+
useContraryNames ? "£\\overline{A}£" : "£B£",
|
|
127
|
+
],
|
|
128
|
+
],
|
|
129
|
+
],
|
|
130
|
+
[
|
|
131
|
+
[
|
|
132
|
+
[`£${probas.pAC.toTex()}£`, useContraryNames ? "£B£" : "£C£"],
|
|
133
|
+
[
|
|
134
|
+
`£${probas.pAD.toTex()}£`,
|
|
135
|
+
useContraryNames ? "£\\overline{B}£" : "£D£",
|
|
136
|
+
],
|
|
137
|
+
],
|
|
138
|
+
[
|
|
139
|
+
[`£${probas.pBC.toTex()}£`, useContraryNames ? "£B£" : "£C£"],
|
|
140
|
+
[
|
|
141
|
+
`£${probas.pBD.toTex()}£`,
|
|
142
|
+
useContraryNames ? "£\\overline{B}£" : "£D£",
|
|
143
|
+
],
|
|
144
|
+
],
|
|
145
|
+
],
|
|
146
|
+
];
|
|
147
|
+
let instr = `On considère l'arbre de probabilités ci-dessous :
|
|
148
|
+
|
|
149
|
+
<svg id="treeDiagram">${JSON.stringify(tree)}</svg>
|
|
150
|
+
|
|
151
|
+
${type === "conditionnelle" || type === "simple" ? "Déterminer :" : "Calculer :"}
|
|
152
|
+
|
|
153
|
+
$$
|
|
154
|
+
${trueProbaName}
|
|
155
|
+
$$`;
|
|
156
|
+
if (options?.allowApproximate) {
|
|
157
|
+
instr += `
|
|
158
|
+
|
|
159
|
+
Donner la valeur exacte ou une valeur arrondie au ${options.allowApproximate}.`;
|
|
160
|
+
}
|
|
161
|
+
return instr;
|
|
162
|
+
};
|
|
163
|
+
const getProbaAndOpposite = (decimal = false) => {
|
|
164
|
+
if (!decimal) {
|
|
165
|
+
const proba = RationalConstructor.randomIrreductibleProba().toTree();
|
|
166
|
+
return [proba, substract(1, proba).simplify()];
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
const proba = round(randfloat(0.01, 1, 2), 2);
|
|
170
|
+
return [proba.toTree(), round(1 - proba, 2).toTree()];
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
const getStartStatement = (identifiers) => {
|
|
174
|
+
return getTrueProbaName(identifiers);
|
|
175
|
+
};
|
|
176
|
+
const getProbabilityTree = (opts) => {
|
|
177
|
+
const isDecimal = opts?.probaType === "Décimales";
|
|
178
|
+
const [pA, pB] = getProbaAndOpposite(isDecimal);
|
|
179
|
+
const [pCSachantA, pDSachantA] = getProbaAndOpposite(isDecimal);
|
|
180
|
+
const [pCSachantB, pDSachantB] = getProbaAndOpposite(isDecimal);
|
|
181
|
+
const eventTypes = opts?.eventTypes?.length
|
|
182
|
+
? opts.eventTypes
|
|
183
|
+
: defaultOptionValues;
|
|
184
|
+
const type = random(eventTypes);
|
|
185
|
+
const index = optionValues.indexOf(type);
|
|
186
|
+
let probaName = "";
|
|
187
|
+
switch (index) {
|
|
188
|
+
case 0: //inter
|
|
189
|
+
probaName = random([
|
|
190
|
+
"P(A\\cap C)",
|
|
191
|
+
"P(A\\cap D)",
|
|
192
|
+
"P(B\\cap C)",
|
|
193
|
+
"P(B\\cap D)",
|
|
194
|
+
]);
|
|
195
|
+
break;
|
|
196
|
+
case 1: //totale
|
|
197
|
+
probaName = random(["P(C)", "P(D)"]);
|
|
198
|
+
break;
|
|
199
|
+
case 2: //conditionnal
|
|
200
|
+
probaName = random(["P_A(C)", "P_A(D)", "P_B(C)", "P_B(D)"]);
|
|
201
|
+
break;
|
|
202
|
+
case 3: //simple
|
|
203
|
+
probaName = random(["P(A)", "P(B)"]);
|
|
204
|
+
break;
|
|
205
|
+
case 4: //inversion
|
|
206
|
+
probaName = random(["P_C(A)", "P_D(A)", "P_C(B)", "P_D(B)"]);
|
|
207
|
+
break;
|
|
208
|
+
}
|
|
209
|
+
const identifiers = {
|
|
210
|
+
A: pA.toIdentifiers(),
|
|
211
|
+
B: pB.toIdentifiers(),
|
|
212
|
+
AC: pCSachantA.toIdentifiers(),
|
|
213
|
+
AD: pDSachantA.toIdentifiers(),
|
|
214
|
+
BC: pCSachantB.toIdentifiers(),
|
|
215
|
+
BD: pDSachantB.toIdentifiers(),
|
|
216
|
+
probaName,
|
|
217
|
+
useContraryNames: opts?.eventsNames === "Événements et leur contraire",
|
|
218
|
+
};
|
|
219
|
+
return getQuestionFromIdentifiers(identifiers, opts);
|
|
220
|
+
};
|
|
221
|
+
const getHint = (identifiers) => {
|
|
222
|
+
const { probaName, useContraryNames } = identifiers;
|
|
223
|
+
const type = getProbaType(identifiers);
|
|
224
|
+
const trueProbaName = getTrueProbaName(identifiers);
|
|
225
|
+
switch (type) {
|
|
226
|
+
case "conditionnelle": {
|
|
227
|
+
const splitted = probaName
|
|
228
|
+
.replaceAll("(", "")
|
|
229
|
+
.replaceAll(")", "")
|
|
230
|
+
.split("_")[1];
|
|
231
|
+
const under = splitted[0];
|
|
232
|
+
const trueUnder = useContraryNames && under === "B" ? "\\overline{A}" : under;
|
|
233
|
+
const over = splitted[1];
|
|
234
|
+
const trueOver = useContraryNames
|
|
235
|
+
? over === "C"
|
|
236
|
+
? "B"
|
|
237
|
+
: "\\overline{B}"
|
|
238
|
+
: over;
|
|
239
|
+
return `La probabilité $${trueProbaName}$ est la probabilité de $${trueOver}$ sachant $${trueUnder}$.
|
|
240
|
+
|
|
241
|
+
Dans l'arbre, elle se lit sur la branche partant de $${trueUnder}$ et allant jusqu'à $${trueOver}$.`;
|
|
242
|
+
}
|
|
243
|
+
case "inter": {
|
|
244
|
+
const [first, second] = probaName
|
|
245
|
+
.replaceAll("P(", "")
|
|
246
|
+
.replaceAll(")", "")
|
|
247
|
+
.split("\\cap ");
|
|
248
|
+
const trueFirst = useContraryNames && first === "B" ? "\\overline{A}" : first;
|
|
249
|
+
const trueSecond = useContraryNames
|
|
250
|
+
? second === "C"
|
|
251
|
+
? "B"
|
|
252
|
+
: "\\overline{B}"
|
|
253
|
+
: second;
|
|
254
|
+
return `La probabilité $${trueProbaName}$ est la probabilité d'une intersection.
|
|
255
|
+
|
|
256
|
+
Pour la calculer, il faut multiplier les probabilités présentes sur les branches suivant le chemin $${trueFirst}$ puis $${trueSecond}$.
|
|
257
|
+
`;
|
|
258
|
+
}
|
|
259
|
+
case "totale": {
|
|
260
|
+
const evenement = probaName[2];
|
|
261
|
+
const trueEvenement = useContraryNames
|
|
262
|
+
? evenement === "C"
|
|
263
|
+
? "B"
|
|
264
|
+
: "\\overline{B}"
|
|
265
|
+
: evenement;
|
|
266
|
+
return `Il y a plusieurs chemins qui mènent à l'événement $${trueEvenement}$. Sa probabilité est la somme des probabilités de chacun de ces chemins. Pour obtenir la probabilité d'un chemin, il faut multiplier les probabilités présentes sur les branches de ce chemin.`;
|
|
267
|
+
}
|
|
268
|
+
case "simple": {
|
|
269
|
+
const trueEvent = useContraryNames && probaName[2] === "B"
|
|
270
|
+
? "\\overline{A}"
|
|
271
|
+
: probaName[2];
|
|
272
|
+
return `La probabilité $${trueProbaName}$ se lit sur la branche menant à l'événement $${trueEvent}$.`;
|
|
273
|
+
}
|
|
274
|
+
case "inversion": {
|
|
275
|
+
const splitted = probaName
|
|
276
|
+
.replaceAll("(", "")
|
|
277
|
+
.replaceAll(")", "")
|
|
278
|
+
.split("_")[1];
|
|
279
|
+
const under = splitted[0];
|
|
280
|
+
const trueUnder = useContraryNames
|
|
281
|
+
? under === "C"
|
|
282
|
+
? "B"
|
|
283
|
+
: "\\overline{B}"
|
|
284
|
+
: under;
|
|
285
|
+
const over = splitted[1];
|
|
286
|
+
const trueOver = useContraryNames && over === "B" ? "\\overline{A}" : over;
|
|
287
|
+
return `La probabilité $${trueProbaName}$ est la probabilité de $${trueOver}$ sachant $${trueUnder}$.
|
|
288
|
+
|
|
289
|
+
Pour la déterminer, tu peux revenir à la définition d'une probabilité conditionnelle : pour deux évenements $M$ et $N$, on a :
|
|
290
|
+
|
|
291
|
+
$$
|
|
292
|
+
P_M(N) = \\frac{P(M \\cap N)}{P(M)}
|
|
293
|
+
$$
|
|
294
|
+
`;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
};
|
|
298
|
+
const getCorrection = (identifiers) => {
|
|
299
|
+
const { probaName } = identifiers;
|
|
300
|
+
const probas = buildAll(identifiers);
|
|
301
|
+
const type = getProbaType(identifiers);
|
|
302
|
+
const trueProbaName = getTrueProbaName(identifiers);
|
|
303
|
+
const { useContraryNames } = identifiers;
|
|
304
|
+
switch (type) {
|
|
305
|
+
case "conditionnelle": {
|
|
306
|
+
const splitted = probaName
|
|
307
|
+
.replaceAll("(", "")
|
|
308
|
+
.replaceAll(")", "")
|
|
309
|
+
.split("_")[1];
|
|
310
|
+
const under = splitted[0];
|
|
311
|
+
const trueUnder = useContraryNames && under === "B" ? "\\overline{A}" : under;
|
|
312
|
+
const over = splitted[1];
|
|
313
|
+
const trueOver = useContraryNames
|
|
314
|
+
? over === "C"
|
|
315
|
+
? "B"
|
|
316
|
+
: "\\overline{B}"
|
|
317
|
+
: over;
|
|
318
|
+
return `La probabilité $${trueProbaName}$ est la probabilité de $${trueOver}$ sachant $${trueUnder}$.
|
|
319
|
+
|
|
320
|
+
Dans l'arbre, elle se lit sur la branche partant de $${trueUnder}$ et allant jusqu'à $${trueOver}$.
|
|
321
|
+
|
|
322
|
+
On a donc :
|
|
323
|
+
|
|
324
|
+
$$
|
|
325
|
+
${trueProbaName} = ${getAnswer(identifiers)}
|
|
326
|
+
$$`;
|
|
327
|
+
}
|
|
328
|
+
case "inter": {
|
|
329
|
+
const [first, second] = probaName
|
|
330
|
+
.replaceAll("P(", "")
|
|
331
|
+
.replaceAll(")", "")
|
|
332
|
+
.split("\\cap ");
|
|
333
|
+
const firstProba = first === "A" ? probas.pA : probas.pB;
|
|
334
|
+
const secondProba = second === "C"
|
|
335
|
+
? first === "A"
|
|
336
|
+
? probas.pAC
|
|
337
|
+
: probas.pBC
|
|
338
|
+
: first === "A"
|
|
339
|
+
? probas.pAD
|
|
340
|
+
: probas.pBD;
|
|
341
|
+
const trueFirst = useContraryNames && first === "B" ? "\\overline{A}" : first;
|
|
342
|
+
const secondFirst = useContraryNames
|
|
343
|
+
? second === "C"
|
|
344
|
+
? "B"
|
|
345
|
+
: "\\overline{B}"
|
|
346
|
+
: second;
|
|
347
|
+
return `La probabilité $${trueProbaName}$ est la probabilité d'une intersection.
|
|
348
|
+
|
|
349
|
+
Pour la calculer, il faut multiplier les probabilités présentes sur les branches suivant le chemin $${trueFirst}$ puis $${secondFirst}$.
|
|
350
|
+
|
|
351
|
+
On a donc :
|
|
352
|
+
|
|
353
|
+
$$
|
|
354
|
+
${trueProbaName} = ${multiply(firstProba, secondProba).toSimplificationTex()}
|
|
355
|
+
$$
|
|
356
|
+
`;
|
|
357
|
+
}
|
|
358
|
+
case "totale": {
|
|
359
|
+
const evenement = probaName[2];
|
|
360
|
+
const trueEvenement = useContraryNames
|
|
361
|
+
? evenement === "C"
|
|
362
|
+
? "B"
|
|
363
|
+
: "\\overline{B}"
|
|
364
|
+
: evenement;
|
|
365
|
+
const first = evenement === "C" ? probas.pAC : probas.pAD;
|
|
366
|
+
const second = evenement === "C" ? probas.pBC : probas.pBD;
|
|
367
|
+
const firstWay = multiply(probas.pA, first);
|
|
368
|
+
const secondWay = multiply(probas.pB, second);
|
|
369
|
+
return `Il y a plusieurs chemins qui mènent à l'événement $${trueEvenement}$ : le chemin de l'intersection $A\\cap ${trueEvenement}$ et celui de l'intersection $${useContraryNames ? "\\overline{A}" : "B"}\\cap ${trueEvenement}$. La probabilité $${trueProbaName}$ est la somme des probabilités de ces chemins.
|
|
370
|
+
|
|
371
|
+
On a :
|
|
372
|
+
|
|
373
|
+
$$
|
|
374
|
+
P(A\\cap ${trueEvenement}) = ${firstWay.toSimplificationTex()}
|
|
375
|
+
$$
|
|
376
|
+
|
|
377
|
+
et
|
|
378
|
+
|
|
379
|
+
$$
|
|
380
|
+
P(${useContraryNames ? "\\overline{A}" : "B"}\\cap ${trueEvenement}) = ${secondWay.toSimplificationTex()}
|
|
381
|
+
$$
|
|
382
|
+
|
|
383
|
+
Donc :
|
|
384
|
+
|
|
385
|
+
$$
|
|
386
|
+
${trueProbaName} = ${add(firstWay.simplify(), secondWay.simplify()).toSimplificationTex()}
|
|
387
|
+
$$
|
|
388
|
+
`;
|
|
389
|
+
}
|
|
390
|
+
case "simple": {
|
|
391
|
+
const trueEvent = useContraryNames && probaName[2] === "B"
|
|
392
|
+
? "\\overline{A}"
|
|
393
|
+
: probaName[2];
|
|
394
|
+
return `La probabilité $${trueProbaName}$ se lit sur la branche menant à l'événement $${trueEvent}$.
|
|
395
|
+
|
|
396
|
+
On a donc :
|
|
397
|
+
|
|
398
|
+
$$
|
|
399
|
+
${trueProbaName} = ${getAnswer(identifiers)}
|
|
400
|
+
$$`;
|
|
401
|
+
}
|
|
402
|
+
case "inversion": {
|
|
403
|
+
const splitted = probaName
|
|
404
|
+
.replaceAll("(", "")
|
|
405
|
+
.replaceAll(")", "")
|
|
406
|
+
.split("_")[1];
|
|
407
|
+
const under = splitted[0];
|
|
408
|
+
const trueUnder = useContraryNames
|
|
409
|
+
? under === "C"
|
|
410
|
+
? "B"
|
|
411
|
+
: "\\overline{B}"
|
|
412
|
+
: under;
|
|
413
|
+
const over = splitted[1];
|
|
414
|
+
const trueOver = useContraryNames && over === "B" ? "\\overline{A}" : over;
|
|
415
|
+
const total = add(multiply(probas.pA, under === "C" ? probas.pAC : probas.pAD), multiply(probas.pB, under === "C" ? probas.pBC : probas.pBD));
|
|
416
|
+
const inter = multiply(over === "A" ? probas.pA : probas.pB, under === "C"
|
|
417
|
+
? over === "A"
|
|
418
|
+
? probas.pAC
|
|
419
|
+
: probas.pBC
|
|
420
|
+
: over === "A"
|
|
421
|
+
? probas.pAD
|
|
422
|
+
: probas.pBD);
|
|
423
|
+
return `La probabilité $${trueProbaName}$ est la probabilité de $${trueOver}$ sachant $${trueUnder}$.
|
|
424
|
+
|
|
425
|
+
Pour la déterminer, on revient à la définition d'une probabilité conditionnelle :
|
|
426
|
+
|
|
427
|
+
$$
|
|
428
|
+
${trueProbaName} = \\frac{P(${trueOver} \\cap ${trueUnder})}{P(${trueUnder})}
|
|
429
|
+
$$
|
|
430
|
+
|
|
431
|
+
On calcule donc d'abord $P(${trueOver} \\cap ${trueUnder})$ :
|
|
432
|
+
|
|
433
|
+
$$
|
|
434
|
+
P(${trueOver} \\cap ${trueUnder}) = ${inter.toSimplificationTex()}
|
|
435
|
+
$$
|
|
436
|
+
|
|
437
|
+
Puis on calcule la probabilité totale $P(${trueUnder})$ :
|
|
438
|
+
|
|
439
|
+
$$
|
|
440
|
+
P(${trueUnder})=${total.toSimplificationTex()}
|
|
441
|
+
$$
|
|
442
|
+
|
|
443
|
+
On a donc :
|
|
444
|
+
|
|
445
|
+
$$
|
|
446
|
+
${trueProbaName} = ${frac(inter.simplify(), total.simplify()).toSimplificationTex()}
|
|
447
|
+
$$
|
|
448
|
+
`;
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
};
|
|
452
|
+
const getQuestionFromIdentifiers = (identifiers, opts) => {
|
|
453
|
+
const question = {
|
|
454
|
+
instruction: getInstruction(identifiers, opts),
|
|
455
|
+
startStatement: getStartStatement(identifiers, opts),
|
|
456
|
+
answer: getAnswer(identifiers, opts),
|
|
457
|
+
keys: [],
|
|
458
|
+
answerFormat: "tex",
|
|
459
|
+
identifiers,
|
|
460
|
+
hint: getHint(identifiers, opts),
|
|
461
|
+
correction: getCorrection(identifiers, opts),
|
|
462
|
+
};
|
|
463
|
+
return question;
|
|
464
|
+
};
|
|
465
|
+
const getPropositions = (n, { answer, ...identifiers }) => {
|
|
466
|
+
const propositions = [];
|
|
467
|
+
addValidProp(propositions, answer);
|
|
468
|
+
const answerNode = getAnswerNode(identifiers);
|
|
469
|
+
propWhile(propositions, n, () => {
|
|
470
|
+
const wrongAnswer = multiply(answerNode, randint(2, 11)).simplify();
|
|
471
|
+
tryToAddWrongProp(propositions, wrongAnswer.toTex());
|
|
472
|
+
});
|
|
473
|
+
return shuffle(propositions);
|
|
474
|
+
};
|
|
475
|
+
const isAnswerValid = (ans, { answer }, opts) => {
|
|
476
|
+
try {
|
|
477
|
+
const rank = opts?.allowApproximate
|
|
478
|
+
? ["dixième", "centième", "millième"].indexOf(opts.allowApproximate) + 1
|
|
479
|
+
: undefined;
|
|
480
|
+
return rationalVEA(ans, answer, {
|
|
481
|
+
allowNonIrreductible: true,
|
|
482
|
+
allowDecimal: true,
|
|
483
|
+
decimalPrecision: rank,
|
|
484
|
+
});
|
|
485
|
+
}
|
|
486
|
+
catch (err) {
|
|
487
|
+
return handleVEAError(err);
|
|
488
|
+
}
|
|
489
|
+
};
|
|
490
|
+
const options = [
|
|
491
|
+
{
|
|
492
|
+
id: "allowApproximate",
|
|
493
|
+
label: "Autoriser les valeurs approchées au : ",
|
|
494
|
+
target: GeneratorOptionTarget.vea,
|
|
495
|
+
type: GeneratorOptionType.select,
|
|
496
|
+
defaultValue: "centième",
|
|
497
|
+
values: ["dixième", "centième", "millième"],
|
|
498
|
+
},
|
|
499
|
+
{
|
|
500
|
+
id: "eventTypes",
|
|
501
|
+
label: "Types de questions",
|
|
502
|
+
target: GeneratorOptionTarget.generation,
|
|
503
|
+
type: GeneratorOptionType.multiselect,
|
|
504
|
+
defaultValue: defaultOptionValues,
|
|
505
|
+
values: optionValues,
|
|
506
|
+
},
|
|
507
|
+
{
|
|
508
|
+
id: "probaType",
|
|
509
|
+
label: "Format des probabilités",
|
|
510
|
+
target: GeneratorOptionTarget.generation,
|
|
511
|
+
type: GeneratorOptionType.select,
|
|
512
|
+
defaultValue: "Fractions",
|
|
513
|
+
values: ["Fractions", "Décimales"],
|
|
514
|
+
},
|
|
515
|
+
{
|
|
516
|
+
id: "eventsNames",
|
|
517
|
+
label: "Noms des événements",
|
|
518
|
+
target: GeneratorOptionTarget.generation,
|
|
519
|
+
type: GeneratorOptionType.select,
|
|
520
|
+
defaultValue: "Événements et leur contraire",
|
|
521
|
+
values: [
|
|
522
|
+
"Événements et leur contraire",
|
|
523
|
+
"Noms d'événements tous différents",
|
|
524
|
+
],
|
|
525
|
+
},
|
|
526
|
+
];
|
|
527
|
+
const partialOptions = options.filter((p) => p.id !== "eventTypes");
|
|
528
|
+
export const probabilityTree = {
|
|
529
|
+
id: "probabilityTree",
|
|
530
|
+
connector: "=",
|
|
531
|
+
label: "Calculer une probabilité dans un arbre pondéré (tous calculs)",
|
|
532
|
+
isSingleStep: false,
|
|
533
|
+
generator: (nb, opts) => getDistinctQuestions(() => getProbabilityTree(opts), nb),
|
|
534
|
+
qcmTimer: 60,
|
|
535
|
+
freeTimer: 60,
|
|
536
|
+
getPropositions,
|
|
537
|
+
isAnswerValid,
|
|
538
|
+
subject: "Mathématiques",
|
|
539
|
+
options,
|
|
540
|
+
getQuestionFromIdentifiers,
|
|
541
|
+
hasHintAndCorrection: true,
|
|
542
|
+
};
|
|
543
|
+
export const probabilityTreeIntersection = {
|
|
544
|
+
id: "probabilityTreeIntersection",
|
|
545
|
+
connector: "=",
|
|
546
|
+
label: "Calculer une intersection dans un arbre pondéré",
|
|
547
|
+
isSingleStep: false,
|
|
548
|
+
generator: (nb, opts) => getDistinctQuestions(() => getProbabilityTree({
|
|
549
|
+
eventTypes: ["Probabilité d'intersection $P(A\\cap C)$"],
|
|
550
|
+
allowApproximate: opts?.allowApproximate,
|
|
551
|
+
probaType: opts?.probaType,
|
|
552
|
+
eventsNames: opts?.eventsNames,
|
|
553
|
+
}), nb),
|
|
554
|
+
qcmTimer: 60,
|
|
555
|
+
freeTimer: 60,
|
|
556
|
+
getPropositions,
|
|
557
|
+
isAnswerValid,
|
|
558
|
+
subject: "Mathématiques",
|
|
559
|
+
options: partialOptions,
|
|
560
|
+
getQuestionFromIdentifiers,
|
|
561
|
+
hasHintAndCorrection: true,
|
|
562
|
+
};
|
|
563
|
+
export const probabilityTreeTotalProbability = {
|
|
564
|
+
id: "probabilityTreeTotalProbability",
|
|
565
|
+
connector: "=",
|
|
566
|
+
label: "Calculer une probabilité totale dans un arbre pondéré",
|
|
567
|
+
isSingleStep: false,
|
|
568
|
+
generator: (nb, opts) => getDistinctQuestions(() => getProbabilityTree({
|
|
569
|
+
eventTypes: ["Probabilité totale $P(C)$"],
|
|
570
|
+
allowApproximate: opts?.allowApproximate,
|
|
571
|
+
probaType: opts?.probaType,
|
|
572
|
+
eventsNames: opts?.eventsNames,
|
|
573
|
+
}), nb),
|
|
574
|
+
qcmTimer: 60,
|
|
575
|
+
freeTimer: 60,
|
|
576
|
+
getPropositions,
|
|
577
|
+
isAnswerValid,
|
|
578
|
+
subject: "Mathématiques",
|
|
579
|
+
options: partialOptions,
|
|
580
|
+
getQuestionFromIdentifiers,
|
|
581
|
+
hasHintAndCorrection: true,
|
|
582
|
+
};
|
|
583
|
+
export const probabilityTreeReadProbability = {
|
|
584
|
+
id: "probabilityTreeReadProbability",
|
|
585
|
+
connector: "=",
|
|
586
|
+
label: "Lire une probabilité dans un arbre pondéré",
|
|
587
|
+
isSingleStep: false,
|
|
588
|
+
generator: (nb, opts) => getDistinctQuestions(() => getProbabilityTree({
|
|
589
|
+
eventTypes: [
|
|
590
|
+
"Probabilité conditionnelle $P_B(A)$",
|
|
591
|
+
"Probabilité 'simple' $P(A)$",
|
|
592
|
+
],
|
|
593
|
+
allowApproximate: opts?.allowApproximate,
|
|
594
|
+
probaType: opts?.probaType,
|
|
595
|
+
eventsNames: opts?.eventsNames,
|
|
596
|
+
}), nb),
|
|
597
|
+
qcmTimer: 60,
|
|
598
|
+
freeTimer: 60,
|
|
599
|
+
getPropositions,
|
|
600
|
+
isAnswerValid,
|
|
601
|
+
subject: "Mathématiques",
|
|
602
|
+
options: partialOptions,
|
|
603
|
+
getQuestionFromIdentifiers,
|
|
604
|
+
hasHintAndCorrection: true,
|
|
605
|
+
};
|
|
606
|
+
export const probabilityTreeInversionProbability = {
|
|
607
|
+
id: "probabilityTreeInversionProbability",
|
|
608
|
+
connector: "=",
|
|
609
|
+
label: "Calculer une probabilité d'inversion de causalité du type $P_B(A)$ dans un arbre pondéré",
|
|
610
|
+
isSingleStep: false,
|
|
611
|
+
generator: (nb, opts) => getDistinctQuestions(() => getProbabilityTree({
|
|
612
|
+
eventTypes: ["Probabilité d'inversion de causalité $P_B(A)$"],
|
|
613
|
+
allowApproximate: opts?.allowApproximate,
|
|
614
|
+
probaType: opts?.probaType,
|
|
615
|
+
eventsNames: opts?.eventsNames,
|
|
616
|
+
}), nb),
|
|
617
|
+
qcmTimer: 60,
|
|
618
|
+
freeTimer: 60,
|
|
619
|
+
getPropositions,
|
|
620
|
+
isAnswerValid,
|
|
621
|
+
subject: "Mathématiques",
|
|
622
|
+
options: partialOptions,
|
|
623
|
+
getQuestionFromIdentifiers,
|
|
624
|
+
hasHintAndCorrection: true,
|
|
625
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Exercise } from "../../../../exercises/exercise.js";
|
|
2
|
+
type TreeDiagram = string[][][][];
|
|
3
|
+
type Identifiers = {
|
|
4
|
+
initTree: TreeDiagram;
|
|
5
|
+
answerTree: TreeDiagram;
|
|
6
|
+
};
|
|
7
|
+
export declare const treeInAnswer: Exercise<Identifiers>;
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=treeInAnswer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"treeInAnswer.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/probaStat/trees/treeInAnswer.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAST,MAAM,6BAA6B,CAAC;AAOrC,KAAK,WAAW,GAAG,MAAM,EAAE,EAAE,EAAE,EAAE,CAAC;AAElC,KAAK,WAAW,GAAG;IACjB,QAAQ,EAAE,WAAW,CAAC;IACtB,UAAU,EAAE,WAAW,CAAC;CACzB,CAAC;AAyGF,eAAO,MAAM,YAAY,EAAE,QAAQ,CAAC,WAAW,CAgB9C,CAAC"}
|