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
@@ -7,6 +7,9 @@ import { Affine } from "../../../../math/polynomials/affine.js";
7
7
  import { randint } from "../../../../math/utils/random/randint.js";
8
8
  import { InequationNode } from "../../../../tree/nodes/inequations/inequationNode.js";
9
9
  import { InequationSolutionNode } from "../../../../tree/nodes/inequations/inequationSolutionNode.js";
10
+ import { add } from "../../../../tree/nodes/operators/addNode.js";
11
+ import { multiply } from "../../../../tree/nodes/operators/multiplyNode.js";
12
+ import { substract } from "../../../../tree/nodes/operators/substractNode.js";
10
13
  import { inequationParser } from "../../../../tree/parsers/inequationParser.js";
11
14
  import { intervalParser } from "../../../../tree/parsers/intervalParser.js";
12
15
  import { coinFlip } from "../../../../utils/alea/coinFlip.js";
@@ -41,37 +44,59 @@ const getAnswerNode = (identifiers, opts) => {
41
44
  const getAnswer = (identifiers, opts) => {
42
45
  return getAnswerNode(identifiers, opts).toTex();
43
46
  };
44
- // const getHint: GetHint<Identifiers, Options> = (identifiers, opts) => {
45
- // return `Isole le terme $x$ dans le membre de gauche de l'inéquation. Attention : lorsqu'on multiplie (ou divise) les deux membres d'une inéquation par un nombre négatif, le sens de l'inéquation est inversé.`;
46
- // };
47
- // const getCorrection: GetHint<Identifiers, Options> = (identifiers, opts) => {
48
- // const { a, b, c, d,ineqType } = identifiers;
49
- // const isInterval =
50
- // opts?.inequationSolutionFormat === "Intervalle (S = [a;b])";
51
- // const answer = getAnswer(identifiers, opts);
52
- // return `On isole $x$ dans le membre de gauche de l'inéquation :
53
- // $$
54
- // ${firstDegreeInequationResolutionTex(new Affine(a, b), ineqType, new Affine(c,d))}
55
- // $$
56
- // ${
57
- // identifiers.a < 0
58
- // ? `On a changé le sens de l'inéquation, car $${a}$ est négatif.`
59
- // : ""
60
- // }
61
- // ${
62
- // isInterval
63
- // ? `On traduit ensuite cette inéquation en intervalle :
64
- // $$
65
- // ${answer}
66
- // $$
67
- // `
68
- // : ""
69
- // }
70
- // `;
71
- // };
47
+ const getHint = () => {
48
+ return `Commence par regrouper les termes en $x$ d'un même côté de l'inéquation. Puis isole $x$ en effectuant les bonnes opérations.
49
+
50
+ Attention, lorsqu'on divise ou multiplie les deux membres d'une inéquation par un nombre négatif, l'inéquation change de sens. `;
51
+ };
52
+ const getCorrection = (identifiers, opts) => {
53
+ const { a, b, c, d, ineqType } = identifiers;
54
+ const affine1 = new Affine(a, b);
55
+ const affine2 = new Affine(c, d);
56
+ const isInterval = opts?.inequationSolutionFormat === "Intervalle (S = [a;b])";
57
+ return `On doit résoudre l'inéquation :
58
+
59
+ $$
60
+ ${affine1.toTex()} ${ineqType} ${affine2.toTex()}
61
+ $$
62
+
63
+ On ${c < 0 ? "ajoute" : "enlève"} $${multiply(Math.abs(c), "x").toTex()}$ des deux côtés :
64
+
65
+ $$
66
+ ${add(multiply(substract(a, c).simplify(), "x"), b).toTex()} ${ineqType} ${d.frenchify()}
67
+ $$
68
+
69
+ On ${b < 0 ? "ajoute" : "enlève"} $${Math.abs(b).frenchify()}$ des deux côtés :
70
+
71
+ $$
72
+ ${multiply(substract(a, c).simplify(), "x").toTex()} ${ineqType} ${substract(d, b)
73
+ .simplify()
74
+ .toTex()}
75
+ $$
76
+
77
+ On divise ensuite par $${substract(a, c)
78
+ .simplify()
79
+ .toTex()}$. Puisque $${substract(a, c).simplify().toTex()}$ est ${a > c ? "positif" : "négatif"}, l'inéquation ${a > c ? "ne change pas" : "change"} de sens :
80
+
81
+ $$
82
+ ${getAnswer(identifiers, {
83
+ inequationSolutionFormat: "Inégalité (x>a)",
84
+ })}
85
+ $$
86
+
87
+ ${isInterval
88
+ ? `On traduit cette inégalité par un intervalle :
89
+
90
+ $$
91
+ ${getAnswer(identifiers, opts)}
92
+ $$`
93
+ : ""}
94
+ `;
95
+ };
72
96
  const getFirstDegreeInequationsQuestion = (opts) => {
73
- const affine1 = new Affine(randint(-10, 10, [0]), randint(-10, 10));
74
- const affine2 = new Affine(randint(-10, 10, [0, affine1.a]), randint(-10, 10));
97
+ // ax+b < cx+d
98
+ const affine1 = new Affine(randint(-10, 10, [0, 1]), randint(-10, 10, [0]));
99
+ const affine2 = new Affine(randint(-10, 10, [0, affine1.a, 1, affine1.a - 1]), randint(-10, 10, [0]));
75
100
  const coeff = affine1.a - affine2.a;
76
101
  const ineqType = InequationSymbolConstructor.random();
77
102
  const identifiers = {
@@ -91,6 +116,8 @@ const getQuestionFromIdentifiers = (identifiers, opts) => {
91
116
  keys: getKeys(identifiers, opts),
92
117
  answerFormat: "tex",
93
118
  identifiers,
119
+ hint: getHint(identifiers, opts),
120
+ correction: getCorrection(identifiers, opts),
94
121
  };
95
122
  return question;
96
123
  };
@@ -157,6 +184,7 @@ export const firstDegreeInequationsType3 = {
157
184
  subject: "Mathématiques",
158
185
  options,
159
186
  getQuestionFromIdentifiers,
187
+ hasHintAndCorrection: true,
160
188
  };
161
189
  // export const reuseFirstDegreeInequationsType3 = {
162
190
  // getAnswerNode,
@@ -0,0 +1,3 @@
1
+ export * from "./writeCombinationFormulaUsingFactorial.js";
2
+ export * from "./mentalCalculateCombination.js";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/combinatory/combination/index.ts"],"names":[],"mappings":"AAAA,cAAc,4CAA4C,CAAC;AAC3D,cAAc,iCAAiC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from "./writeCombinationFormulaUsingFactorial.js";
2
+ export * from "./mentalCalculateCombination.js";
@@ -0,0 +1,11 @@
1
+ import { Exercise } from "../../../../exercises/exercise.js";
2
+ type Identifiers = {
3
+ total: number;
4
+ picked: number;
5
+ };
6
+ type Options = {
7
+ statementFormulaType: string;
8
+ };
9
+ export declare const mentalCalculateCombination: Exercise<Identifiers, Options>;
10
+ export {};
11
+ //# sourceMappingURL=mentalCalculateCombination.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mentalCalculateCombination.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/combinatory/combination/mentalCalculateCombination.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAmBT,MAAM,6BAA6B,CAAC;AAarC,KAAK,WAAW,GAAG;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AA8OF,KAAK,OAAO,GAAG;IACb,oBAAoB,EAAE,MAAM,CAAC;CAC9B,CAAC;AAgBF,eAAO,MAAM,0BAA0B,EAAE,QAAQ,CAAC,WAAW,EAAE,OAAO,CAkBrE,CAAC"}
@@ -0,0 +1,225 @@
1
+ import { GeneratorOptionTarget, GeneratorOptionType, addValidProp, propWhile, shuffleProps, tryToAddWrongProp, } from "../../../../exercises/exercise.js";
2
+ import { numberVEA } from "../../../../exercises/vea/numberVEA.js";
3
+ import { randint } from "../../../../math/utils/random/randint.js";
4
+ import { facto } from "../../../../tree/nodes/functions/factorialNode.js";
5
+ import { binom } from "../../../../tree/nodes/operators/binomialCoefficientNode.js";
6
+ import { frac } from "../../../../tree/nodes/operators/fractionNode.js";
7
+ import { multiply } from "../../../../tree/nodes/operators/multiplyNode.js";
8
+ import { substract } from "../../../../tree/nodes/operators/substractNode.js";
9
+ import { coinFlip } from "../../../../utils/alea/coinFlip.js";
10
+ import { handleVEAError } from "../../../../utils/errors/handleVEAError.js";
11
+ import { alignTex } from "../../../../utils/latex/alignTex.js";
12
+ const getInstruction = (identifiers, optsIn) => {
13
+ const opts = optsIn ?? optsDefault;
14
+ const { statementFormulaType } = opts;
15
+ const { total, picked } = identifiers;
16
+ const texFormula = (() => {
17
+ switch (statementFormulaType) {
18
+ case "$\\binom{n}{k}$":
19
+ return binom(total, picked).toTex();
20
+ case "$\\frac{n!}{k!(n-k)!}$":
21
+ return binom(total, picked).toFormulaWithFactoFractionNode().toTex();
22
+ default:
23
+ throw new Error("Unsupported statementFormulaType:" + statementFormulaType);
24
+ }
25
+ })();
26
+ return `Sans calculatrice, et en utilisant des simplifications, calculer :
27
+
28
+ $$
29
+ ${texFormula}
30
+ $$`;
31
+ };
32
+ const getAnswerStuff = (identifiers) => {
33
+ const { total, picked } = identifiers;
34
+ const nodeBinom = binom(total, picked);
35
+ const nodeFormulaRaw = nodeBinom.toFormulaWithFactoFractionNode();
36
+ const nodeAnswer = nodeBinom.toFormulaWithoutFacto();
37
+ return { nodeBinom, nodeFormulaRaw, nodeAnswer };
38
+ };
39
+ const getAnswer = (identifiers) => {
40
+ return getAnswerStuff(identifiers)
41
+ .nodeAnswer.simplify({
42
+ towardsDistribute: true,
43
+ })
44
+ .toTex();
45
+ };
46
+ const getHint = (identifiers) => {
47
+ const { total, picked } = identifiers;
48
+ const { nodeBinom, nodeFormulaRaw } = getAnswerStuff(identifiers);
49
+ return `Voici la formule pour $${picked}$ parmi $${total}$:
50
+
51
+ $$
52
+ ${nodeBinom.toTex()} = ${nodeFormulaRaw.toTex()}
53
+ $$
54
+
55
+ Voici les produits qui correspondent à chaque factorielle :
56
+
57
+ ${alignTex([facto(total), facto(picked), facto(total - picked)].flatMap((nodeFacto) => {
58
+ const texExpanded = nodeFacto
59
+ .toMultiplyNode()
60
+ .toTex({ forceNoSimplification: true, forceTimesSign: true });
61
+ const arrTexFactor = texExpanded.split("\\times");
62
+ const arrArrTexFactor = arrTexFactor.reduce((acc, texFactor, i, arr) => {
63
+ acc.running.push(texFactor);
64
+ if (acc.running.length >= 4 || i === arr.length - 1) {
65
+ acc.chunks.push(acc.running);
66
+ acc.running = [];
67
+ }
68
+ return acc;
69
+ }, {
70
+ chunks: [],
71
+ running: [],
72
+ }).chunks;
73
+ return arrArrTexFactor.map((arrTexFactor, i) => {
74
+ const texChunk = arrTexFactor.join(" \\times ");
75
+ if (i === 0) {
76
+ return [nodeFacto.toTex(), "= \\ \\ \\ ", texChunk];
77
+ }
78
+ else {
79
+ return [" ", "\\ \\ \\ \\times", texChunk];
80
+ }
81
+ });
82
+ }))}
83
+
84
+ Remplace chaque factorielle par le produit qui lui correspond puis simplifie quand le même terme apparaît au numérateur et au dénominateur.
85
+ `;
86
+ };
87
+ const getCorrection = (identifiers) => {
88
+ const { total, picked } = identifiers;
89
+ const { nodeBinom, nodeFormulaRaw, nodeAnswer } = getAnswerStuff(identifiers);
90
+ const nodeFracFacto = frac(facto(total), facto(picked));
91
+ const nodeNum = nodeAnswer.leftChild;
92
+ return `Voici la formule pour $${picked}$ parmi $${total}$:
93
+
94
+ $$
95
+ ${nodeBinom.toTex()} = ${nodeFormulaRaw.toTex()}
96
+ $$
97
+
98
+ Or :
99
+
100
+ $$
101
+ ${nodeFracFacto.toTex()} = ${nodeNum.toTex()}
102
+ $$
103
+
104
+ Donc:
105
+
106
+ ${alignTex([
107
+ [
108
+ nodeFormulaRaw.toTex(),
109
+ "=",
110
+ nodeAnswer.toTex({ forceTimesSign: true, forceNoSimplification: true }),
111
+ ],
112
+ ["", "=", nodeAnswer.simplify({ towardsDistribute: true }).toTex()],
113
+ ])}
114
+
115
+ `;
116
+ };
117
+ const getPropositions = (n, { answer, ...identifiers }) => {
118
+ const { total, picked } = identifiers;
119
+ const propositions = [];
120
+ addValidProp(propositions, answer);
121
+ function checkAndTryToAddNode(node) {
122
+ const value = node.evaluate();
123
+ if (0.01 <= value && value <= 220) {
124
+ tryToAddWrongProp(propositions, node.simplify({ towardsDistribute: true }).toTex());
125
+ }
126
+ }
127
+ //student: total!/(total-picked)!
128
+ {
129
+ const node = frac(facto(total), facto(substract(total, picked)));
130
+ checkAndTryToAddNode(node);
131
+ }
132
+ //student: total!/picked!
133
+ {
134
+ const node = frac(facto(total), facto(picked));
135
+ checkAndTryToAddNode(node);
136
+ }
137
+ //student: picked!/total!
138
+ {
139
+ const node = frac(facto(total), facto(picked));
140
+ checkAndTryToAddNode(node);
141
+ }
142
+ //student: forgets factorial somewhere
143
+ {
144
+ {
145
+ const node = frac(facto(total), multiply(picked, facto(substract(total, picked))));
146
+ checkAndTryToAddNode(node);
147
+ }
148
+ {
149
+ const node = frac(facto(picked), multiply(total, facto(substract(total, picked))));
150
+ checkAndTryToAddNode(node);
151
+ }
152
+ }
153
+ propWhile(propositions, n, () => {
154
+ const identifiersWrong = createRandomIdentifiers();
155
+ tryToAddWrongProp(propositions, getAnswer(identifiersWrong));
156
+ });
157
+ return shuffleProps(propositions, n);
158
+ };
159
+ const getKeys = () => {
160
+ return [];
161
+ };
162
+ const isAnswerValid = (ans, { answer }) => {
163
+ try {
164
+ return numberVEA(ans, answer);
165
+ }
166
+ catch (err) {
167
+ return handleVEAError(err);
168
+ }
169
+ };
170
+ const createRandomIdentifiers = () => {
171
+ const total = randint(5, 13);
172
+ const nbFactors = randint(2, 4);
173
+ const picked = coinFlip() ? nbFactors : total - nbFactors;
174
+ return {
175
+ total,
176
+ picked,
177
+ };
178
+ };
179
+ const getMentalCalculateCombinationQuestion = (optsIn) => {
180
+ const opts = optsIn ?? optsDefault;
181
+ const identifiers = createRandomIdentifiers();
182
+ return getQuestionFromIdentifiers(identifiers, opts);
183
+ };
184
+ const getQuestionFromIdentifiers = (identifiers, opts) => {
185
+ const question = {
186
+ instruction: getInstruction(identifiers, opts),
187
+ answer: getAnswer(identifiers),
188
+ keys: getKeys(identifiers),
189
+ answerFormat: "tex",
190
+ identifiers,
191
+ hint: getHint(identifiers),
192
+ correction: getCorrection(identifiers),
193
+ options: opts,
194
+ };
195
+ return question;
196
+ };
197
+ const optsDefault = {
198
+ statementFormulaType: "$\\binom{n}{k}$",
199
+ };
200
+ const options = [
201
+ {
202
+ id: "statementFormulaType",
203
+ label: "Type de formule dans l'énoncé",
204
+ target: GeneratorOptionTarget.generation,
205
+ type: GeneratorOptionType.select,
206
+ values: ["$\\binom{n}{k}$", "$\\frac{n!}{k!(n-k)!}$"],
207
+ defaultValue: optsDefault.statementFormulaType,
208
+ },
209
+ ];
210
+ export const mentalCalculateCombination = {
211
+ id: "mentalCalculateCombination",
212
+ connector: "=",
213
+ label: "Calculer une combinaison sans calculatrice",
214
+ isSingleStep: true,
215
+ generator: (nb, opts) => [...Array(nb).keys()].map(() => getMentalCalculateCombinationQuestion(opts)),
216
+ options,
217
+ qcmTimer: 60,
218
+ freeTimer: 60,
219
+ getPropositions,
220
+ isAnswerValid,
221
+ subject: "Mathématiques",
222
+ getQuestionFromIdentifiers,
223
+ hasHintAndCorrection: true,
224
+ shouldHaveCalculator: false,
225
+ };
@@ -0,0 +1,13 @@
1
+ import { Exercise } from "../../../../exercises/exercise.js";
2
+ import { NodeIdentifiers } from "../../../../tree/nodes/nodeConstructor.js";
3
+ type Identifiers = {
4
+ nodeIdsTotal: NodeIdentifiers;
5
+ nodeIdsPicked: NodeIdentifiers;
6
+ operandType: string;
7
+ };
8
+ type Options = {
9
+ operandType: string;
10
+ };
11
+ export declare const writeCombinationFormulaUsingFactorial: Exercise<Identifiers, Options>;
12
+ export {};
13
+ //# sourceMappingURL=writeCombinationFormulaUsingFactorial.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"writeCombinationFormulaUsingFactorial.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/combinatory/combination/writeCombinationFormulaUsingFactorial.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAkBT,MAAM,6BAA6B,CAAC;AAMrC,OAAO,EAEL,eAAe,EAChB,MAAM,qCAAqC,CAAC;AAiB7C,KAAK,WAAW,GAAG;IACjB,YAAY,EAAE,eAAe,CAAC;IAC9B,aAAa,EAAE,eAAe,CAAC;IAC/B,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AA2UF,KAAK,OAAO,GAAG;IACb,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAsBF,eAAO,MAAM,qCAAqC,EAAE,QAAQ,CAC1D,WAAW,EACX,OAAO,CAoBR,CAAC"}
@@ -0,0 +1,285 @@
1
+ import { GeneratorOptionTarget, GeneratorOptionType, addValidProp, shuffleProps, tryToAddWrongProp, } from "../../../../exercises/exercise.js";
2
+ import { getDistinctQuestions } from "../../../../exercises/utils/getDistinctQuestions.js";
3
+ import { defaultArrayedOptsWhereNeeded } from "../../../../exercises/utils/options/arrayedOptions.js";
4
+ import { randint } from "../../../../math/utils/random/randint.js";
5
+ import { facto } from "../../../../tree/nodes/functions/factorialNode.js";
6
+ import { NodeConstructor, } from "../../../../tree/nodes/nodeConstructor.js";
7
+ import { binom } from "../../../../tree/nodes/operators/binomialCoefficientNode.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 { VariableNode } from "../../../../tree/nodes/variables/variableNode.js";
12
+ import { parseAlgebraic } from "../../../../tree/parsers/latexParser.js";
13
+ import { NodeComparator } from "../../../../tree/utilities/nodeComparator.js";
14
+ import { random, randomMany } from "../../../../utils/alea/random.js";
15
+ import { handleVEAError } from "../../../../utils/errors/handleVEAError.js";
16
+ import { alignTex } from "../../../../utils/latex/alignTex.js";
17
+ const getInstruction = (identifiers) => {
18
+ const { nodeIdsTotal, nodeIdsPicked } = identifiers;
19
+ const [nodeTotal, nodePicked] = [nodeIdsTotal, nodeIdsPicked].map((nodeIds) => NodeConstructor.fromIdentifiers(nodeIds));
20
+ return `Ecrire à l'aide de la factorielle la formule permettant de calculer :
21
+
22
+ $$
23
+ ${binom(nodeTotal, nodePicked).toTex()}
24
+ $$`;
25
+ };
26
+ const getAnswerStuff = (identifiers) => {
27
+ const { nodeIdsTotal, nodeIdsPicked } = identifiers;
28
+ const [nodeTotal, nodePicked] = [nodeIdsTotal, nodeIdsPicked].map((nodeIds) => NodeConstructor.fromIdentifiers(nodeIds));
29
+ const nodeBinom = binom(nodeTotal, nodePicked);
30
+ const nodeAnswer = nodeBinom.toFormulaWithFactoFractionNode();
31
+ return { nodeBinom, nodeAnswer };
32
+ };
33
+ const getAnswer = (identifiers) => {
34
+ return getAnswerStuff(identifiers).nodeAnswer.toTex({
35
+ forceParenthesis: true,
36
+ });
37
+ };
38
+ const getHint = () => {
39
+ return `Le nombre de combinaisons de $k$ élements parmi $n$ (noté $${binom(new VariableNode("n"), new VariableNode("k")).toTex()}$)
40
+ est égal au nombre de façon de prendre $k$ éléments parmi $n$ sans tenir compte de l'ordre.
41
+
42
+ Exemple:
43
+ `;
44
+ };
45
+ const getCorrection = (identifiers) => {
46
+ const { nodeIdsTotal, nodeIdsPicked, operandType } = identifiers;
47
+ const [nodeTotal, nodePicked] = [nodeIdsTotal, nodeIdsPicked].map((nodeIds) => NodeConstructor.fromIdentifiers(nodeIds));
48
+ const nodeBinom = binom(nodeTotal, nodePicked);
49
+ const nodeAnswerRaw = nodeBinom.toFormulaWithFactoFractionNode(false);
50
+ const nodeAnswerPretty = nodeBinom.toFormulaWithFactoFractionNode(true);
51
+ switch (operandType) {
52
+ case "lettres":
53
+ return `
54
+
55
+ $$
56
+ ${nodeBinom.toTex()} = ${nodeBinom.toTex()}
57
+ $$
58
+
59
+ `;
60
+ case "entiers":
61
+ return `
62
+
63
+ ${alignTex([
64
+ [nodeBinom.toTex(), "=", nodeAnswerRaw.toTex()],
65
+ ["", "=", nodeAnswerPretty.toTex()],
66
+ ])}
67
+
68
+ `;
69
+ default:
70
+ throw new Error("Unsupported operandType: " + operandType);
71
+ }
72
+ };
73
+ const getPropositions = (n, { answer, ...identifiers }) => {
74
+ const { nodeIdsTotal, nodeIdsPicked, operandType } = identifiers;
75
+ const [nodeTotal, nodePicked] = [nodeIdsTotal, nodeIdsPicked].map((nodeIds) => NodeConstructor.fromIdentifiers(nodeIds));
76
+ const propositions = [];
77
+ addValidProp(propositions, answer);
78
+ //student: total<->picked
79
+ {
80
+ switch (operandType) {
81
+ case "lettres":
82
+ {
83
+ const node = frac(facto(nodePicked), multiply(facto(nodeTotal), facto(substract(nodePicked, nodeTotal))));
84
+ tryToAddWrongProp(propositions, node.toTex());
85
+ }
86
+ break;
87
+ case "entiers":
88
+ {
89
+ const node = frac(facto(nodePicked), multiply(facto(nodeTotal), facto(substract(nodeTotal, nodePicked).simplify({
90
+ towardsDistribute: true,
91
+ }))));
92
+ tryToAddWrongProp(propositions, node.toTex());
93
+ }
94
+ break;
95
+ default:
96
+ throw new Error("Unsupported operandType: " + operandType);
97
+ }
98
+ }
99
+ //student: total!/(total-picked)!
100
+ {
101
+ const node = frac(facto(nodeTotal), facto(substract(nodeTotal, nodePicked).simplify({ towardsDistribute: true })));
102
+ tryToAddWrongProp(propositions, node.toTex());
103
+ }
104
+ //student: total!/picked!
105
+ {
106
+ const node = frac(facto(nodeTotal), facto(nodePicked));
107
+ tryToAddWrongProp(propositions, node.toTex());
108
+ }
109
+ //student: picked!/total!
110
+ {
111
+ const node = frac(facto(nodePicked), facto(nodeTotal));
112
+ tryToAddWrongProp(propositions, node.toTex());
113
+ }
114
+ //student: forgets factorial somewhere
115
+ {
116
+ {
117
+ const node = frac(facto(nodeTotal), multiply(nodePicked, facto(substract(nodeTotal, nodePicked).simplify({
118
+ towardsDistribute: true,
119
+ }))));
120
+ tryToAddWrongProp(propositions, node.toTex());
121
+ }
122
+ switch (operandType) {
123
+ case "lettres":
124
+ {
125
+ {
126
+ const node = frac(facto(nodePicked), multiply(nodeTotal, facto(substract(nodePicked, nodeTotal))));
127
+ tryToAddWrongProp(propositions, node.toTex());
128
+ }
129
+ }
130
+ break;
131
+ case "entiers":
132
+ {
133
+ const node = frac(facto(nodePicked), multiply(nodeTotal, facto(substract(nodeTotal, nodePicked).simplify({
134
+ towardsDistribute: true,
135
+ }))));
136
+ tryToAddWrongProp(propositions, node.toTex());
137
+ }
138
+ break;
139
+ default:
140
+ throw new Error("Unsupported operandType: " + operandType);
141
+ }
142
+ }
143
+ return shuffleProps(propositions, n);
144
+ };
145
+ const getKeys = (identifiers) => {
146
+ const { operandType } = identifiers;
147
+ const keyFacto = {
148
+ id: "custom",
149
+ label: "!",
150
+ labelType: "tex",
151
+ mathfieldInstructions: {
152
+ method: "write",
153
+ content: "!",
154
+ },
155
+ };
156
+ switch (operandType) {
157
+ case "lettres": {
158
+ const { nodeIdsTotal, nodeIdsPicked } = identifiers;
159
+ const [nodeTotal, nodePicked] = [nodeIdsTotal, nodeIdsPicked].map((nodeIds) => NodeConstructor.fromIdentifiers(nodeIds));
160
+ return [
161
+ // "facto",
162
+ keyFacto,
163
+ ...[nodeTotal, nodePicked].map((node) => node.name),
164
+ ];
165
+ }
166
+ case "entiers":
167
+ // return ["facto"];
168
+ return [keyFacto];
169
+ default:
170
+ throw new Error("Unsupported operandType: " + operandType);
171
+ }
172
+ };
173
+ const isAnswerValid = (ans, { answer, ...identifiers }) => {
174
+ const { operandType } = identifiers;
175
+ switch (operandType) {
176
+ case "lettres": {
177
+ try {
178
+ //TODO: parse factorial
179
+ const nodeAnswer = getAnswerStuff(identifiers).nodeAnswer;
180
+ const isFormat1 = (str) => str === nodeAnswer.toTex();
181
+ const isFormat2 = (str) => str ===
182
+ (() => {
183
+ const nodeDenum = nodeAnswer.rightChild;
184
+ const nodeAnswer2 = frac(nodeAnswer.leftChild, multiply(nodeDenum.rightChild, nodeDenum.leftChild));
185
+ return nodeAnswer2;
186
+ })().toTex();
187
+ return isFormat1(ans) || isFormat2(ans);
188
+ }
189
+ catch (err) {
190
+ return handleVEAError(err);
191
+ }
192
+ }
193
+ case "entiers": {
194
+ try {
195
+ //TODO: parse factorial
196
+ function countFactorialSymbols(str) {
197
+ return str.split("").filter((str) => str === "!").length;
198
+ }
199
+ if (countFactorialSymbols(ans) !== countFactorialSymbols(answer)) {
200
+ return false;
201
+ }
202
+ const nodeAns = parseAlgebraic(ans);
203
+ const nodeAnswer = parseAlgebraic(answer);
204
+ return NodeComparator.isEqualViaFrac(nodeAns, nodeAnswer);
205
+ }
206
+ catch (err) {
207
+ return handleVEAError(err);
208
+ }
209
+ }
210
+ default:
211
+ throw new Error("Unsupported operandType: " + operandType);
212
+ }
213
+ };
214
+ const createRandomIdentifiers = (operandType) => {
215
+ switch (operandType) {
216
+ case "lettres": {
217
+ const poolLetters = "abcdklmnpqrst".split("");
218
+ const [nodeTotal, nodePicked] = randomMany(poolLetters, 2).map((letter) => new VariableNode(letter));
219
+ return {
220
+ nodeIdsTotal: nodeTotal.toIdentifiers(),
221
+ nodeIdsPicked: nodePicked.toIdentifiers(),
222
+ operandType,
223
+ };
224
+ }
225
+ case "entiers": {
226
+ const total = randint(30, 61);
227
+ const picked = randint(5, 21);
228
+ const [nodeTotal, nodePicked] = [total, picked].map((v) => v.toTree());
229
+ return {
230
+ nodeIdsTotal: nodeTotal.toIdentifiers(),
231
+ nodeIdsPicked: nodePicked.toIdentifiers(),
232
+ operandType,
233
+ };
234
+ }
235
+ default:
236
+ throw new Error("Unsupported operandType: " + operandType);
237
+ }
238
+ };
239
+ const getWriteCombinationFormulaUsingFactorialQuestion = (optsIn) => {
240
+ const arrayedOpts = defaultArrayedOptsWhereNeeded(optsIn, arrayedOptsDefault);
241
+ const operandType = random(arrayedOpts.operandType);
242
+ const identifiers = createRandomIdentifiers(operandType);
243
+ return getQuestionFromIdentifiers(identifiers);
244
+ };
245
+ const getQuestionFromIdentifiers = (identifiers) => {
246
+ const question = {
247
+ instruction: getInstruction(identifiers),
248
+ answer: getAnswer(identifiers),
249
+ keys: getKeys(identifiers),
250
+ answerFormat: "tex",
251
+ identifiers,
252
+ hint: getHint(identifiers),
253
+ correction: getCorrection(identifiers),
254
+ };
255
+ return question;
256
+ };
257
+ const arrayedOptsDefault = {
258
+ operandType: ["entiers"],
259
+ };
260
+ const options = [
261
+ {
262
+ id: "operandType",
263
+ label: "Type d'opérandes",
264
+ target: GeneratorOptionTarget.generation,
265
+ type: GeneratorOptionType.multiselect,
266
+ values: ["lettres", "entiers"],
267
+ defaultValue: arrayedOptsDefault.operandType,
268
+ },
269
+ ];
270
+ export const writeCombinationFormulaUsingFactorial = {
271
+ id: "writeCombinationFormulaUsingFactorial",
272
+ connector: "=",
273
+ label: "Écrire à l'aide de factorielles la formule pour $\\binom{n}{k}$",
274
+ isSingleStep: true,
275
+ generator: (nb, opts) => getDistinctQuestions(() => getWriteCombinationFormulaUsingFactorialQuestion(opts), nb),
276
+ options,
277
+ qcmTimer: 60,
278
+ freeTimer: 60,
279
+ getPropositions,
280
+ isAnswerValid,
281
+ subject: "Mathématiques",
282
+ getQuestionFromIdentifiers,
283
+ hasHintAndCorrection: true,
284
+ shouldHaveCalculator: false,
285
+ };