math-exercises 3.0.198 → 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.
Files changed (152) hide show
  1. package/lib/exercises/exercise.d.ts +14 -1
  2. package/lib/exercises/exercise.d.ts.map +1 -1
  3. package/lib/exercises/math/_debug/debugReorder1.d.ts +8 -0
  4. package/lib/exercises/math/_debug/debugReorder1.d.ts.map +1 -0
  5. package/lib/exercises/math/_debug/debugReorder1.js +81 -0
  6. package/lib/exercises/math/_debug/debugReorder2.d.ts +10 -0
  7. package/lib/exercises/math/_debug/debugReorder2.d.ts.map +1 -0
  8. package/lib/exercises/math/_debug/debugReorder2.js +88 -0
  9. package/lib/exercises/math/_debug/debugReorder3.d.ts +10 -0
  10. package/lib/exercises/math/_debug/debugReorder3.d.ts.map +1 -0
  11. package/lib/exercises/math/_debug/debugReorder3.js +81 -0
  12. package/lib/exercises/math/_debug/index.d.ts +3 -1
  13. package/lib/exercises/math/_debug/index.d.ts.map +1 -1
  14. package/lib/exercises/math/_debug/index.js +3 -1
  15. package/lib/exercises/math/calcul/factorial/index.d.ts +2 -0
  16. package/lib/exercises/math/calcul/factorial/index.d.ts.map +1 -0
  17. package/lib/exercises/math/calcul/factorial/index.js +1 -0
  18. package/lib/exercises/math/calcul/factorial/simplifyQuotientOfFactorialToProduct.d.ts +8 -0
  19. package/lib/exercises/math/calcul/factorial/simplifyQuotientOfFactorialToProduct.d.ts.map +1 -0
  20. package/lib/exercises/math/calcul/factorial/simplifyQuotientOfFactorialToProduct.js +199 -0
  21. package/lib/exercises/math/calculLitteral/equation/exp/expOfTrinomEquals1Equation.d.ts.map +1 -1
  22. package/lib/exercises/math/calculLitteral/equation/exp/expOfTrinomEquals1Equation.js +3 -0
  23. package/lib/exercises/math/calculLitteral/inequations/firstDegreeInequationsType3.d.ts.map +1 -1
  24. package/lib/exercises/math/calculLitteral/inequations/firstDegreeInequationsType3.js +58 -30
  25. package/lib/exercises/math/combinatory/combination/index.d.ts +3 -0
  26. package/lib/exercises/math/combinatory/combination/index.d.ts.map +1 -0
  27. package/lib/exercises/math/combinatory/combination/index.js +2 -0
  28. package/lib/exercises/math/combinatory/combination/mentalCalculateCombination.d.ts +11 -0
  29. package/lib/exercises/math/combinatory/combination/mentalCalculateCombination.d.ts.map +1 -0
  30. package/lib/exercises/math/combinatory/combination/mentalCalculateCombination.js +225 -0
  31. package/lib/exercises/math/combinatory/combination/writeCombinationFormulaUsingFactorial.d.ts +13 -0
  32. package/lib/exercises/math/combinatory/combination/writeCombinationFormulaUsingFactorial.d.ts.map +1 -0
  33. package/lib/exercises/math/combinatory/combination/writeCombinationFormulaUsingFactorial.js +285 -0
  34. package/lib/exercises/math/complex/addComplex.d.ts.map +1 -1
  35. package/lib/exercises/math/complex/addComplex.js +53 -7
  36. package/lib/exercises/math/complex/conjugateComplex.d.ts.map +1 -1
  37. package/lib/exercises/math/complex/conjugateComplex.js +48 -7
  38. package/lib/exercises/math/complex/mutiplyComplex.d.ts.map +1 -1
  39. package/lib/exercises/math/complex/mutiplyComplex.js +51 -18
  40. package/lib/exercises/math/complex/reAndIm.d.ts.map +1 -1
  41. package/lib/exercises/math/complex/reAndIm.js +35 -4
  42. package/lib/exercises/math/dataRepresentations/scatterPlot/scatterPlotInterpreting.d.ts.map +1 -1
  43. package/lib/exercises/math/dataRepresentations/scatterPlot/scatterPlotInterpreting.js +1 -1
  44. package/lib/exercises/math/derivation/derivative/trigo/cosSecondDegreeDerivative.d.ts.map +1 -1
  45. package/lib/exercises/math/derivation/derivative/trigo/cosSecondDegreeDerivative.js +47 -3
  46. package/lib/exercises/math/derivation/derivative/trigo/productOfSinAXPlusBCosCXPlusDDerivative.d.ts +9 -0
  47. package/lib/exercises/math/derivation/derivative/trigo/productOfSinAXPlusBCosCXPlusDDerivative.d.ts.map +1 -0
  48. package/lib/exercises/math/derivation/derivative/trigo/productOfSinAXPlusBCosCXPlusDDerivative.js +209 -0
  49. package/lib/exercises/math/derivation/derivative/trigo/sinAndCosMixedWithSquareDerivative.d.ts +9 -0
  50. package/lib/exercises/math/derivation/derivative/trigo/sinAndCosMixedWithSquareDerivative.d.ts.map +1 -0
  51. package/lib/exercises/math/derivation/derivative/trigo/sinAndCosMixedWithSquareDerivative.js +359 -0
  52. package/lib/exercises/math/derivation/derivative/trigo/sinCosDerivativeRewriteUsingCos2PlusSin2Equals1.d.ts +11 -0
  53. package/lib/exercises/math/derivation/derivative/trigo/sinCosDerivativeRewriteUsingCos2PlusSin2Equals1.d.ts.map +1 -0
  54. package/lib/exercises/math/derivation/derivative/trigo/sinCosDerivativeRewriteUsingCos2PlusSin2Equals1.js +445 -0
  55. package/lib/exercises/math/functions/affines/affineVarTableOnBoundedInterval.d.ts.map +1 -1
  56. package/lib/exercises/math/functions/affines/affineVarTableOnBoundedInterval.js +2 -3
  57. package/lib/exercises/math/functions/exponential/sign/expFunctionBasicSign.d.ts.map +1 -1
  58. package/lib/exercises/math/functions/exponential/sign/expFunctionBasicSign.js +3 -0
  59. package/lib/exercises/math/functions/sign/affineProductSign.d.ts.map +1 -1
  60. package/lib/exercises/math/functions/sign/affineProductSign.js +0 -4
  61. package/lib/exercises/math/index.d.ts +1 -0
  62. package/lib/exercises/math/index.d.ts.map +1 -1
  63. package/lib/exercises/math/index.js +1 -1
  64. package/lib/exercises/math/limits/sequenceGeometricLimit.d.ts.map +1 -1
  65. package/lib/exercises/math/limits/sequenceGeometricLimit.js +9 -0
  66. package/lib/exercises/math/primitive/constantPrimitive.d.ts +8 -5
  67. package/lib/exercises/math/primitive/constantPrimitive.d.ts.map +1 -1
  68. package/lib/exercises/math/primitive/constantPrimitive.js +40 -21
  69. package/lib/exercises/math/probaStat/stats2var/averagePoint.d.ts.map +1 -1
  70. package/lib/exercises/math/probaStat/stats2var/averagePoint.js +34 -2
  71. package/lib/exercises/math/sequences/geometric/graph/geometricFindThresholdFromGraph.d.ts +15 -0
  72. package/lib/exercises/math/sequences/geometric/graph/geometricFindThresholdFromGraph.d.ts.map +1 -0
  73. package/lib/exercises/math/sequences/geometric/graph/geometricFindThresholdFromGraph.js +255 -0
  74. package/lib/exercises/math/sequences/geometric/graph/geometricFindThresholdUsingCalculator.d.ts +15 -0
  75. package/lib/exercises/math/sequences/geometric/graph/geometricFindThresholdUsingCalculator.d.ts.map +1 -0
  76. package/lib/exercises/math/sequences/geometric/graph/geometricFindThresholdUsingCalculator.js +242 -0
  77. package/lib/exercises/math/sequences/geometric/graph/geometricPlaceFirstPoints.js +4 -4
  78. package/lib/exercises/math/sequences/geometric/graph/geometricSignOfReasonFromGraph.d.ts +12 -0
  79. package/lib/exercises/math/sequences/geometric/graph/geometricSignOfReasonFromGraph.d.ts.map +1 -0
  80. package/lib/exercises/math/sequences/geometric/graph/geometricSignOfReasonFromGraph.js +161 -0
  81. package/lib/exercises/math/sets/cartesianProduct/findCardinalOfCartesianProductOfFiniteSets.d.ts +10 -0
  82. package/lib/exercises/math/sets/cartesianProduct/findCardinalOfCartesianProductOfFiniteSets.d.ts.map +1 -0
  83. package/lib/exercises/math/sets/cartesianProduct/findCardinalOfCartesianProductOfFiniteSets.js +224 -0
  84. package/lib/exercises/math/sets/cartesianProduct/findCardinalOfCartesianProductOfFiniteSetsFromSituation.d.ts +18 -0
  85. package/lib/exercises/math/sets/cartesianProduct/findCardinalOfCartesianProductOfFiniteSetsFromSituation.d.ts.map +1 -0
  86. package/lib/exercises/math/sets/cartesianProduct/findCardinalOfCartesianProductOfFiniteSetsFromSituation.js +198 -0
  87. package/lib/exercises/math/sets/cartesianProduct/findCardinalOfPowEK.d.ts +10 -0
  88. package/lib/exercises/math/sets/cartesianProduct/findCardinalOfPowEK.d.ts.map +1 -0
  89. package/lib/exercises/math/sets/cartesianProduct/findCardinalOfPowEK.js +231 -0
  90. package/lib/exercises/math/sets/cartesianProduct/findNumberOfPasswordsWithLettersAndNumbers.d.ts +19 -0
  91. package/lib/exercises/math/sets/cartesianProduct/findNumberOfPasswordsWithLettersAndNumbers.d.ts.map +1 -0
  92. package/lib/exercises/math/sets/cartesianProduct/findNumberOfPasswordsWithLettersAndNumbers.js +187 -0
  93. package/lib/exercises/math/sets/cartesianProduct/index.d.ts +7 -0
  94. package/lib/exercises/math/sets/cartesianProduct/index.d.ts.map +1 -0
  95. package/lib/exercises/math/sets/cartesianProduct/index.js +6 -0
  96. package/lib/exercises/math/sets/cartesianProduct/proposeElementInCartesianProductOfFiniteSets.d.ts +15 -0
  97. package/lib/exercises/math/sets/cartesianProduct/proposeElementInCartesianProductOfFiniteSets.d.ts.map +1 -0
  98. package/lib/exercises/math/sets/cartesianProduct/proposeElementInCartesianProductOfFiniteSets.js +291 -0
  99. package/lib/exercises/math/sets/cartesianProduct/proposeElementInPowEK.d.ts +15 -0
  100. package/lib/exercises/math/sets/cartesianProduct/proposeElementInPowEK.d.ts.map +1 -0
  101. package/lib/exercises/math/sets/cartesianProduct/proposeElementInPowEK.js +274 -0
  102. package/lib/exercises/math/sets/combinations/findNumberOfCombinationsFromSituation.d.ts +17 -0
  103. package/lib/exercises/math/sets/combinations/findNumberOfCombinationsFromSituation.d.ts.map +1 -0
  104. package/lib/exercises/math/sets/combinations/findNumberOfCombinationsFromSituation.js +228 -0
  105. package/lib/exercises/math/sets/combinations/findNumberOfProductsOfCombinationsFromSituation.d.ts +17 -0
  106. package/lib/exercises/math/sets/combinations/findNumberOfProductsOfCombinationsFromSituation.d.ts.map +1 -0
  107. package/lib/exercises/math/sets/combinations/findNumberOfProductsOfCombinationsFromSituation.js +388 -0
  108. package/lib/exercises/math/sets/combinations/index.d.ts +4 -0
  109. package/lib/exercises/math/sets/combinations/index.d.ts.map +1 -0
  110. package/lib/exercises/math/sets/combinations/index.js +3 -0
  111. package/lib/exercises/math/sets/combinations/proposeCombination.d.ts +15 -0
  112. package/lib/exercises/math/sets/combinations/proposeCombination.d.ts.map +1 -0
  113. package/lib/exercises/math/sets/combinations/proposeCombination.js +347 -0
  114. package/lib/exercises/math/sets/partialPermutations/findNumberOfPartialPermutationsFromSituation.d.ts +16 -0
  115. package/lib/exercises/math/sets/partialPermutations/findNumberOfPartialPermutationsFromSituation.d.ts.map +1 -0
  116. package/lib/exercises/math/sets/partialPermutations/findNumberOfPartialPermutationsFromSituation.js +186 -0
  117. package/lib/exercises/math/sets/partialPermutations/findNumberOfPermutationsFromSituation.d.ts +17 -0
  118. package/lib/exercises/math/sets/partialPermutations/findNumberOfPermutationsFromSituation.d.ts.map +1 -0
  119. package/lib/exercises/math/sets/partialPermutations/findNumberOfPermutationsFromSituation.js +232 -0
  120. package/lib/exercises/math/sets/partialPermutations/index.d.ts +4 -0
  121. package/lib/exercises/math/sets/partialPermutations/index.d.ts.map +1 -0
  122. package/lib/exercises/math/sets/partialPermutations/index.js +3 -0
  123. package/lib/exercises/math/sets/partialPermutations/proposePartialPermutation.d.ts +15 -0
  124. package/lib/exercises/math/sets/partialPermutations/proposePartialPermutation.d.ts.map +1 -0
  125. package/lib/exercises/math/sets/partialPermutations/proposePartialPermutation.js +343 -0
  126. package/lib/exercises/math/spaceGeometry/vectors/spaceVectorLinearCombinationCoords.d.ts.map +1 -1
  127. package/lib/exercises/math/trigonometry/functions/parityOfCosAXTimesSinBX.d.ts +8 -0
  128. package/lib/exercises/math/trigonometry/functions/parityOfCosAXTimesSinBX.d.ts.map +1 -0
  129. package/lib/exercises/math/trigonometry/functions/parityOfCosAXTimesSinBX.js +193 -0
  130. package/lib/index.d.ts +15 -1
  131. package/lib/index.d.ts.map +1 -1
  132. package/lib/math/sets/setOperations.d.ts +9 -0
  133. package/lib/math/sets/setOperations.d.ts.map +1 -0
  134. package/lib/math/sets/setOperations.js +84 -0
  135. package/lib/math/sets/tuple.d.ts +12 -0
  136. package/lib/math/sets/tuple.d.ts.map +1 -0
  137. package/lib/math/sets/tuple.js +17 -0
  138. package/lib/server.js +28 -2
  139. package/lib/tests/pdfExo.test.js +2 -2
  140. package/lib/tests/pdfs/buildPDFForExercise.d.ts.map +1 -1
  141. package/lib/tests/pdfs/buildPDFForExercise.js +6 -0
  142. package/lib/tests/pdfs/quizPdfPreambule.d.ts.map +1 -1
  143. package/lib/tests/pdfs/quizPdfPreambule.js +1 -0
  144. package/lib/tests/pdfs/treeDiagramToLatex.d.ts +15 -0
  145. package/lib/tests/pdfs/treeDiagramToLatex.d.ts.map +1 -0
  146. package/lib/tests/pdfs/treeDiagramToLatex.js +49 -0
  147. package/lib/tests/questionTest.d.ts.map +1 -1
  148. package/lib/tests/questionTest.js +19 -0
  149. package/lib/tree/utilities/nodePrinter.d.ts +7 -0
  150. package/lib/tree/utilities/nodePrinter.d.ts.map +1 -0
  151. package/lib/tree/utilities/nodePrinter.js +36 -0
  152. package/package.json +1 -1
@@ -0,0 +1,347 @@
1
+ import { addValidProp, shuffleProps, tryToAddWrongProp, } from "../../../../exercises/exercise.js";
2
+ import { getDistinctQuestions } from "../../../../exercises/utils/getDistinctQuestions.js";
3
+ import { alignTex } from "../../../../utils/latex/alignTex.js";
4
+ import { parseAlgebraic } from "../../../../tree/parsers/latexParser.js";
5
+ import { handleVEAError } from "../../../../utils/errors/handleVEAError.js";
6
+ import { NodeConstructor, } from "../../../../tree/nodes/nodeConstructor.js";
7
+ import { DiscreteSetNode } from "../../../../tree/nodes/sets/discreteSetNode.js";
8
+ import { Tuple } from "../../../../math/sets/tuple.js";
9
+ import { isVariableNode, VariableNode, } from "../../../../tree/nodes/variables/variableNode.js";
10
+ import { NodeComparator } from "../../../../tree/utilities/nodeComparator.js";
11
+ import { randomCombinationFromDiscreteSet, randomManyCombinationsFromDiscreteSet, randomTupleInDiscreteSetPower, } from "../../../../math/sets/setOperations.js";
12
+ import { randint } from "../../../../math/utils/random/randint.js";
13
+ import { shuffle } from "../../../../utils/alea/shuffle.js";
14
+ import { coinFlip } from "../../../../utils/alea/coinFlip.js";
15
+ import { probaLawFlip } from "../../../../utils/alea/probaLawFlip.js";
16
+ import { randomMany } from "../../../../utils/alea/random.js";
17
+ const randomDiscreteSetIdsAndDescription = () => {
18
+ return probaLawFlip([
19
+ [
20
+ (() => {
21
+ const nbElements = randint(2, 5);
22
+ const arrLetter = shuffle(["a", "b", "c", "d"]).slice(0, nbElements);
23
+ const arrNode = arrLetter.map((letter) => new VariableNode(letter));
24
+ const nodeSetE = new DiscreteSetNode(arrNode);
25
+ return {
26
+ nodeIdsSetE: nodeSetE.toIdentifiers(),
27
+ strDescriptionE: `l'ensemble $${discreteSetNodeToTex(nodeSetE)}$`,
28
+ };
29
+ })(),
30
+ 0.3,
31
+ ],
32
+ [
33
+ (() => {
34
+ const nbElements = randint(2, 6);
35
+ const arrNumber = randomMany([...Array(9).keys()].map((i) => i + 1), nbElements);
36
+ const arrNode = shuffle(arrNumber.map((v) => v.toTree()));
37
+ const nodeSetE = new DiscreteSetNode(arrNode);
38
+ return {
39
+ nodeIdsSetE: nodeSetE.toIdentifiers(),
40
+ strDescriptionE: `l'ensemble $${discreteSetNodeToTex(nodeSetE)}$`,
41
+ };
42
+ })(),
43
+ 0.3,
44
+ ],
45
+ [
46
+ (() => {
47
+ const [boundLowRaw, boundHighRaw] = [randint(2, 8), randint(13, 19)];
48
+ const [isBoundLowIncluded, isBoundHighIncluded] = [0, 1].map(() => coinFlip());
49
+ const boundLow = boundLowRaw + (isBoundLowIncluded ? 0 : 1);
50
+ const boundHigh = boundHighRaw + (isBoundHighIncluded ? 0 : -1);
51
+ const arrNumber = [...Array(boundHigh - boundLow + 1).keys()].map((i) => i + boundLow);
52
+ const arrNode = arrNumber.map((v) => v.toTree());
53
+ const nodeSetE = new DiscreteSetNode(arrNode);
54
+ return {
55
+ nodeIdsSetE: nodeSetE.toIdentifiers(),
56
+ strDescriptionE: `l'ensemble des entiers compris entre $${boundLow}$ ${isBoundLowIncluded ? "inclus" : "exclu"} et $${boundHigh}$ ${isBoundHighIncluded ? "inclus" : "exclu"}`,
57
+ };
58
+ })(),
59
+ 0.2,
60
+ ],
61
+ [
62
+ (() => {
63
+ const isFilterEven = coinFlip();
64
+ const [boundLowRaw, boundHighRaw] = [randint(2, 8), randint(13, 19)];
65
+ const [isBoundLowIncluded, isBoundHighIncluded] = [0, 1].map(() => coinFlip());
66
+ const boundLow = boundLowRaw + (isBoundLowIncluded ? 0 : 1);
67
+ const boundHigh = boundHighRaw + (isBoundHighIncluded ? 0 : -1);
68
+ const arrNumber = [...Array(boundHigh - boundLow + 1).keys()]
69
+ .map((i) => i + boundLow)
70
+ .filter((v) => (isFilterEven ? v % 2 === 0 : v % 2 === 1));
71
+ const arrNode = arrNumber.map((v) => v.toTree());
72
+ const nodeSetE = new DiscreteSetNode(arrNode);
73
+ return {
74
+ nodeIdsSetE: nodeSetE.toIdentifiers(),
75
+ strDescriptionE: `l'ensemble des entiers ${isFilterEven ? "pairs" : "impairs"} compris entre $${boundLow}$ ${isBoundLowIncluded ? "inclus" : "exclu"} et $${boundHigh}$ ${isBoundHighIncluded ? "inclus" : "exclu"}`,
76
+ };
77
+ })(),
78
+ 0.2,
79
+ ],
80
+ ]);
81
+ };
82
+ /*
83
+ This toTex() function supports discreteSetNodes with variableNodes inside (this won't create unknown command \\lbracem if m is the first element)
84
+ */
85
+ const discreteSetNodeToTex = (discreteSetNode) => {
86
+ return `\\lbrace ${discreteSetNode.elements
87
+ .map((el) => el.toTex())
88
+ .join(";")} \\rbrace`;
89
+ };
90
+ const getInstruction = (identifiers) => {
91
+ const { strDescriptionE, k } = identifiers;
92
+ return `Soit $E$ ${strDescriptionE}.
93
+ Donner une combinaison de $${k}$ éléments de E.`;
94
+ };
95
+ const getAnswerStuff = (identifiers) => {
96
+ const { nodeIdsSetE, k } = identifiers;
97
+ const nodeSetE = NodeConstructor.fromIdentifiers(nodeIdsSetE);
98
+ const arrCombination = k <= nodeSetE.elements.length
99
+ ? randomManyCombinationsFromDiscreteSet(nodeSetE, k, 5)
100
+ : [];
101
+ return { arrCombination };
102
+ };
103
+ const getAnswer = (identifiers) => {
104
+ const { arrCombination } = getAnswerStuff(identifiers);
105
+ if (arrCombination.length === 0) {
106
+ return "\\text{Ce n'est pas possible.}";
107
+ }
108
+ else {
109
+ return arrCombination[0].toTex();
110
+ }
111
+ };
112
+ const getHint = (identifiers) => {
113
+ const { k } = identifiers;
114
+ return `Pour prendre une combinaison de $${k}$ éléments de $E$, il faut effectuer $${k}$ tirages simultanés d'un élement de $E$.
115
+ Il faut donc s'assurer que l'ensemble $E$ contient suffisament d'éléments pour former un $${k}$-uplet d'éléments distincts.
116
+
117
+ La combinaison se notera {élement tirage $1$ ; élement tirage $2$ ; élement tirage $3$ ; ...} (c'est un ensemble (l'ordre n'a pas d'importance)).`;
118
+ };
119
+ const getCorrection = (identifiers) => {
120
+ const { nodeIdsSetE, k } = identifiers;
121
+ const nodeSetE = NodeConstructor.fromIdentifiers(nodeIdsSetE);
122
+ const arrCombination = getAnswerStuff(identifiers).arrCombination;
123
+ return `
124
+ $$
125
+ E = ${discreteSetNodeToTex(nodeSetE)}
126
+ $$
127
+
128
+ ${(() => {
129
+ if (arrCombination.length === 0) {
130
+ return `On veut prendre $${k}$ éléments distincts dans un ensemble qui n'en contient que $${nodeSetE.elements.length}$.
131
+ Ce n'est pas possible.`;
132
+ }
133
+ else if (arrCombination.length === 1) {
134
+ return `Voici la seule combinaison à $${k}$ éléments de E :
135
+
136
+ ${alignTex(arrCombination.map((discreteSetNode) => [
137
+ discreteSetNodeToTex(discreteSetNode),
138
+ ]))}`;
139
+ }
140
+ else {
141
+ return `Voici quelques combinaisons à $${k}$ éléments de E :
142
+
143
+ ${alignTex(arrCombination.map((discreteSetNode) => [
144
+ discreteSetNodeToTex(discreteSetNode),
145
+ ]))}
146
+
147
+ Attention à ne pas confondre la notation d'un ensemble (entre accolades) et la notation d'un k-uplet (entre parenthèses).`;
148
+ }
149
+ })()}`;
150
+ };
151
+ const getPropositions = (n, { answer, ...identifiers }) => {
152
+ const { items } = identifiers;
153
+ const propositions = [];
154
+ items.map(({ str, isValid }) => {
155
+ if (isValid) {
156
+ addValidProp(propositions, str, "raw");
157
+ }
158
+ else {
159
+ tryToAddWrongProp(propositions, str, "raw");
160
+ }
161
+ });
162
+ return shuffleProps(propositions, n);
163
+ };
164
+ const getKeys = (identifiers) => {
165
+ const { nodeIdsSetE } = identifiers;
166
+ const nodeSetE = NodeConstructor.fromIdentifiers(nodeIdsSetE);
167
+ const arrVarNode = nodeSetE.elements.filter((node) => isVariableNode(node));
168
+ return [
169
+ "semicolon",
170
+ "lbrace",
171
+ "rbrace",
172
+ ...arrVarNode.map((varNode) => {
173
+ const tex = varNode.toTex();
174
+ return {
175
+ id: "custom",
176
+ label: tex,
177
+ labelType: "tex",
178
+ mathfieldInstructions: {
179
+ method: "write",
180
+ content: tex,
181
+ },
182
+ };
183
+ }),
184
+ {
185
+ id: "custom",
186
+ label: "\\text{Ce n'est pas possible.}",
187
+ labelType: "tex",
188
+ mathfieldInstructions: {
189
+ method: "write",
190
+ content: "\\text{Ce n'est pas possible.}",
191
+ },
192
+ },
193
+ ];
194
+ };
195
+ const isAnswerValid = (ans, { answer, ...identifiers }) => {
196
+ if (ans === answer) {
197
+ return true;
198
+ }
199
+ const { nodeIdsSetE, k } = identifiers;
200
+ const nodeSetE = NodeConstructor.fromIdentifiers(nodeIdsSetE);
201
+ function matchGroups(regex, input) {
202
+ const match = regex.exec(input);
203
+ return match?.groups || undefined;
204
+ }
205
+ try {
206
+ const tupleAns = (() => {
207
+ const arrKey = [...Array(k).keys()]
208
+ .map((i) => i + 1)
209
+ .map((v) => `str${v}`);
210
+ const strRegex = `^\\\\left\\(${arrKey
211
+ .map((strKey) => `(?<${strKey}>.*(?!;$))`)
212
+ .join(";")}\\\\right\\)$`;
213
+ const regex = new RegExp(strRegex);
214
+ const ansParts = matchGroups(regex, ans);
215
+ if (ansParts === undefined) {
216
+ throw new Error("Parsing error: ans is not a tuple");
217
+ }
218
+ const arrNode = Object.entries(ansParts).map(([_key, str]) => {
219
+ try {
220
+ return parseAlgebraic(str);
221
+ }
222
+ catch (_) {
223
+ return new VariableNode(str);
224
+ }
225
+ });
226
+ return new Tuple(arrNode);
227
+ })();
228
+ return NodeComparator.isTupleInCartesianProductOfDiscreteSets(tupleAns, [...Array(k).keys()].map(() => nodeSetE));
229
+ }
230
+ catch (err) {
231
+ return handleVEAError(err);
232
+ }
233
+ };
234
+ const getProposeCombinationQuestion = () => {
235
+ const k = randint(2, 6);
236
+ const dict = randomDiscreteSetIdsAndDescription();
237
+ const nodeSetE = NodeConstructor.fromIdentifiers(dict.nodeIdsSetE);
238
+ const items = (() => {
239
+ const _nbValid = 1;
240
+ const items = [
241
+ //valid: combination or "it's not possible"
242
+ (() => {
243
+ if (k <= nodeSetE.elements.length) {
244
+ const combination = randomCombinationFromDiscreteSet(nodeSetE, k);
245
+ return {
246
+ str: `$${combination.toTex()}$`,
247
+ isValid: true,
248
+ };
249
+ }
250
+ else {
251
+ return {
252
+ str: "Ce n'est pas possible.",
253
+ isValid: true,
254
+ };
255
+ }
256
+ })(),
257
+ //invalid: tuple with distinct
258
+ ...(() => {
259
+ if (k <= nodeSetE.elements.length) {
260
+ const tuple = randomTupleInDiscreteSetPower(nodeSetE, k, true);
261
+ return [
262
+ {
263
+ str: `$${tuple.toTex()}$`,
264
+ isValid: false,
265
+ },
266
+ ];
267
+ }
268
+ else {
269
+ return [];
270
+ }
271
+ })(),
272
+ //invalid: tuple with duplicate
273
+ (() => {
274
+ const tuple = randomTupleInDiscreteSetPower(nodeSetE, k, false, true);
275
+ return {
276
+ str: `$${tuple.toTex()}$`,
277
+ isValid: false,
278
+ };
279
+ })(),
280
+ //invalid: wrong cardinal
281
+ ...(() => {
282
+ if (k <= nodeSetE.elements.length) {
283
+ return [];
284
+ }
285
+ else {
286
+ const combination = randomCombinationFromDiscreteSet(nodeSetE, 1);
287
+ return [
288
+ {
289
+ str: `$${combination.toTex()}$`,
290
+ isValid: false,
291
+ },
292
+ ];
293
+ }
294
+ })(),
295
+ //invalid: "it's not possible" or contains duplicate
296
+ (() => {
297
+ if (k <= nodeSetE.elements.length) {
298
+ return {
299
+ str: "Ce n'est pas possible.",
300
+ isValid: false,
301
+ };
302
+ }
303
+ else {
304
+ const combination = randomCombinationFromDiscreteSet(nodeSetE, nodeSetE.elements.length);
305
+ return {
306
+ str: `$${combination.toTex()}$`,
307
+ isValid: false,
308
+ };
309
+ }
310
+ })(),
311
+ ];
312
+ return items;
313
+ })();
314
+ const identifiers = {
315
+ strDescriptionE: dict.strDescriptionE,
316
+ nodeIdsSetE: nodeSetE.toIdentifiers(),
317
+ k,
318
+ items,
319
+ };
320
+ return getQuestionFromIdentifiers(identifiers);
321
+ };
322
+ const getQuestionFromIdentifiers = (identifiers) => {
323
+ const question = {
324
+ instruction: getInstruction(identifiers),
325
+ answer: getAnswer(identifiers),
326
+ keys: getKeys(identifiers),
327
+ answerFormat: "tex",
328
+ identifiers,
329
+ hint: getHint(identifiers),
330
+ correction: getCorrection(identifiers),
331
+ };
332
+ return question;
333
+ };
334
+ export const proposeCombination = {
335
+ id: "proposeCombination",
336
+ connector: "=",
337
+ isSingleStep: true,
338
+ label: "Un ensemble $E$ étant donné, donner une combinaison de $k$ éléments de $E$",
339
+ generator: (nb) => getDistinctQuestions(getProposeCombinationQuestion, nb),
340
+ qcmTimer: 60,
341
+ freeTimer: 60,
342
+ getPropositions,
343
+ isAnswerValid,
344
+ subject: "Mathématiques",
345
+ hasHintAndCorrection: true,
346
+ getQuestionFromIdentifiers,
347
+ };
@@ -0,0 +1,16 @@
1
+ import { Exercise } from "../../../../exercises/exercise.js";
2
+ import { NodeIdentifiers } from "../../../../tree/nodes/nodeConstructor.js";
3
+ type Situation = {
4
+ strInstruction: string;
5
+ strCorrection: string;
6
+ dictSets: Record<string, {
7
+ value: number;
8
+ }>;
9
+ nodeIdsCardinal: NodeIdentifiers;
10
+ };
11
+ type Identifiers = {
12
+ situation: Situation;
13
+ };
14
+ export declare const findNumberOfPartialPermutationsFromSituation: Exercise<Identifiers>;
15
+ export {};
16
+ //# sourceMappingURL=findNumberOfPartialPermutationsFromSituation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"findNumberOfPartialPermutationsFromSituation.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/sets/partialPermutations/findNumberOfPartialPermutationsFromSituation.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAeT,MAAM,6BAA6B,CAAC;AAErC,OAAO,EAEL,eAAe,EAChB,MAAM,qCAAqC,CAAC;AAuD7C,KAAK,SAAS,GAAG;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC5C,eAAe,EAAE,eAAe,CAAC;CAClC,CAAC;AAqEF,KAAK,WAAW,GAAG;IACjB,SAAS,EAAE,SAAS,CAAC;CACtB,CAAC;AAsJF,eAAO,MAAM,4CAA4C,EAAE,QAAQ,CAAC,WAAW,CAmB5E,CAAC"}
@@ -0,0 +1,186 @@
1
+ import { addValidProp, shuffleProps, tryToAddWrongProp, } from "../../../../exercises/exercise.js";
2
+ import { getDistinctQuestions } from "../../../../exercises/utils/getDistinctQuestions.js";
3
+ import { NodeConstructor, } from "../../../../tree/nodes/nodeConstructor.js";
4
+ import { random } from "../../../../utils/alea/random.js";
5
+ import { randint } from "../../../../math/utils/random/randint.js";
6
+ import { frac, isFractionNode, } from "../../../../tree/nodes/operators/fractionNode.js";
7
+ import { facto } from "../../../../tree/nodes/functions/factorialNode.js";
8
+ import { substract } from "../../../../tree/nodes/operators/substractNode.js";
9
+ import { round } from "../../../../math/utils/round.js";
10
+ import { binom } from "../../../../tree/nodes/operators/binomialCoefficientNode.js";
11
+ import { power } from "../../../../tree/nodes/operators/powerNode.js";
12
+ import { handleVEAError } from "../../../../utils/errors/handleVEAError.js";
13
+ import { parseAlgebraic } from "../../../../tree/parsers/latexParser.js";
14
+ import { NodeComparator } from "../../../../tree/utilities/nodeComparator.js";
15
+ const situationTemplates = [
16
+ {
17
+ strInstruction: `Un coffret contient $\${total}$ perles toutes distinctes. Syrine enfile l'une après l'autre $\${picked}$ perles. Combien d'enfilements sont ainsi réalisables ?`,
18
+ strCorrection: `Pour la première perle, Syrine a $\${total}$ choix possibles.
19
+ Pour la deuxième perle, Syrine a $\${total-1}$ choix possibles.
20
+ Pour la troisième perle, Syrine a $\${total-2}$ choix possibles, etc.
21
+ Pour la dernière perle, Syrine a $\${total-(picked-1)}$ choix possibles.
22
+ Le nombre d'enfilements distincts est donc :
23
+
24
+ $$
25
+ \${cardinal}
26
+ $$
27
+
28
+ `,
29
+ dictFuncs: {
30
+ total: () => {
31
+ return {
32
+ value: randint(50, 101),
33
+ };
34
+ },
35
+ picked: () => {
36
+ return {
37
+ value: randint(20, 30),
38
+ };
39
+ },
40
+ },
41
+ },
42
+ ];
43
+ class SituationConstructor {
44
+ static randomSituationFromTemplate(situationTemplate) {
45
+ const dictSets = Object.entries(situationTemplate.dictFuncs).reduce((acc, [key, func]) => {
46
+ acc[key] = func();
47
+ return acc;
48
+ }, {});
49
+ const { strInstruction, strCorrection: strCorrectionIncomplete } = Object.entries(dictSets).reduce((acc, [key, miniDict]) => {
50
+ acc.strInstruction = acc.strInstruction.replace(`\${${key}}`, `${miniDict.value}`);
51
+ acc.strCorrection = acc.strCorrection.replace(`\${${key}}`, `${miniDict.value}`);
52
+ return acc;
53
+ }, {
54
+ strInstruction: situationTemplate.strInstruction,
55
+ strCorrection: situationTemplate.strCorrection,
56
+ });
57
+ const { total: { value: valueTotal }, picked: { value: valuePicked }, } = dictSets;
58
+ const nodeCardinal = frac(facto(valueTotal), facto(substract(valueTotal, valuePicked)));
59
+ const strCorrection = strCorrectionIncomplete
60
+ .replace(`\${cardinal}`, `${valueTotal} \\times ${round(valueTotal - 1, 0)} \\times ${round(valueTotal - 2, 0)} \\times ... \\times ${round(valueTotal - valuePicked + 1, 0)} = ${nodeCardinal.toTex()}`)
61
+ .replace(`\${total-1}`, `${round(valueTotal - 1, 0)}`)
62
+ .replace(`\${total-2}`, `${round(valueTotal - 2, 0)}`)
63
+ .replace(`\${total-(picked-1)}`, `${substract(valueTotal, valuePicked - 1).toTex()} = ${round(valueTotal - valuePicked + 1, 0)}`);
64
+ return {
65
+ nodeIdsCardinal: nodeCardinal.toIdentifiers(),
66
+ strInstruction,
67
+ strCorrection,
68
+ dictSets,
69
+ };
70
+ }
71
+ }
72
+ const getInstruction = (identifiers) => {
73
+ const { situation: { strInstruction }, } = identifiers;
74
+ return strInstruction;
75
+ };
76
+ const getAnswerNode = (identifiers) => {
77
+ const { situation: { nodeIdsCardinal }, } = identifiers;
78
+ const nodeCardinal = NodeConstructor.fromIdentifiers(nodeIdsCardinal);
79
+ return nodeCardinal;
80
+ };
81
+ const getAnswer = (identifiers) => {
82
+ return getAnswerNode(identifiers).toTex();
83
+ };
84
+ const getHint = () => {
85
+ return `Ici, il faut tenir compte de l'ordre.
86
+ Tu as deux possibilités :
87
+ - soit tu appliques directement la formule du nombre d'arrangements
88
+ - soit tu retrouves la formule en comptant le nombre de choix possibles pour la première perle, puis pour la seconde, etc.`;
89
+ };
90
+ const getCorrection = (identifiers) => {
91
+ const { situation: { strCorrection }, } = identifiers;
92
+ return `${strCorrection}
93
+
94
+ On utilise la formule car elle est équivalente et beaucoup moins longue à écrire.`;
95
+ };
96
+ const getPropositions = (n, { answer, ...identifiers }) => {
97
+ const { situation: { dictSets }, } = identifiers;
98
+ const propositions = [];
99
+ addValidProp(propositions, answer);
100
+ const { total: { value: valueTotal }, picked: { value: valuePicked }, } = dictSets;
101
+ //student: picked!
102
+ {
103
+ const nodeWrong = facto(valuePicked);
104
+ tryToAddWrongProp(propositions, nodeWrong.toTex());
105
+ }
106
+ //student: binom(total, picked)
107
+ {
108
+ const nodeWrong = binom(valueTotal, valuePicked);
109
+ tryToAddWrongProp(propositions, nodeWrong.toTex());
110
+ }
111
+ //student: power(total, picked)
112
+ {
113
+ const nodeWrong = power(valueTotal, valuePicked);
114
+ tryToAddWrongProp(propositions, nodeWrong.toTex());
115
+ }
116
+ return shuffleProps(propositions, n);
117
+ };
118
+ const getKeys = () => {
119
+ const keyFacto = {
120
+ id: "custom",
121
+ label: "!",
122
+ labelType: "tex",
123
+ mathfieldInstructions: {
124
+ method: "write",
125
+ content: "!",
126
+ },
127
+ };
128
+ return [
129
+ // "facto",
130
+ keyFacto,
131
+ ];
132
+ };
133
+ const isAnswerValid = (ans, { answer }) => {
134
+ try {
135
+ const nodeAns = parseAlgebraic(ans);
136
+ const nodeAnswer = parseAlgebraic(answer);
137
+ return (NodeComparator.isEqualViaFrac(nodeAns, nodeAnswer) ||
138
+ (() => {
139
+ if (isFractionNode(nodeAns)) {
140
+ return (NodeComparator.isEqualViaFrac(nodeAns.leftChild, nodeAnswer.leftChild) ||
141
+ NodeComparator.isEqualViaFrac(nodeAns.rightChild, nodeAnswer.rightChild));
142
+ }
143
+ else {
144
+ return false;
145
+ }
146
+ })());
147
+ }
148
+ catch (e) {
149
+ handleVEAError(e);
150
+ return false;
151
+ }
152
+ };
153
+ const getFindNumberOfPartialPermutationsFromSituationQuestion = () => {
154
+ const situationTemplate = random(situationTemplates);
155
+ const situation = SituationConstructor.randomSituationFromTemplate(situationTemplate);
156
+ const identifiers = {
157
+ situation,
158
+ };
159
+ return getQuestionFromIdentifiers(identifiers);
160
+ };
161
+ const getQuestionFromIdentifiers = (identifiers) => {
162
+ const question = {
163
+ instruction: getInstruction(identifiers),
164
+ answer: getAnswer(identifiers),
165
+ keys: getKeys(identifiers),
166
+ answerFormat: "tex",
167
+ identifiers,
168
+ hint: getHint(identifiers),
169
+ correction: getCorrection(identifiers),
170
+ };
171
+ return question;
172
+ };
173
+ export const findNumberOfPartialPermutationsFromSituation = {
174
+ id: "findNumberOfPartialPermutationsFromSituation",
175
+ connector: "=",
176
+ isSingleStep: true,
177
+ label: "Déterminer le nombre de $k$-uplets d'éléments distincts à partir d'une situation",
178
+ generator: (nb) => getDistinctQuestions(getFindNumberOfPartialPermutationsFromSituationQuestion, nb),
179
+ qcmTimer: 60,
180
+ freeTimer: 60,
181
+ getPropositions,
182
+ isAnswerValid,
183
+ subject: "Mathématiques",
184
+ hasHintAndCorrection: true,
185
+ getQuestionFromIdentifiers,
186
+ };
@@ -0,0 +1,17 @@
1
+ import { Exercise } from "../../../../exercises/exercise.js";
2
+ import { NodeIdentifiers } from "../../../../tree/nodes/nodeConstructor.js";
3
+ type Situation = {
4
+ strInstruction: string;
5
+ strHint: string;
6
+ strCorrection: string;
7
+ dictSets: Record<string, {
8
+ value: number;
9
+ }>;
10
+ nodeIdsCardinal: NodeIdentifiers;
11
+ };
12
+ type Identifiers = {
13
+ situation: Situation;
14
+ };
15
+ export declare const findNumberOfPermutationsFromSituation: Exercise<Identifiers>;
16
+ export {};
17
+ //# sourceMappingURL=findNumberOfPermutationsFromSituation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"findNumberOfPermutationsFromSituation.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/sets/partialPermutations/findNumberOfPermutationsFromSituation.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAeT,MAAM,6BAA6B,CAAC;AAErC,OAAO,EAEL,eAAe,EAChB,MAAM,qCAAqC,CAAC;AA4F7C,KAAK,SAAS,GAAG;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC5C,eAAe,EAAE,eAAe,CAAC;CAClC,CAAC;AA0DF,KAAK,WAAW,GAAG;IACjB,SAAS,EAAE,SAAS,CAAC;CACtB,CAAC;AA+JF,eAAO,MAAM,qCAAqC,EAAE,QAAQ,CAAC,WAAW,CAkBvE,CAAC"}