math-exercises 3.0.176 → 3.0.178

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 (136) hide show
  1. package/lib/exercises/math/derivation/variations/readExtremaAbscissFromDerivativeCurve.js +1 -1
  2. package/lib/exercises/math/functions/trinoms/sign/index.d.ts +1 -0
  3. package/lib/exercises/math/functions/trinoms/sign/index.d.ts.map +1 -1
  4. package/lib/exercises/math/functions/trinoms/sign/index.js +1 -0
  5. package/lib/exercises/math/functions/trinoms/sign/signOfProductOfAffineAndTrinom.d.ts +8 -0
  6. package/lib/exercises/math/functions/trinoms/sign/signOfProductOfAffineAndTrinom.d.ts.map +1 -0
  7. package/lib/exercises/math/functions/trinoms/sign/signOfProductOfAffineAndTrinom.js +233 -0
  8. package/lib/exercises/math/geometry/angles/parallelogramFourthAngle.d.ts.map +1 -1
  9. package/lib/exercises/math/geometry/angles/parallelogramFourthAngle.js +10 -10
  10. package/lib/exercises/math/geometry/quadrilaterals/parallelogramAngles.js +8 -8
  11. package/lib/exercises/math/geometry/triangles/similar/isSimilarTrianglesWithAngles.js +6 -6
  12. package/lib/exercises/math/geometry/triangles/triangleThirdAngleValue.js +8 -8
  13. package/lib/exercises/math/geometry/vectors/scalarProduct/alKashi/scalarProductAlKashiAngle.js +1 -1
  14. package/lib/exercises/math/geometry/vectors/scalarProduct/alKashi/scalarProductAlKashiSideLength.js +2 -2
  15. package/lib/exercises/math/geometry/vectors/scalarProduct/angleFromScalarProduct.js +2 -2
  16. package/lib/exercises/math/geometry/vectors/scalarProduct/scalarProductOrthoInSquare.d.ts.map +1 -1
  17. package/lib/exercises/math/geometry/vectors/scalarProduct/scalarProductOrthoInSquare.js +31 -6
  18. package/lib/exercises/math/probaStat/randomVariable/index.d.ts.map +1 -1
  19. package/lib/exercises/math/probaStat/randomVariable/index.js +1 -0
  20. package/lib/exercises/math/probaStat/trees/index.d.ts +1 -3
  21. package/lib/exercises/math/probaStat/trees/index.d.ts.map +1 -1
  22. package/lib/exercises/math/probaStat/trees/index.js +8 -3
  23. package/lib/exercises/math/probaStat/trees/probabilityTree.d.ts +3 -9
  24. package/lib/exercises/math/probaStat/trees/probabilityTree.d.ts.map +1 -1
  25. package/lib/exercises/math/probaStat/trees/probabilityTree.js +45 -419
  26. package/lib/exercises/math/probaStat/trees/probabilityTreeV2.d.ts +25 -0
  27. package/lib/exercises/math/probaStat/trees/probabilityTreeV2.d.ts.map +1 -0
  28. package/lib/exercises/math/probaStat/trees/probabilityTreeV2.js +625 -0
  29. package/lib/exercises/math/python/index.d.ts +1 -0
  30. package/lib/exercises/math/python/index.d.ts.map +1 -1
  31. package/lib/exercises/math/python/index.js +1 -0
  32. package/lib/exercises/math/python/sequences/pySequenceThresholdInstructionCompletion.d.ts.map +1 -1
  33. package/lib/exercises/math/python/sequences/pySequenceThresholdInstructionCompletion.js +11 -8
  34. package/lib/exercises/math/sequences/arithmetic/arithmeticFindExplicitFormulaFromTwoTerms.d.ts.map +1 -1
  35. package/lib/exercises/math/sequences/arithmetic/arithmeticFindExplicitFormulaFromTwoTerms.js +4 -3
  36. package/lib/exercises/math/sequences/arithmetic/index.d.ts +4 -3
  37. package/lib/exercises/math/sequences/arithmetic/index.d.ts.map +1 -1
  38. package/lib/exercises/math/sequences/arithmetic/index.js +4 -3
  39. package/lib/exercises/math/sequences/arithmetic/situations/arithmeticFindExplicitFormulaFromSituation.d.ts.map +1 -1
  40. package/lib/exercises/math/sequences/arithmetic/situations/arithmeticFindExplicitFormulaFromSituation.js +3 -2
  41. package/lib/exercises/math/sequences/arithmetic/situations/arithmeticFindRankFromSituation.d.ts.map +1 -1
  42. package/lib/exercises/math/sequences/arithmetic/situations/arithmeticFindRankFromSituation.js +8 -6
  43. package/lib/exercises/math/sequences/arithmetic/situations/arithmeticFindThresholdFromSituation.d.ts.map +1 -1
  44. package/lib/exercises/math/sequences/arithmetic/situations/arithmeticFindThresholdFromSituation.js +6 -5
  45. package/lib/exercises/math/sequences/arithmetic/situations/index.d.ts +0 -2
  46. package/lib/exercises/math/sequences/arithmetic/situations/index.d.ts.map +1 -1
  47. package/lib/exercises/math/sequences/arithmetic/situations/index.js +2 -2
  48. package/lib/exercises/math/sequences/arithmetic/sum/arithmeticComputeSumWithDots.d.ts +1 -0
  49. package/lib/exercises/math/sequences/arithmetic/sum/arithmeticComputeSumWithDots.d.ts.map +1 -1
  50. package/lib/exercises/math/sequences/arithmetic/sum/arithmeticComputeSumWithDots.js +65 -14
  51. package/lib/exercises/math/sequences/arithmetic/sum/index.d.ts +0 -1
  52. package/lib/exercises/math/sequences/arithmetic/sum/index.d.ts.map +1 -1
  53. package/lib/exercises/math/sequences/arithmetic/sum/index.js +1 -1
  54. package/lib/exercises/math/sequences/geometric/geometricFindExplicitFormulaFromTwoConsecutiveTerms.d.ts +14 -0
  55. package/lib/exercises/math/sequences/geometric/geometricFindExplicitFormulaFromTwoConsecutiveTerms.d.ts.map +1 -0
  56. package/lib/exercises/math/sequences/geometric/geometricFindExplicitFormulaFromTwoConsecutiveTerms.js +291 -0
  57. package/lib/exercises/math/sequences/geometric/geometricFindExplicitFormulaFromTwoTerms.d.ts.map +1 -1
  58. package/lib/exercises/math/sequences/geometric/geometricFindExplicitFormulaFromTwoTerms.js +4 -3
  59. package/lib/exercises/math/sequences/geometric/geometricFindRandomTermFromTwoConsecutiveTerms.d.ts +15 -0
  60. package/lib/exercises/math/sequences/geometric/geometricFindRandomTermFromTwoConsecutiveTerms.d.ts.map +1 -0
  61. package/lib/exercises/math/sequences/geometric/geometricFindRandomTermFromTwoConsecutiveTerms.js +249 -0
  62. package/lib/exercises/math/sequences/geometric/geometricFindRandomTermFromTwoTerms.js +1 -1
  63. package/lib/exercises/math/sequences/geometric/index.d.ts +6 -2
  64. package/lib/exercises/math/sequences/geometric/index.d.ts.map +1 -1
  65. package/lib/exercises/math/sequences/geometric/index.js +6 -2
  66. package/lib/exercises/math/sequences/geometric/situations/geometricFindExplicitFormulaFromSituation.d.ts.map +1 -1
  67. package/lib/exercises/math/sequences/geometric/situations/geometricFindExplicitFormulaFromSituation.js +3 -2
  68. package/lib/exercises/math/sequences/geometric/situations/geometricFindTermFromSituation.js +1 -1
  69. package/lib/exercises/math/sequences/geometric/sum/geometricComputeSumWithDots.js +2 -2
  70. package/lib/exercises/math/sequences/graph/placeFirstSequencePoints.js +2 -2
  71. package/lib/exercises/math/sequences/index.d.ts +1 -0
  72. package/lib/exercises/math/sequences/index.d.ts.map +1 -1
  73. package/lib/exercises/math/sequences/index.js +1 -0
  74. package/lib/exercises/math/sequences/seqArithmGeom/seqArithmGeomRecurrenceFormulaUsage.d.ts.map +1 -1
  75. package/lib/exercises/math/sequences/seqArithmGeom/seqArithmGeomRecurrenceFormulaUsage.js +5 -9
  76. package/lib/exercises/math/spaceGeometry/sphere/sphereLatLonReading.2d.js +1 -1
  77. package/lib/exercises/math/trigonometry/circle/findAngleFromCosAndSin.d.ts.map +1 -1
  78. package/lib/exercises/math/trigonometry/circle/findAngleFromCosAndSin.js +17 -8
  79. package/lib/exercises/math/trigonometry/circle/index.d.ts +2 -0
  80. package/lib/exercises/math/trigonometry/circle/index.d.ts.map +1 -1
  81. package/lib/exercises/math/trigonometry/circle/index.js +2 -1
  82. package/lib/exercises/math/trigonometry/circle/mainRemarkableValues.d.ts.map +1 -1
  83. package/lib/exercises/math/trigonometry/circle/mainRemarkableValues.js +57 -0
  84. package/lib/exercises/math/trigonometry/circle/remarkableValues.d.ts.map +1 -1
  85. package/lib/exercises/math/trigonometry/circle/remarkableValues.js +88 -0
  86. package/lib/exercises/math/trigonometry/circle/selectQuadrantOnTrigoCircle.d.ts +5 -0
  87. package/lib/exercises/math/trigonometry/circle/selectQuadrantOnTrigoCircle.d.ts.map +1 -1
  88. package/lib/exercises/math/trigonometry/circle/selectQuadrantOnTrigoCircle.js +92 -94
  89. package/lib/exercises/math/trigonometry/functions/associateAngleSimplification.d.ts +11 -0
  90. package/lib/exercises/math/trigonometry/functions/associateAngleSimplification.d.ts.map +1 -0
  91. package/lib/exercises/math/trigonometry/functions/associateAngleSimplification.js +166 -0
  92. package/lib/exercises/math/trigonometry/functions/basicEquationCos.d.ts.map +1 -1
  93. package/lib/exercises/math/trigonometry/functions/basicEquationCos.js +54 -9
  94. package/lib/exercises/math/trigonometry/functions/basicEquationSin.d.ts.map +1 -1
  95. package/lib/exercises/math/trigonometry/functions/basicEquationSin.js +54 -8
  96. package/lib/exercises/math/trigonometry/functions/equationSinOnRandomInterval.js +1 -2
  97. package/lib/exercises/math/trigonometry/functions/index.d.ts +1 -0
  98. package/lib/exercises/math/trigonometry/functions/index.d.ts.map +1 -1
  99. package/lib/exercises/math/trigonometry/functions/index.js +1 -0
  100. package/lib/exercises/math/trigonometry/triangle/trigonometryAngleCalcul.js +2 -2
  101. package/lib/exercises/pc/snellDescartes.js +2 -2
  102. package/lib/index.d.ts +165 -36
  103. package/lib/index.d.ts.map +1 -1
  104. package/lib/latexTester.d.ts.map +1 -1
  105. package/lib/latexTester.js +8 -5
  106. package/lib/math/polynomials/affine.d.ts +1 -0
  107. package/lib/math/polynomials/affine.d.ts.map +1 -1
  108. package/lib/math/polynomials/affine.js +5 -0
  109. package/lib/math/utils/arithmetic/primeFactors.js +1 -1
  110. package/lib/math/utils/functions/functionComposition.d.ts.map +1 -1
  111. package/lib/math/utils/functions/functionComposition.js +18 -1
  112. package/lib/math/utils/random/randTupleInt.d.ts +1 -0
  113. package/lib/math/utils/random/randTupleInt.d.ts.map +1 -1
  114. package/lib/math/utils/random/randTupleInt.js +1 -1
  115. package/lib/math/utils/sequences/situations/seqArithmeticSituations.d.ts +18 -4
  116. package/lib/math/utils/sequences/situations/seqArithmeticSituations.d.ts.map +1 -1
  117. package/lib/math/utils/sequences/situations/seqArithmeticSituations.js +437 -336
  118. package/lib/math/utils/sequences/situations/seqArithmeticUtils.d.ts.map +1 -1
  119. package/lib/math/utils/sequences/situations/seqArithmeticUtils.js +3 -1
  120. package/lib/math/utils/sequences/situations/seqGeometricSituations.d.ts +5 -0
  121. package/lib/math/utils/sequences/situations/seqGeometricSituations.d.ts.map +1 -1
  122. package/lib/math/utils/sequences/situations/seqGeometricSituations.js +58 -25
  123. package/lib/prototypesEnhancement.d.ts +1 -0
  124. package/lib/prototypesEnhancement.d.ts.map +1 -1
  125. package/lib/prototypesEnhancement.js +3 -0
  126. package/lib/tests/pdfs/mdCodeToLatex.d.ts.map +1 -1
  127. package/lib/tests/pdfs/mdCodeToLatex.js +8 -15
  128. package/lib/tests/questionTest.d.ts.map +1 -1
  129. package/lib/tests/questionTest.js +6 -3
  130. package/lib/tree/nodes/algebraicNode.d.ts +1 -0
  131. package/lib/tree/nodes/algebraicNode.d.ts.map +1 -1
  132. package/lib/tree/nodes/geometry/degree.js +1 -1
  133. package/lib/tree/nodes/operators/addNode.d.ts.map +1 -1
  134. package/lib/tree/nodes/operators/addNode.js +4 -2
  135. package/lib/tree/parsers/degreeParser.js +2 -2
  136. package/package.json +1 -1
@@ -36,10 +36,10 @@ $$
36
36
  const str = `${strRaw}
37
37
 
38
38
  $$
39
- u_{${rank2.frenchify()}} = u_{${rank1.frenchify()}} + (${reason.frenchify()})
39
+ u_{${rank2.frPretty(2)}} = u_{${rank1.frPretty(2)}} + (${reason.frPretty(2)})
40
40
  $$
41
41
 
42
- La relation de récurrence est, pour $n \\geq ${firstRank.frenchify()}$ :
42
+ La relation de récurrence est, pour $n \\geq ${firstRank.frPretty(2)}$ :
43
43
 
44
44
  $$
45
45
  ${seqArithmeticUtils
@@ -79,31 +79,36 @@ ${alignTex([
79
79
  }),
80
80
  variationFindRank: Object.assign({}, variationFindRank, {
81
81
  getCorrectionStuff: (initial, reason, firstRank, ...otherArgs) => {
82
- const [valueAsked] = otherArgs;
82
+ const [valueAsked, _rankDecoder] = otherArgs;
83
83
  const { str: strRaw } = variationFindRank.getCorrectionStuff(initial, reason, firstRank, ...otherArgs);
84
- const answerNode = variationFindRank.getAnswerNode(initial, reason, firstRank, ...otherArgs);
84
+ const { answerNode, rankNode } = variationFindRank.getAnswerStuff(initial, reason, firstRank, ...otherArgs);
85
+ const texRankSimplified = rankNode.evaluate().frPretty(0);
86
+ const texAnswer = [
87
+ ...new Set([answerNode.toTex(), answerNode.evaluate().frPretty(2)]),
88
+ ].join(" = ");
85
89
  const str = `${strRaw}
86
90
 
87
91
  On note $p$ le rang recherché. On a :
88
92
 
89
93
  ${alignTex([
90
- [`u_p`, "=", valueAsked.frenchify()],
94
+ [`u_p`, "=", valueAsked.frPretty(2)],
91
95
  [
92
96
  `${add(initial, multiply(reason, "p".toTree())).toTex()}`,
93
97
  "=",
94
- valueAsked.frenchify(),
98
+ valueAsked.frPretty(2),
95
99
  ],
96
100
  ])}
97
101
 
98
102
  On résout l'équation :
99
103
 
100
104
  ${alignTex([
101
- [`p`, "=", answerNode.toTex()],
102
- ["", "=", answerNode.simplify().toTex()],
105
+ [`p`, "=", rankNode.toTex()],
106
+ ["", "=", texRankSimplified],
103
107
  ])}
104
108
 
109
+ Le rang $p$ est donc $${texRankSimplified}$.
105
110
 
106
- `;
111
+ Le nombre recherché est donc $${texAnswer}$.`;
107
112
  return { str };
108
113
  },
109
114
  }),
@@ -111,17 +116,21 @@ ${alignTex([
111
116
  getCorrectionStuff: (initial, reason, firstRank, ...otherArgs) => {
112
117
  const [valueThreshold, inequationSymbol] = otherArgs;
113
118
  const { str: strRaw } = variationFindThreshold.getCorrectionStuff(initial, reason, firstRank, ...otherArgs);
114
- const answerNode = variationFindThreshold.getAnswerNode(initial, reason, firstRank, ...otherArgs);
119
+ const { answerNode, rankNode } = variationFindThreshold.getAnswerStuff(initial, reason, firstRank, ...otherArgs);
120
+ const texRankSimplified = rankNode.evaluate().frPretty(0);
121
+ const texAnswer = [
122
+ ...new Set([answerNode.toTex(), answerNode.evaluate().frPretty(2)]),
123
+ ].join(" = ");
115
124
  const str = `${strRaw}
116
125
 
117
126
  On note $p$ le rang recherché. On a :
118
127
 
119
128
  ${alignTex([
120
- [`u_p`, inequationSymbol.symbol, valueThreshold.frenchify()],
129
+ [`u_p`, inequationSymbol.symbol, valueThreshold.frPretty(2)],
121
130
  [
122
131
  `${add(initial, multiply(reason, substract("p".toTree(), firstRank).simplify())).toTex()}`,
123
132
  inequationSymbol.symbol,
124
- valueThreshold.frenchify(),
133
+ valueThreshold.frPretty(2),
125
134
  ],
126
135
  ])}
127
136
 
@@ -138,9 +147,9 @@ ${(() => {
138
147
  })()}
139
148
  $$
140
149
 
141
- Le rang $p$ recherché est donc $${answerNode.toTex()}$.
150
+ Le rang $p$ est donc $${texRankSimplified}$.
142
151
 
143
- `;
152
+ Le nombre recherché est donc $${texAnswer}$.`;
144
153
  return { str };
145
154
  },
146
155
  }),
@@ -178,10 +187,14 @@ const templatesSituationsArithmetic = [
178
187
  values,
179
188
  };
180
189
  },
190
+ rankDecoder: {
191
+ targetFromRank: (rank, _firstRank) => rank.toTree(),
192
+ rankFromTarget: (nodeTarget, _firstRank) => nodeTarget.evaluate(),
193
+ },
181
194
  getStrSituation: (initial, reason, firstRank, superfluousData) => {
182
195
  if (superfluousData === undefined) {
183
- return `On suppose qu'une plante, d'une hauteur initiale (jour $${firstRank.frenchify()}$) de $${initial.frenchify()}\\ \\textrm{cm}$,
184
- croît chaque jour de $${reason.frenchify()}\\ \\textrm{cm}$.
196
+ return `On suppose qu'une plante, d'une hauteur initiale (jour $${firstRank.frPretty(2)}$) de $${initial.frPretty(2)}\\ \\textrm{cm}$,
197
+ croît chaque jour de $${reason.frPretty(2)}\\ \\textrm{cm}$.
185
198
  On note $u_n$ la hauteur de la plante relevée le jour $n$, en $\\textrm{cm}$.`;
186
199
  }
187
200
  else {
@@ -189,18 +202,18 @@ On note $u_n$ la hauteur de la plante relevée le jour $n$, en $\\textrm{cm}$.`;
189
202
  case 0:
190
203
  {
191
204
  const [wateringPeriodInDays] = superfluousData.values;
192
- return `On suppose qu'une plante, d'une hauteur initiale (jour $${firstRank.frenchify()}$) de $${initial.frenchify()}\\ \\textrm{cm}$ et
193
- arrosée en moyenne tous les $${wateringPeriodInDays.frenchify()}$ jours,
194
- croît chaque jour de $${reason.frenchify()}\\ \\textrm{cm}$.
205
+ return `On suppose qu'une plante, d'une hauteur initiale (jour $${firstRank.frPretty(2)}$) de $${initial.frPretty(2)}\\ \\textrm{cm}$ et
206
+ arrosée en moyenne tous les $${wateringPeriodInDays.frPretty(2)}$ jours,
207
+ croît chaque jour de $${reason.frPretty(2)}\\ \\textrm{cm}$.
195
208
  On note $u_n$ la hauteur de la plante relevée le jour $n$, en $\\textrm{cm}$.`;
196
209
  }
197
210
  break;
198
211
  case 1:
199
212
  {
200
213
  const [potDiameterInCm] = superfluousData.values;
201
- return `On suppose qu'on a mis une plante dans un pot de diamètre $${potDiameterInCm.frenchify()} \\ \\textrm{cm}$.
202
- La plante a alors une hauteur initiale (jour $${firstRank.frenchify()}$) de $${initial.frenchify()}\\ \\textrm{cm}$.
203
- La plante croît chaque jour de $${reason.frenchify()}\\ \\textrm{cm}$.
214
+ return `On suppose qu'on a mis une plante dans un pot de diamètre $${potDiameterInCm.frPretty(2)} \\ \\textrm{cm}$.
215
+ La plante a alors une hauteur initiale (jour $${firstRank.frPretty(2)}$) de $${initial.frPretty(2)}\\ \\textrm{cm}$.
216
+ La plante croît chaque jour de $${reason.frPretty(2)}\\ \\textrm{cm}$.
204
217
  On note $u_n$ la hauteur de la plante relevée le jour $n$, en $\\textrm{cm}$.`;
205
218
  }
206
219
  break;
@@ -216,8 +229,8 @@ On note $u_n$ la hauteur de la plante relevée le jour $n$, en $\\textrm{cm}$.`;
216
229
  Inspire toi de ce calcul pour déterminer la hauteur de la plante au bout de $${getStrFactor(firstRank)}$ jours.`,
217
230
  getCorrectionStuff: (initial, reason, _firstRank) => {
218
231
  return {
219
- str: `Chaque jour, la plante gagne $${reason.frenchify()}\\ \\textrm{cm}$.
220
- La hauteur de la plante relevée chaque jour, en $\\textrm{cm}$, est donc une suite arithmétique de premier terme $${initial.frenchify()}$ et de raison $${reason.frenchify()}$.`,
232
+ str: `Chaque jour, la plante gagne $${reason.frPretty(2)}\\ \\textrm{cm}$.
233
+ La hauteur de la plante relevée chaque jour, en $\\textrm{cm}$, est donc une suite arithmétique de premier terme $${initial.frPretty(2)}$ et de raison $${reason.frPretty(2)}$.`,
221
234
  };
222
235
  },
223
236
  },
@@ -231,8 +244,8 @@ Déduis-en comment calculer $u_{n+1}$ à partir de $u_n$.`,
231
244
  const target2 = 11;
232
245
  const [rank1, rank2] = [target1, target2].map((target) => target + firstRank);
233
246
  return {
234
- str: `Chaque jour, la plante gagne $${reason.frenchify()}\\ \\textrm{cm}$.
235
- Par exemple, la hauteur de la plante le jour $${target2.frenchify()}$ est égale à celle du jour $${target1.frenchify()}$ augmentée de $${reason.frenchify()}\\ \\textrm{cm}$.`,
247
+ str: `Chaque jour, la plante gagne $${reason.frPretty(2)}\\ \\textrm{cm}$.
248
+ Par exemple, la hauteur de la plante le jour $${target2.frPretty(2)}$ est égale à celle du jour $${target1.frPretty(2)}$ augmentée de $${reason.frPretty(2)}\\ \\textrm{cm}$.`,
236
249
  rank1,
237
250
  rank2,
238
251
  };
@@ -248,34 +261,36 @@ Par exemple, la hauteur de la plante le jour $${target2.frenchify()}$ est égale
248
261
  const target = rankAsked - firstRank;
249
262
  return `Quelle est la nature de la suite $u_n$ ?
250
263
 
251
- Utilise le terme général de $u_n$ pour déterminer la hauteur de la plante au bout de $${target.frenchify()}$ jours.`;
264
+ Utilise le terme général de $u_n$ pour déterminer la hauteur de la plante au bout de $${target.frPretty(2)}$ jours.`;
252
265
  },
253
266
  getCorrectionStuff: (initial, reason, _firstRank) => {
254
267
  return {
255
- str: `Chaque jour, la plante gagne $${reason.frenchify()}\\ \\textrm{cm}$.
256
- La hauteur de la plante relevée chaque jour, en $\\textrm{cm}$, est donc une suite arithmétique de premier terme $${initial.frenchify()}$ et de raison $${reason.frenchify()}$.`,
268
+ str: `Chaque jour, la plante gagne $${reason.frPretty(2)}\\ \\textrm{cm}$.
269
+ La hauteur de la plante relevée chaque jour, en $\\textrm{cm}$, est donc une suite arithmétique de premier terme $${initial.frPretty(2)}$ et de raison $${reason.frPretty(2)}$.`,
257
270
  };
258
271
  },
259
272
  },
260
273
  variationFindRank: {
261
274
  getStrQuestion: (_initial, _reason, _firstRank, ...otherArgs) => {
262
275
  const [valueAsked] = otherArgs;
263
- return `Quel jour la plante aura-t-elle atteint une hauteur de $${round(valueAsked, 2).frenchify()} \\ \\textrm{cm}$ ?`;
276
+ return `Quel jour la plante aura-t-elle atteint une hauteur de $${round(valueAsked, 2).frPretty(2)} \\ \\textrm{cm}$ ?`;
264
277
  },
265
- getAnswerNode: (initial, reason, firstRank, ...otherArgs) => {
266
- const [valueAsked] = otherArgs;
267
- return seqArithmeticUtils.getAnswerNodeRandomRank(initial, reason, firstRank, valueAsked);
278
+ getAnswerStuff: (initial, reason, firstRank, ...otherArgs) => {
279
+ const [valueAsked, rankDecoder] = otherArgs;
280
+ const rankNode = seqArithmeticUtils.getAnswerNodeRandomRank(initial, reason, firstRank, valueAsked);
281
+ const answerNode = rankDecoder.targetFromRank(rankNode.evaluate(), firstRank);
282
+ return { answerNode, rankNode };
268
283
  },
269
284
  getHint: (_firstRank, ...otherArgs) => {
270
285
  const [valueAsked] = otherArgs;
271
286
  return `Quelle est la nature de la suite $u_n$ ?
272
287
 
273
- Utilise le terme général de $u_n$ pour déterminer quand $u_n = ${valueAsked.frenchify()}$.`;
288
+ Utilise le terme général de $(u_n)$ pour déterminer $n$ tel que $u_n = ${valueAsked.frPretty(2)}$.`;
274
289
  },
275
290
  getCorrectionStuff: (initial, reason, _firstRank) => {
276
291
  return {
277
- str: `Chaque jour, la plante gagne $${reason.frenchify()}\\ \\textrm{cm}$.
278
- La hauteur de la plante relevée chaque jour, en $\\textrm{cm}$, est donc une suite arithmétique de premier terme $${initial.frenchify()}$ et de raison $${reason.frenchify()}$.`,
292
+ str: `Chaque jour, la plante gagne $${reason.frPretty(2)}\\ \\textrm{cm}$.
293
+ La hauteur de la plante relevée chaque jour, en $\\textrm{cm}$, est donc une suite arithmétique de premier terme $${initial.frPretty(2)}$ et de raison $${reason.frPretty(2)}$.`,
279
294
  };
280
295
  },
281
296
  },
@@ -286,15 +301,17 @@ La hauteur de la plante relevée chaque jour, en $\\textrm{cm}$, est donc une su
286
301
  switch (inequationSymbol.symbol) {
287
302
  case "<":
288
303
  case "\\le":
289
- return `Quel sera le dernier jour où la hauteur de la plante sera ${isStrict ? "strictement" : ""} plus petite que $${valueThreshold.frenchify()} \\ \\textrm{cm}$ ?`;
304
+ return `Quel sera le dernier jour où la hauteur de la plante sera ${isStrict ? "strictement" : ""} en dessous de $${valueThreshold.frPretty(2)} \\ \\textrm{cm}$ ?`;
290
305
  case ">":
291
306
  case "\\ge":
292
- return `Quel sera le premier jour où la hauteur de la plante sera ${isStrict ? "strictement" : ""} plus grande que $${valueThreshold.frenchify()} \\ \\textrm{cm}$ ?`;
307
+ return `Quel sera le jour où la hauteur de la plante ${isStrict ? "dépassera" : "atteindra ou dépassera"} $${valueThreshold.frPretty(2)} \\ \\textrm{cm}$ ?`;
293
308
  }
294
309
  },
295
- getAnswerNode: (initial, reason, firstRank, ...otherArgs) => {
296
- const [valueThreshold, inequationSymbol] = otherArgs;
297
- return seqArithmeticUtils.getAnswerNodeThresholdRank(initial, reason, firstRank, valueThreshold, inequationSymbol);
310
+ getAnswerStuff: (initial, reason, firstRank, ...otherArgs) => {
311
+ const [valueThreshold, inequationSymbol, rankDecoder] = otherArgs;
312
+ const rankNode = seqArithmeticUtils.getAnswerNodeThresholdRank(initial, reason, firstRank, valueThreshold, inequationSymbol);
313
+ const answerNode = rankDecoder.targetFromRank(rankNode.evaluate(), firstRank);
314
+ return { answerNode, rankNode };
298
315
  },
299
316
  getHint: (_firstRank, ...otherArgs) => {
300
317
  const [valueThreshold, inequationSymbol, reason] = otherArgs;
@@ -311,12 +328,12 @@ La hauteur de la plante relevée chaque jour, en $\\textrm{cm}$, est donc une su
311
328
  })();
312
329
  return `Quelle est la nature de la suite $u_n$ ?
313
330
 
314
- Utilise le terme général de $(u_n)$ pour déterminer ${texP} $p$ tel que $u_p ${inequationSymbol.symbol} ${valueThreshold.frenchify()}$.`;
331
+ Utilise le terme général de $(u_n)$ pour déterminer ${texP} $p$ tel que $u_p ${inequationSymbol.symbol} ${valueThreshold.frPretty(2)}$.`;
315
332
  },
316
333
  getCorrectionStuff: (initial, reason, _firstRank) => {
317
334
  return {
318
- str: `Chaque jour, la plante gagne $${reason.frenchify()}\\ \\textrm{cm}$.
319
- La hauteur de la plante relevée chaque jour, en $\\textrm{cm}$, est donc une suite arithmétique de premier terme $${initial.frenchify()}$ et de raison $${reason.frenchify()}$.`,
335
+ str: `Chaque jour, la plante gagne $${reason.frPretty(2)}\\ \\textrm{cm}$.
336
+ La hauteur de la plante relevée chaque jour, en $\\textrm{cm}$, est donc une suite arithmétique de premier terme $${initial.frPretty(2)}$ et de raison $${reason.frPretty(2)}$.`,
320
337
  };
321
338
  },
322
339
  },
@@ -348,10 +365,14 @@ La hauteur de la plante relevée chaque jour, en $\\textrm{cm}$, est donc une su
348
365
  values,
349
366
  };
350
367
  },
368
+ rankDecoder: {
369
+ targetFromRank: (rank, firstRank) => (rank - firstRank).toTree(),
370
+ rankFromTarget: (nodeTarget, firstRank) => nodeTarget.evaluate() + firstRank,
371
+ },
351
372
  getStrSituation: (initial, reason, firstRank, superfluousData) => {
352
373
  if (superfluousData === undefined) {
353
- return `Une compagnie de taxis propose un tarif qui inclut un montant fixe de $${initial.frenchify()}\\ \\textrm{€}$
354
- et un montant variable de $${reason.frenchify()}\\ \\textrm{€}$ par kilomètre parcouru.
374
+ return `Une compagnie de taxis propose un tarif qui inclut un montant fixe de $${initial.frPretty(2)}\\ \\textrm{€}$
375
+ et un montant variable de $${reason.frPretty(2)}\\ \\textrm{€}$ par kilomètre parcouru.
355
376
  On note $u_n$ le prix payé (en $\\textrm{€}$) pour $${getStrFactor(firstRank)} \\ \\textrm{km}$ parcourus.`;
356
377
  }
357
378
  else {
@@ -359,18 +380,18 @@ On note $u_n$ le prix payé (en $\\textrm{€}$) pour $${getStrFactor(firstRank)
359
380
  case 0:
360
381
  {
361
382
  const [fuelConsumptionPer100Km] = superfluousData.values;
362
- return `Une compagnie de taxis propose un tarif qui inclut un montant fixe de $${initial.frenchify()}\\ \\textrm{€}$
363
- et un montant variable de $${reason.frenchify()}\\ \\textrm{€}$ par kilomètre parcouru.
364
- Le taxi consomme $${fuelConsumptionPer100Km.frenchify()} \\ \\textrm{L}$ d'essence tous les 100 kilomètres.
383
+ return `Une compagnie de taxis propose un tarif qui inclut un montant fixe de $${initial.frPretty(2)}\\ \\textrm{€}$
384
+ et un montant variable de $${reason.frPretty(2)}\\ \\textrm{€}$ par kilomètre parcouru.
385
+ Le taxi consomme $${fuelConsumptionPer100Km.frPretty(2)} \\ \\textrm{L}$ d'essence tous les 100 kilomètres.
365
386
  On note $u_n$ le prix payé (en $\\textrm{€}$) pour $${getStrFactor(firstRank)} \\ \\textrm{km}$ parcourus.`;
366
387
  }
367
388
  break;
368
389
  case 1:
369
390
  {
370
391
  const [distanceToNextCityInKm] = superfluousData.values;
371
- return `Une compagnie de taxis propose un tarif qui inclut un montant fixe de $${initial.frenchify()}\\ \\textrm{€}$
372
- et un montant variable de $${reason.frenchify()}\\ \\textrm{€}$ par kilomètre parcouru.
373
- La distance à la ville la plus proche est de $${distanceToNextCityInKm.frenchify()} \\ \\textrm{km}$.
392
+ return `Une compagnie de taxis propose un tarif qui inclut un montant fixe de $${initial.frPretty(2)}\\ \\textrm{€}$
393
+ et un montant variable de $${reason.frPretty(2)}\\ \\textrm{€}$ par kilomètre parcouru.
394
+ La distance à la ville la plus proche est de $${distanceToNextCityInKm.frPretty(2)} \\ \\textrm{km}$.
374
395
  On note $u_n$ le prix payé (en $\\textrm{€}$) pour $${getStrFactor(firstRank)} \\ \\textrm{km}$ parcourus.`;
375
396
  }
376
397
  break;
@@ -386,8 +407,8 @@ On note $u_n$ le prix payé (en $\\textrm{€}$) pour $${getStrFactor(firstRank)
386
407
  Inspire toi de ce calcul pour déterminer la hauteur de la plante au bout de $${getStrFactor(firstRank)} \\ \\textrm{km}$.`,
387
408
  getCorrectionStuff: (initial, reason, _firstRank) => {
388
409
  return {
389
- str: `Pour chaque kilomètre supplémentaire, la facture augmente de $${reason.frenchify()}\\ \\textrm{€}$.
390
- La facture est donc une suite arithmétique de premier terme $${initial.frenchify()}$ et de raison $${reason.frenchify()}$.`,
410
+ str: `Pour chaque kilomètre supplémentaire, la facture augmente de $${reason.frPretty(2)}\\ \\textrm{€}$.
411
+ La facture est donc une suite arithmétique de premier terme $${initial.frPretty(2)}$ et de raison $${reason.frPretty(2)}$.`,
391
412
  };
392
413
  },
393
414
  },
@@ -401,8 +422,8 @@ Déduis-en comment calculer $u_{n+1}$ à partir de $u_n$.`,
401
422
  const target2 = 11;
402
423
  const [rank1, rank2] = [target1, target2].map((target) => target + firstRank);
403
424
  return {
404
- str: `Pour chaque kilomètre supplémentaire, la facture augmente de $${reason.frenchify()}\\ \\textrm{€}$.
405
- Par exemple, la facture pour $${target2.frenchify()} \\ \\textrm{km}$ est égale à celle de $${target1.frenchify()} \\ \\textrm{km}$ augmentée de $${reason.frenchify()}\\ \\textrm{€}$.`,
425
+ str: `Pour chaque kilomètre supplémentaire, la facture augmente de $${reason.frPretty(2)}\\ \\textrm{€}$.
426
+ Par exemple, la facture pour $${target2.frPretty(2)} \\ \\textrm{km}$ est égale à celle de $${target1.frPretty(2)} \\ \\textrm{km}$ augmentée de $${reason.frPretty(2)}\\ \\textrm{€}$.`,
406
427
  rank1,
407
428
  rank2,
408
429
  };
@@ -418,34 +439,40 @@ Par exemple, la facture pour $${target2.frenchify()} \\ \\textrm{km}$ est égale
418
439
  const target = rankAsked - firstRank;
419
440
  return `Quelle est la nature de la suite $u_n$ ?
420
441
 
421
- Utilise le terme général de $u_n$ pour déterminer la facture pour $${target.frenchify()} \\ \\textrm{km}$.`;
442
+ Utilise le terme général de $u_n$ pour déterminer la facture pour $${target.frPretty(2)} \\ \\textrm{km}$.`;
422
443
  },
423
444
  getCorrectionStuff: (initial, reason, _firstRank) => {
424
445
  return {
425
- str: `Pour chaque kilomètre supplémentaire, la facture augmente de $${reason.frenchify()}\\ \\textrm{€}$.
426
- La facture est donc une suite arithmétique de premier terme $${initial.frenchify()}$ et de raison $${reason.frenchify()}$.`,
446
+ str: `Pour chaque kilomètre supplémentaire, la facture augmente de $${reason.frPretty(2)}\\ \\textrm{€}$.
447
+ La facture est donc une suite arithmétique de premier terme $${initial.frPretty(2)}$ et de raison $${reason.frPretty(2)}$.`,
427
448
  };
428
449
  },
429
450
  },
430
451
  variationFindRank: {
431
452
  getStrQuestion: (_initial, _reason, _firstRank, ...otherArgs) => {
432
453
  const [valueAsked] = otherArgs;
433
- return `Quel est le rang $p$ pour lequel $u_{p} = ${round(valueAsked, 2).frenchify()} \\ \\textrm{€}$ ?`;
434
- },
435
- getAnswerNode: (initial, reason, firstRank, ...otherArgs) => {
436
- const [valueAsked] = otherArgs;
437
- return seqArithmeticUtils.getAnswerNodeRandomRank(initial, reason, firstRank, valueAsked);
454
+ // return `Quel est le rang $p$ pour lequel $u_{p} = ${round(
455
+ // valueAsked,
456
+ // 2,
457
+ // ).frPretty(2)} \\ \\textrm{€}$ ?`;
458
+ return `Pour combien de kilomètres la facture sera-t-elle de $${round(valueAsked, 2).frPretty(2)} ?`;
459
+ },
460
+ getAnswerStuff: (initial, reason, firstRank, ...otherArgs) => {
461
+ const [valueThreshold, inequationSymbol, rankDecoder] = otherArgs;
462
+ const rankNode = seqArithmeticUtils.getAnswerNodeThresholdRank(initial, reason, firstRank, valueThreshold, inequationSymbol);
463
+ const answerNode = rankDecoder.targetFromRank(rankNode.evaluate(), firstRank);
464
+ return { answerNode, rankNode };
438
465
  },
439
466
  getHint: (_firstRank, ...otherArgs) => {
440
467
  const [valueAsked] = otherArgs;
441
468
  return `Quelle est la nature de la suite $(u_n)$ ?
442
469
 
443
- Utilise le terme général de $(u_n)$ pour déterminer quand $u_p = ${valueAsked.frenchify()}$.`;
470
+ Utilise le terme général de $(u_n)$ pour déterminer quand $u_p = ${valueAsked.frPretty(2)}$.`;
444
471
  },
445
472
  getCorrectionStuff: (initial, reason, _firstRank) => {
446
473
  return {
447
- str: `Pour chaque kilomètre supplémentaire, la facture augmente de $${reason.frenchify()}\\ \\textrm{€}$.
448
- La facture est donc une suite arithmétique de premier terme $${initial.frenchify()}$ et de raison $${reason.frenchify()}$.`,
474
+ str: `Pour chaque kilomètre supplémentaire, la facture augmente de $${reason.frPretty(2)}\\ \\textrm{€}$.
475
+ La facture est donc une suite arithmétique de premier terme $${initial.frPretty(2)}$ et de raison $${reason.frPretty(2)}$.`,
449
476
  };
450
477
  },
451
478
  },
@@ -456,15 +483,17 @@ La facture est donc une suite arithmétique de premier terme $${initial.frenchif
456
483
  switch (inequationSymbol.symbol) {
457
484
  case "<":
458
485
  case "\\le":
459
- return `Quel est le plus grand rang $p$ $u_{p}$ est ${isStrict ? "strictement" : ""} plus petit que $${valueThreshold.frenchify()} \\ \\textrm{€}$ ?`;
486
+ return `Quel est le nombre maximum de kilomètres que l'on peut parcourir sans que la facture ne dépasse $${valueThreshold.frPretty(2)} \\ \\textrm{€}$ ?`;
460
487
  case ">":
461
488
  case "\\ge":
462
- return `Quel est le plus petit rang $p$ $u_{p}$ est ${isStrict ? "strictement" : ""} plus grand que $${valueThreshold.frenchify()} \\ \\textrm{€}$ ?`;
489
+ return `Combien de kilomètres aura-t-on parcouru quand la facture viendra ${isStrict ? "de dépasser" : "d'égaler ou de dépasser"} $${valueThreshold.frPretty(2)} \\ \\textrm{€}$ ?`;
463
490
  }
464
491
  },
465
- getAnswerNode: (initial, reason, firstRank, ...otherArgs) => {
466
- const [valueThreshold, inequationSymbol] = otherArgs;
467
- return seqArithmeticUtils.getAnswerNodeThresholdRank(initial, reason, firstRank, valueThreshold, inequationSymbol);
492
+ getAnswerStuff: (initial, reason, firstRank, ...otherArgs) => {
493
+ const [valueThreshold, inequationSymbol, rankDecoder] = otherArgs;
494
+ const rankNode = seqArithmeticUtils.getAnswerNodeThresholdRank(initial, reason, firstRank, valueThreshold, inequationSymbol);
495
+ const answerNode = rankDecoder.targetFromRank(rankNode.evaluate(), firstRank);
496
+ return { answerNode, rankNode };
468
497
  },
469
498
  getHint: (_firstRank, ...otherArgs) => {
470
499
  const [valueThreshold, inequationSymbol, reason] = otherArgs;
@@ -481,12 +510,12 @@ La facture est donc une suite arithmétique de premier terme $${initial.frenchif
481
510
  })();
482
511
  return `Quelle est la nature de la suite $u_n$ ?
483
512
 
484
- Utilise le terme général de $(u_n)$ pour déterminer ${texP} $p$ tel que $u_p ${inequationSymbol.symbol} ${valueThreshold.frenchify()}$.`;
513
+ Utilise le terme général de $(u_n)$ pour déterminer ${texP} $p$ tel que $u_p ${inequationSymbol.symbol} ${valueThreshold.frPretty(2)}$.`;
485
514
  },
486
515
  getCorrectionStuff: (initial, reason, _firstRank) => {
487
516
  return {
488
- str: `Pour chaque kilomètre supplémentaire, la facture augmente de $${reason.frenchify()}\\ \\textrm{€}$.
489
- La facture est donc une suite arithmétique de premier terme $${initial.frenchify()}$ et de raison $${reason.frenchify()}$.`,
517
+ str: `Pour chaque kilomètre supplémentaire, la facture augmente de $${reason.frPretty(2)}\\ \\textrm{€}$.
518
+ La facture est donc une suite arithmétique de premier terme $${initial.frPretty(2)}$ et de raison $${reason.frPretty(2)}$.`,
490
519
  };
491
520
  },
492
521
  },
@@ -521,8 +550,8 @@ La facture est donc une suite arithmétique de premier terme $${initial.frenchif
521
550
  getStrSituation: (initial, reason, firstRank, superfluousData) => {
522
551
  if (superfluousData === undefined) {
523
552
  return `Pour l’électricité de sa maison, Jimmy paye
524
- un abonnement fixe de $${initial.frenchify()}\\ \\textrm{€}$
525
- puis il paye $${reason.frenchify()}\\ \\textrm{€}$ par kWh consommé.
553
+ un abonnement fixe de $${initial.frPretty(2)}\\ \\textrm{€}$
554
+ puis il paye $${reason.frPretty(2)}\\ \\textrm{€}$ par kWh consommé.
526
555
  On note $u_n$ la facture (en $\\textrm{€}$) pour $${getStrFactor(firstRank)} \\ \\textrm{kWh}$ consommés.`;
527
556
  }
528
557
  else {
@@ -531,9 +560,9 @@ On note $u_n$ la facture (en $\\textrm{€}$) pour $${getStrFactor(firstRank)} \
531
560
  {
532
561
  const [fridgeConsumptionPerMonth] = superfluousData.values;
533
562
  return `Pour l’électricité de sa maison, Jimmy paye
534
- un abonnement fixe de $${initial.frenchify()}\\ \\textrm{€}$
535
- puis il paye $${reason.frenchify()}\\ \\textrm{€}$ par kWh consommé.
536
- Son refrigétateur consomme $${fridgeConsumptionPerMonth.frenchify()} \\ \\textrm{kWh}$ tous les mois.
563
+ un abonnement fixe de $${initial.frPretty(2)}\\ \\textrm{€}$
564
+ puis il paye $${reason.frPretty(2)}\\ \\textrm{€}$ par kWh consommé.
565
+ Son refrigétateur consomme $${fridgeConsumptionPerMonth.frPretty(2)} \\ \\textrm{kWh}$ tous les mois.
537
566
  On note $u_n$ la facture (en $\\textrm{€}$) pour $${getStrFactor(firstRank)} \\ \\textrm{kWh}$ consommés.`;
538
567
  }
539
568
  break;
@@ -541,9 +570,9 @@ On note $u_n$ la facture (en $\\textrm{€}$) pour $${getStrFactor(firstRank)} \
541
570
  {
542
571
  const [internetBill] = superfluousData.values;
543
572
  return `Pour l’électricité de sa maison, Jimmy paye
544
- un abonnement fixe de $${initial.frenchify()}\\ \\textrm{€}$
545
- puis il paye $${reason.frenchify()}\\ \\textrm{€}$ par kWh consommé.
546
- Jimmy paye $${internetBill.frenchify()}\\ \\textrm{€}$ tous les mois pour son abonnement internet.
573
+ un abonnement fixe de $${initial.frPretty(2)}\\ \\textrm{€}$
574
+ puis il paye $${reason.frPretty(2)}\\ \\textrm{€}$ par kWh consommé.
575
+ Jimmy paye $${internetBill.frPretty(2)}\\ \\textrm{€}$ tous les mois pour son abonnement internet.
547
576
  On note $u_n$ la facture (en $\\textrm{€}$) pour $${getStrFactor(firstRank)} \\ \\textrm{kWh}$ consommés.`;
548
577
  }
549
578
  break;
@@ -552,6 +581,10 @@ On note $u_n$ la facture (en $\\textrm{€}$) pour $${getStrFactor(firstRank)} \
552
581
  }
553
582
  }
554
583
  },
584
+ rankDecoder: {
585
+ targetFromRank: (rank, firstRank) => (rank - firstRank).toTree(),
586
+ rankFromTarget: (nodeTarget, firstRank) => nodeTarget.evaluate() + firstRank,
587
+ },
555
588
  variationFindExplicitFormula: {
556
589
  getAnswerNode: seqArithmeticUtils.getAnswerNodeExplicitFormula,
557
590
  getHint: (firstRank) => `Quel calcul permet de trouver le prix payé pour $10 \\ \\textrm{kWh}$ ?
@@ -559,8 +592,8 @@ On note $u_n$ la facture (en $\\textrm{€}$) pour $${getStrFactor(firstRank)} \
559
592
  Inspire toi de ce calcul pour déterminer le prix à payer pour $${getStrFactor(firstRank)} \\ \\textrm{kWh}$.`,
560
593
  getCorrectionStuff: (initial, reason, _firstRank) => {
561
594
  return {
562
- str: `Pour chaque $\\textrm{kWh}$ supplémentaire, la facture augmente de $${reason.frenchify()}\\ \\textrm{€}$.
563
- La facture est donc une suite arithmétique de premier terme $${initial.frenchify()}$ et de raison $${reason.frenchify()}$.`,
595
+ str: `Pour chaque $\\textrm{kWh}$ supplémentaire, la facture augmente de $${reason.frPretty(2)}\\ \\textrm{€}$.
596
+ La facture est donc une suite arithmétique de premier terme $${initial.frPretty(2)}$ et de raison $${reason.frPretty(2)}$.`,
564
597
  };
565
598
  },
566
599
  },
@@ -574,8 +607,8 @@ Déduis-en comment calculer $u_{n+1}$ à partir de $u_n$.`,
574
607
  const target2 = 11;
575
608
  const [rank1, rank2] = [target1, target2].map((target) => target + firstRank);
576
609
  return {
577
- str: `Pour chaque $\\textrm{kWh}$ supplémentaire, la facture augmente de $${reason.frenchify()}\\ \\textrm{€}$.
578
- Par exemple, la facture pour $${target2.frenchify()} \\ \\textrm{kWh}$ est égale à celle de $${target1.frenchify()} \\ \\textrm{kWh}$ augmentée de $${reason.frenchify()}\\ \\textrm{€}$.`,
610
+ str: `Pour chaque $\\textrm{kWh}$ supplémentaire, la facture augmente de $${reason.frPretty(2)}\\ \\textrm{€}$.
611
+ Par exemple, la facture pour $${target2.frPretty(2)} \\ \\textrm{kWh}$ est égale à celle de $${target1.frPretty(2)} \\ \\textrm{kWh}$ augmentée de $${reason.frPretty(2)}\\ \\textrm{€}$.`,
579
612
  rank1,
580
613
  rank2,
581
614
  };
@@ -591,34 +624,40 @@ Par exemple, la facture pour $${target2.frenchify()} \\ \\textrm{kWh}$ est égal
591
624
  const target = rankAsked - firstRank;
592
625
  return `Quelle est la nature de la suite $u_n$ ?
593
626
 
594
- Utilise le terme général de $u_n$ pour déterminer la facture pour $${target.frenchify()} \\ \\textrm{kWh}$.`;
627
+ Utilise le terme général de $u_n$ pour déterminer la facture pour $${target.frPretty(2)} \\ \\textrm{kWh}$.`;
595
628
  },
596
629
  getCorrectionStuff: (initial, reason, _firstRank) => {
597
630
  return {
598
- str: `Pour chaque $\\textrm{kWh}$ supplémentaire, la facture augmente de $${reason.frenchify()}\\ \\textrm{€}$.
599
- La facture est donc une suite arithmétique de premier terme $${initial.frenchify()}$ et de raison $${reason.frenchify()}$.`,
631
+ str: `Pour chaque $\\textrm{kWh}$ supplémentaire, la facture augmente de $${reason.frPretty(2)}\\ \\textrm{€}$.
632
+ La facture est donc une suite arithmétique de premier terme $${initial.frPretty(2)}$ et de raison $${reason.frPretty(2)}$.`,
600
633
  };
601
634
  },
602
635
  },
603
636
  variationFindRank: {
604
637
  getStrQuestion: (_initial, _reason, _firstRank, ...otherArgs) => {
605
638
  const [valueAsked] = otherArgs;
606
- return `Quel est le rang $p$ pour lequel $u_{p} = ${round(valueAsked, 2).frenchify()} \\ \\textrm{€}$ ?`;
607
- },
608
- getAnswerNode: (initial, reason, firstRank, ...otherArgs) => {
609
- const [valueAsked] = otherArgs;
610
- return seqArithmeticUtils.getAnswerNodeRandomRank(initial, reason, firstRank, valueAsked);
639
+ // return `Quel est le rang $p$ pour lequel $u_{p} = ${round(
640
+ // valueAsked,
641
+ // 2,
642
+ // ).frPretty(2)} \\ \\textrm{€}$ ?`;
643
+ return `Pour combien de $\\textrm{kWh}$ la facture sera-t-elle de $${round(valueAsked, 2).frPretty(2)} \\ \\textrm{€}$ ?`;
644
+ },
645
+ getAnswerStuff: (initial, reason, firstRank, ...otherArgs) => {
646
+ const [valueAsked, rankDecoder] = otherArgs;
647
+ const rankNode = seqArithmeticUtils.getAnswerNodeRandomRank(initial, reason, firstRank, valueAsked);
648
+ const answerNode = rankDecoder.targetFromRank(rankNode.evaluate(), firstRank);
649
+ return { answerNode, rankNode };
611
650
  },
612
651
  getHint: (_firstRank, ...otherArgs) => {
613
652
  const [valueAsked] = otherArgs;
614
653
  return `Quelle est la nature de la suite $(u_n)$ ?
615
654
 
616
- Utilise le terme général de $(u_n)$ pour déterminer quand $u_p = ${valueAsked.frenchify()}$.`;
655
+ Utilise le terme général de $(u_n)$ pour déterminer quand $u_p = ${valueAsked.frPretty(2)}$.`;
617
656
  },
618
657
  getCorrectionStuff: (initial, reason, _firstRank) => {
619
658
  return {
620
- str: `Pour chaque $\\textrm{kWh}$ supplémentaire, la facture augmente de $${reason.frenchify()}\\ \\textrm{€}$.
621
- La facture est donc une suite arithmétique de premier terme $${initial.frenchify()}$ et de raison $${reason.frenchify()}$.`,
659
+ str: `Pour chaque $\\textrm{kWh}$ supplémentaire, la facture augmente de $${reason.frPretty(2)}\\ \\textrm{€}$.
660
+ La facture est donc une suite arithmétique de premier terme $${initial.frPretty(2)}$ et de raison $${reason.frPretty(2)}$.`,
622
661
  };
623
662
  },
624
663
  },
@@ -629,15 +668,17 @@ La facture est donc une suite arithmétique de premier terme $${initial.frenchif
629
668
  switch (inequationSymbol.symbol) {
630
669
  case "<":
631
670
  case "\\le":
632
- return `Quel est le plus grand rang $p$ où $u_{p}$ est ${isStrict ? "strictement" : ""} plus petit que $${valueThreshold.frenchify()} \\ \\textrm{€}$ ?`;
671
+ return `Quel est le nombre maximum de $\\textrm{kWh}$ que l'on peut consommer sans que la facture ne dépasse $${valueThreshold.frPretty(2)} \\ \\textrm{€}$ ?`;
633
672
  case ">":
634
673
  case "\\ge":
635
- return `Quel est le plus petit rang $p$ $u_{p}$ est ${isStrict ? "strictement" : ""} plus grand que $${valueThreshold.frenchify()} \\ \\textrm{€}$ ?`;
674
+ return `Combien de $\\textrm{kWh}$ aura-t-on consommé quand la facture viendra ${isStrict ? "de dépasser" : "d'égaler ou de dépasser"} $${valueThreshold.frPretty(2)} \\ \\textrm{€}$ ?`;
636
675
  }
637
676
  },
638
- getAnswerNode: (initial, reason, firstRank, ...otherArgs) => {
639
- const [valueThreshold, inequationSymbol] = otherArgs;
640
- return seqArithmeticUtils.getAnswerNodeThresholdRank(initial, reason, firstRank, valueThreshold, inequationSymbol);
677
+ getAnswerStuff: (initial, reason, firstRank, ...otherArgs) => {
678
+ const [valueThreshold, inequationSymbol, rankDecoder] = otherArgs;
679
+ const rankNode = seqArithmeticUtils.getAnswerNodeThresholdRank(initial, reason, firstRank, valueThreshold, inequationSymbol);
680
+ const answerNode = rankDecoder.targetFromRank(rankNode.evaluate(), firstRank);
681
+ return { answerNode, rankNode };
641
682
  },
642
683
  getHint: (_firstRank, ...otherArgs) => {
643
684
  const [valueThreshold, inequationSymbol, reason] = otherArgs;
@@ -654,12 +695,12 @@ La facture est donc une suite arithmétique de premier terme $${initial.frenchif
654
695
  })();
655
696
  return `Quelle est la nature de la suite $u_n$ ?
656
697
 
657
- Utilise le terme général de $(u_n)$ pour déterminer ${texP} $p$ tel que $u_p ${inequationSymbol.symbol} ${valueThreshold.frenchify()}$.`;
698
+ Utilise le terme général de $(u_n)$ pour déterminer ${texP} $p$ tel que $u_p ${inequationSymbol.symbol} ${valueThreshold.frPretty(2)}$.`;
658
699
  },
659
700
  getCorrectionStuff: (initial, reason, _firstRank) => {
660
701
  return {
661
- str: `Pour chaque $\\textrm{kWh}$ supplémentaire, la facture augmente de $${reason.frenchify()}\\ \\textrm{€}$.
662
- La facture est donc une suite arithmétique de premier terme $${initial.frenchify()}$ et de raison $${reason.frenchify()}$.`,
702
+ str: `Pour chaque $\\textrm{kWh}$ supplémentaire, la facture augmente de $${reason.frPretty(2)}\\ \\textrm{€}$.
703
+ La facture est donc une suite arithmétique de premier terme $${initial.frPretty(2)}$ et de raison $${reason.frPretty(2)}$.`,
663
704
  };
664
705
  },
665
706
  },
@@ -691,11 +732,15 @@ La facture est donc une suite arithmétique de premier terme $${initial.frenchif
691
732
  values,
692
733
  };
693
734
  },
735
+ rankDecoder: {
736
+ targetFromRank: (rank, firstRank) => (100 * (rank - firstRank)).toTree(),
737
+ rankFromTarget: (nodeTarget, firstRank) => nodeTarget.evaluate() / 100 + firstRank,
738
+ },
694
739
  getStrSituation: (initial, reason, firstRank, superfluousData) => {
695
740
  if (superfluousData === undefined) {
696
741
  return `Dany décide de partir au Sud de la France.
697
- Il part de Valenciennes où il fait $${initial.frenchify()} \\ \\textrm{°C}$.
698
- La température ambiante augmente de $${reason.frenchify()}\\ \\textrm{°C}$ à chaque centaine de $\\textrm{km}$ vers le Sud.
742
+ Il part de Valenciennes où il fait $${initial.frPretty(2)} \\ \\textrm{°C}$.
743
+ La température ambiante augmente de $${reason.frPretty(2)}\\ \\textrm{°C}$ à chaque centaine de $\\textrm{km}$ vers le Sud.
699
744
  On note $u_n$ la température ambiante (en $\\textrm{°C}$) pour $${getStrFactor(firstRank)}$ centaines de $\\textrm{km}$ parcourus vers le Sud.`;
700
745
  }
701
746
  else {
@@ -703,18 +748,18 @@ On note $u_n$ la température ambiante (en $\\textrm{°C}$) pour $${getStrFactor
703
748
  case 0:
704
749
  {
705
750
  const [fuelConsumptionPer100Km] = superfluousData.values;
706
- return `Dany décide de partir au Sud de la France. Il part de Valenciennes où il fait $${initial.frenchify()} \\ \\textrm{°C}$.
707
- La température ambiante augmente de $${reason.frenchify()}\\ \\textrm{°C}$ à chaque centaine de $\\textrm{km}$ vers le Sud.
708
- Sa voiture consomme $${fuelConsumptionPer100Km.frenchify()} \\ \\textrm{L}$ d'essence tous les 100 kilomètres.
751
+ return `Dany décide de partir au Sud de la France. Il part de Valenciennes où il fait $${initial.frPretty(2)} \\ \\textrm{°C}$.
752
+ La température ambiante augmente de $${reason.frPretty(2)}\\ \\textrm{°C}$ à chaque centaine de $\\textrm{km}$ vers le Sud.
753
+ Sa voiture consomme $${fuelConsumptionPer100Km.frPretty(2)} \\ \\textrm{L}$ d'essence tous les $100$ kilomètres.
709
754
  On note $u_n$ la température ambiante (en $\\textrm{°C}$) pour $${getStrFactor(firstRank)}$ centaines de $\\textrm{km}$ parcourus vers le Sud.`;
710
755
  }
711
756
  break;
712
757
  case 1:
713
758
  {
714
759
  const [distanceToNextBreakInKm] = superfluousData.values;
715
- return `Dany décide de partir au Sud de la France. Il part de Valenciennes où il fait $${initial.frenchify()} \\ \\textrm{°C}$.
716
- La température ambiante augmente de $${reason.frenchify()}\\ \\textrm{°C}$ à chaque centaine de $\\textrm{km}$ vers le Sud.
717
- Il fait une pause en moyenne tous les $${distanceToNextBreakInKm.frenchify()}$ kilomètres.
760
+ return `Dany décide de partir au Sud de la France. Il part de Valenciennes où il fait $${initial.frPretty(2)} \\ \\textrm{°C}$.
761
+ La température ambiante augmente de $${reason.frPretty(2)}\\ \\textrm{°C}$ à chaque centaine de $\\textrm{km}$ vers le Sud.
762
+ Il fait une pause en moyenne tous les $${distanceToNextBreakInKm.frPretty(2)}$ kilomètres.
718
763
  On note $u_n$ la température ambiante (en $\\textrm{°C}$) pour $${getStrFactor(firstRank)}$ centaines de $\\textrm{km}$ parcourus vers le Sud.`;
719
764
  }
720
765
  break;
@@ -730,12 +775,12 @@ On note $u_n$ la température ambiante (en $\\textrm{°C}$) pour $${getStrFactor
730
775
  Inspire toi de ce calcul pour déterminer la température pour $${getStrFactor(firstRank)}$ centaines de $\\textrm{km}$ parcourus.`,
731
776
  getCorrectionStuff: (initial, reason, firstRank) => {
732
777
  return {
733
- str: `Pour chaque centaine de $\\textrm{km}$ parcourue, la température augmente de $${reason.frenchify()} \\ \\textrm{°C}$.
734
- Au bout de $${getStrFactor(firstRank)}$ centaines de $\\textrm{km}$, la température augmente donc de $${getStrFactor(firstRank)} \\times ${reason.frenchify()} \\ \\textrm{°C}$.
778
+ str: `Pour chaque centaine de $\\textrm{km}$ parcourue, la température augmente de $${reason.frPretty(2)} \\ \\textrm{°C}$.
779
+ Au bout de $${getStrFactor(firstRank)}$ centaines de $\\textrm{km}$, la température augmente donc de $${getStrFactor(firstRank)} \\times ${reason.frPretty(2)} \\ \\textrm{°C}$.
735
780
 
736
- Au départ, la température est de $${initial.frenchify()} \\ \\textrm{°C}$.
781
+ Au départ, la température est de $${initial.frPretty(2)} \\ \\textrm{°C}$.
737
782
 
738
- La température, en $\\textrm{°C}$, est donc une suite arithmétique de premier terme $${initial.frenchify()}$ et de raison $${reason.frenchify()}$.`,
783
+ La température, en $\\textrm{°C}$, est donc une suite arithmétique de premier terme $${initial.frPretty(2)}$ et de raison $${reason.frPretty(2)}$.`,
739
784
  };
740
785
  },
741
786
  },
@@ -749,8 +794,8 @@ Déduis-en comment calculer $u_{n+1}$ à partir de $u_n$.`,
749
794
  const target2 = 400;
750
795
  const [rank1, rank2] = [target1, target2].map((target) => target / 100 + firstRank);
751
796
  return {
752
- str: `Pour chaque centaine de $\\textrm{km}$ supplémentaire, la température augmente de $${reason.frenchify()}\\ \\textrm{°C}$.
753
- Par exemple, la température après $${target2.frenchify()} \\ \\textrm{km}$ parcourus est égale à celle après $${target1.frenchify()} \\ \\textrm{km}$ augmentée de $${reason.frenchify()}\\ \\textrm{°C}$.`,
797
+ str: `Pour chaque centaine de $\\textrm{km}$ supplémentaire, la température augmente de $${reason.frPretty(2)}\\ \\textrm{°C}$.
798
+ Par exemple, la température après $${target2.frPretty(2)} \\ \\textrm{km}$ parcourus est égale à celle après $${target1.frPretty(2)} \\ \\textrm{km}$ augmentée de $${reason.frPretty(2)}\\ \\textrm{°C}$.`,
754
799
  rank1,
755
800
  rank2,
756
801
  };
@@ -766,34 +811,36 @@ Par exemple, la température après $${target2.frenchify()} \\ \\textrm{km}$ par
766
811
  const target = (rankAsked - firstRank) * 100;
767
812
  return `Quelle est la nature de la suite $u_n$ ?
768
813
 
769
- Utilise le terme général de $u_n$ pour déterminer la température pour $${target.frenchify()} \\ \\textrm{km}$ parcourus.`;
814
+ Utilise le terme général de $u_n$ pour déterminer la température pour $${target.frPretty(2)} \\ \\textrm{km}$ parcourus.`;
770
815
  },
771
816
  getCorrectionStuff: (initial, reason, _firstRank) => {
772
817
  return {
773
- str: `Pour chaque centaine de $\\textrm{km}$ supplémentaire, la température ambiante augmente de $${reason.frenchify()}\\ \\textrm{°C}$.
774
- La température ambiante est donc une suite arithmétique de premier terme $${initial.frenchify()}$ et de raison $${reason.frenchify()}$.`,
818
+ str: `Pour chaque centaine de $\\textrm{km}$ supplémentaire, la température ambiante augmente de $${reason.frPretty(2)}\\ \\textrm{°C}$.
819
+ La température ambiante est donc une suite arithmétique de premier terme $${initial.frPretty(2)}$ et de raison $${reason.frPretty(2)}$.`,
775
820
  };
776
821
  },
777
822
  },
778
823
  variationFindRank: {
779
824
  getStrQuestion: (_initial, _reason, _firstRank, ...otherArgs) => {
780
825
  const [valueAsked] = otherArgs;
781
- return `Quel est le rang $p$ pour lequel $u_{p} = ${round(valueAsked, 2).frenchify()} \\ \\textrm{}$ ?`;
826
+ return `Pour combien kilomètres parcourus $p$ la température sera-t-elle de $${round(valueAsked, 2).frPretty(2)} \\ \\textrm{°C}$ ?`;
782
827
  },
783
- getAnswerNode: (initial, reason, firstRank, ...otherArgs) => {
784
- const [valueAsked] = otherArgs;
785
- return seqArithmeticUtils.getAnswerNodeRandomRank(initial, reason, firstRank, valueAsked);
828
+ getAnswerStuff: (initial, reason, firstRank, ...otherArgs) => {
829
+ const [valueAsked, rankDecoder] = otherArgs;
830
+ const rankNode = seqArithmeticUtils.getAnswerNodeRandomRank(initial, reason, firstRank, valueAsked);
831
+ const answerNode = rankDecoder.targetFromRank(rankNode.evaluate(), firstRank);
832
+ return { answerNode, rankNode };
786
833
  },
787
834
  getHint: (_firstRank, ...otherArgs) => {
788
835
  const [valueAsked] = otherArgs;
789
836
  return `Quelle est la nature de la suite $(u_n)$ ?
790
837
 
791
- Utilise le terme général de $(u_n)$ pour déterminer quand $u_p = ${valueAsked.frenchify()}$.`;
838
+ Utilise le terme général de $(u_n)$ pour déterminer quand $u_p = ${valueAsked.frPretty(2)}$.`;
792
839
  },
793
840
  getCorrectionStuff: (initial, reason, _firstRank) => {
794
841
  return {
795
- str: `Pour chaque centaine de $\\textrm{km}$ supplémentaire, la température ambiante augmente de $${reason.frenchify()}\\ \\textrm{°C}$.
796
- La température ambiante est donc une suite arithmétique de premier terme $${initial.frenchify()}$ et de raison $${reason.frenchify()}$.`,
842
+ str: `Pour chaque centaine de $\\textrm{km}$ supplémentaire, la température ambiante augmente de $${reason.frPretty(2)}\\ \\textrm{°C}$.
843
+ La température ambiante est donc une suite arithmétique de premier terme $${initial.frPretty(2)}$ et de raison $${reason.frPretty(2)}$.`,
797
844
  };
798
845
  },
799
846
  },
@@ -804,15 +851,17 @@ La température ambiante est donc une suite arithmétique de premier terme $${in
804
851
  switch (inequationSymbol.symbol) {
805
852
  case "<":
806
853
  case "\\le":
807
- return `Quel est le plus grand rang $p$ $u_{p}$ est ${isStrict ? "strictement" : ""} plus petit que $${valueThreshold.frenchify()} \\ \\textrm{°C}$ ?`;
854
+ return `Quel est le nombre maximum de kilomètres que l'on peut parcourir sans que la température ne dépasse $${valueThreshold.frPretty(2)} \\ \\textrm{°C}$ ?`;
808
855
  case ">":
809
856
  case "\\ge":
810
- return `Quel est le plus petit rang $p$ $u_{p}$ est ${isStrict ? "strictement" : ""} plus grand que $${valueThreshold.frenchify()} \\ \\textrm{°C}$ ?`;
857
+ return `Combien de kilomètres aura-t-on parcouru quand la température viendra ${isStrict ? "de dépasser" : "d'égaler ou de dépasser"} $${valueThreshold.frPretty(2)} \\ \\textrm{°C}$ ?`;
811
858
  }
812
859
  },
813
- getAnswerNode: (initial, reason, firstRank, ...otherArgs) => {
814
- const [valueThreshold, inequationSymbol] = otherArgs;
815
- return seqArithmeticUtils.getAnswerNodeThresholdRank(initial, reason, firstRank, valueThreshold, inequationSymbol);
860
+ getAnswerStuff: (initial, reason, firstRank, ...otherArgs) => {
861
+ const [valueThreshold, inequationSymbol, rankDecoder] = otherArgs;
862
+ const rankNode = seqArithmeticUtils.getAnswerNodeThresholdRank(initial, reason, firstRank, valueThreshold, inequationSymbol);
863
+ const answerNode = rankDecoder.targetFromRank(rankNode.evaluate(), firstRank);
864
+ return { answerNode, rankNode };
816
865
  },
817
866
  getHint: (_firstRank, ...otherArgs) => {
818
867
  const [valueThreshold, inequationSymbol, reason] = otherArgs;
@@ -829,12 +878,12 @@ La température ambiante est donc une suite arithmétique de premier terme $${in
829
878
  })();
830
879
  return `Quelle est la nature de la suite $u_n$ ?
831
880
 
832
- Utilise le terme général de $(u_n)$ pour déterminer ${texP} $p$ tel que $u_p ${inequationSymbol.symbol} ${valueThreshold.frenchify()}$.`;
881
+ Utilise le terme général de $(u_n)$ pour déterminer ${texP} $p$ tel que $u_p ${inequationSymbol.symbol} ${valueThreshold.frPretty(2)}$.`;
833
882
  },
834
883
  getCorrectionStuff: (initial, reason, _firstRank) => {
835
884
  return {
836
- str: `Pour chaque centaine de $\\textrm{km}$ supplémentaire, la température ambiante augmente de $${reason.frenchify()}\\ \\textrm{°C}$.
837
- La température ambiante est donc une suite arithmétique de premier terme $${initial.frenchify()}$ et de raison $${reason.frenchify()}$.`,
885
+ str: `Pour chaque centaine de $\\textrm{km}$ supplémentaire, la température ambiante augmente de $${reason.frPretty(2)}\\ \\textrm{°C}$.
886
+ La température ambiante est donc une suite arithmétique de premier terme $${initial.frPretty(2)}$ et de raison $${reason.frPretty(2)}$.`,
838
887
  };
839
888
  },
840
889
  },
@@ -866,11 +915,15 @@ La température ambiante est donc une suite arithmétique de premier terme $${in
866
915
  values,
867
916
  };
868
917
  },
918
+ rankDecoder: {
919
+ targetFromRank: (rank, firstRank) => (rank - firstRank).toTree(),
920
+ rankFromTarget: (nodeTarget, firstRank) => nodeTarget.evaluate() + firstRank,
921
+ },
869
922
  getStrSituation: (initial, reason, firstRank, superfluousData) => {
870
923
  if (superfluousData === undefined) {
871
924
  return `Emma est salariée. Son salaire net était
872
- de $${initial.frenchify()}\\ \\textrm{€}$ à son entrée dans l'entreprise,
873
- et augmente de $${reason.frenchify()}$ € tous les ans.
925
+ de $${initial.frPretty(2)}\\ \\textrm{€}$ à son entrée dans l'entreprise,
926
+ et augmente de $${reason.frPretty(2)}$ € tous les ans.
874
927
  On note $u_n$ son salaire net (en $\\textrm{€}$) quand elle aura $${getStrFactor(firstRank)}$ années d'ancienneté.`;
875
928
  }
876
929
  else {
@@ -879,9 +932,9 @@ On note $u_n$ son salaire net (en $\\textrm{€}$) quand elle aura $${getStrFact
879
932
  {
880
933
  const [ageWhenHired] = superfluousData.values;
881
934
  return `Emma est salariée.
882
- Son salaire net était de $${initial.frenchify()}\\ \\textrm{€}$ à son entrée dans l'entreprise.
883
- Elle avait alors $${ageWhenHired.frenchify()}$ ans.
884
- Son salaire augmente de $${reason.frenchify()}\\ \\textrm{€}$ tous les ans.
935
+ Son salaire net était de $${initial.frPretty(2)}\\ \\textrm{€}$ à son entrée dans l'entreprise.
936
+ Elle avait alors $${ageWhenHired.frPretty(2)}$ ans.
937
+ Son salaire augmente de $${reason.frPretty(2)}\\ \\textrm{€}$ tous les ans.
885
938
 
886
939
  On note $u_n$ son salaire net (en $\\textrm{€}$) quand elle aura $${getStrFactor(firstRank)}$ années d'ancienneté.`;
887
940
  }
@@ -890,9 +943,9 @@ On note $u_n$ son salaire net (en $\\textrm{€}$) quand elle aura $${getStrFact
890
943
  {
891
944
  const [salaryOfCoworker] = superfluousData.values;
892
945
  return `Emma est salariée.
893
- Son salaire net était de $${initial.frenchify()}\\ \\textrm{€}$ à son entrée dans l'entreprise.
894
- Sa collègue Flora gagnait alors $${salaryOfCoworker.frenchify()} \\ \\textrm{€}$.
895
- Son salaire augmente de $${reason.frenchify()} \\ \\textrm{€}$ tous les ans.
946
+ Son salaire net était de $${initial.frPretty(2)}\\ \\textrm{€}$ à son entrée dans l'entreprise.
947
+ Sa collègue Flora gagnait alors $${salaryOfCoworker.frPretty(2)} \\ \\textrm{€}$.
948
+ Son salaire augmente de $${reason.frPretty(2)} \\ \\textrm{€}$ tous les ans.
896
949
 
897
950
  On note $u_n$ son salaire net (en $\\textrm{€}$) quand elle aura $${getStrFactor(firstRank)}$ années d'ancienneté.`;
898
951
  }
@@ -910,12 +963,12 @@ Inspire toi de ce calcul pour déterminer son salaire net pour $${getStrFactor(f
910
963
  `,
911
964
  getCorrectionStuff: (initial, reason, firstRank) => {
912
965
  return {
913
- str: `Chaque année, son salaire net augmente de $${reason.frenchify()}\\ \\textrm{€}$.
914
- Au bout de $${getStrFactor(firstRank)}$ années, son salaire net aura augmenté de $${getStrFactor(firstRank)} \\times ${reason.frenchify()}\\ \\textrm{€}$.
966
+ str: `Chaque année, son salaire net augmente de $${reason.frPretty(2)}\\ \\textrm{€}$.
967
+ Au bout de $${getStrFactor(firstRank)}$ années, son salaire net aura augmenté de $${getStrFactor(firstRank)} \\times ${reason.frPretty(2)}\\ \\textrm{€}$.
915
968
 
916
- Au départ, son salaire net était de $${initial.frenchify()}\\ \\textrm{€}$.
969
+ Au départ, son salaire net était de $${initial.frPretty(2)}\\ \\textrm{€}$.
917
970
 
918
- Le salaire d'Emma, en $\\textrm{€}$, est donc une suite arithmétique de premier terme $${initial.frenchify()}$ et de raison $${reason.frenchify()}$.`,
971
+ Le salaire d'Emma, en $\\textrm{€}$, est donc une suite arithmétique de premier terme $${initial.frPretty(2)}$ et de raison $${reason.frPretty(2)}$.`,
919
972
  };
920
973
  },
921
974
  },
@@ -929,8 +982,8 @@ Déduis-en comment calculer $u_{n+1}$ à partir de $u_n$.`,
929
982
  const target2 = 11;
930
983
  const [rank1, rank2] = [target1, target2].map((target) => target + firstRank);
931
984
  return {
932
- str: `Pour chaque année supplémentaire, le salaire d'Emma augmente de $${reason.frenchify()}\\ \\textrm{€}$.
933
- Par exemple, son salaire pour $${target2.frenchify()}$ ans d'ancienneté est égal à celui pour $${target1.frenchify()}$ ans augmenté de $${reason.frenchify()}\\ \\textrm{€}$.`,
985
+ str: `Pour chaque année supplémentaire, le salaire d'Emma augmente de $${reason.frPretty(2)}\\ \\textrm{€}$.
986
+ Par exemple, son salaire pour $${target2.frPretty(2)}$ ans d'ancienneté est égal à celui pour $${target1.frPretty(2)}$ ans augmenté de $${reason.frPretty(2)}\\ \\textrm{€}$.`,
934
987
  rank1,
935
988
  rank2,
936
989
  };
@@ -946,38 +999,40 @@ Par exemple, son salaire pour $${target2.frenchify()}$ ans d'ancienneté est ég
946
999
  const target = (rankAsked - firstRank) * 100;
947
1000
  return `Quelle est la nature de la suite $u_n$ ?
948
1001
 
949
- Utilise le terme général de $u_n$ pour déterminer le salaire d'Emma pour $${target.frenchify()}$ ans d'ancienneté.`;
1002
+ Utilise le terme général de $u_n$ pour déterminer le salaire d'Emma pour $${target.frPretty(2)}$ ans d'ancienneté.`;
950
1003
  },
951
1004
  getCorrectionStuff: (initial, reason, _firstRank) => {
952
1005
  return {
953
- str: `Pour chaque année supplémentaire, le salaire d'Emma augmente de $${reason.frenchify()}\\ \\textrm{€}$.
954
- Par exemple, son salaire pour $11$ ans d'ancienneté est égal à celui pour $10$ ans augmenté de $${reason.frenchify()}\\ \\textrm{€}$.
1006
+ str: `Pour chaque année supplémentaire, le salaire d'Emma augmente de $${reason.frPretty(2)}\\ \\textrm{€}$.
1007
+ Par exemple, son salaire pour $11$ ans d'ancienneté est égal à celui pour $10$ ans augmenté de $${reason.frPretty(2)}\\ \\textrm{€}$.
955
1008
 
956
- Au départ, son salaire net était de $${initial.frenchify()}\\ \\textrm{€}$.
1009
+ Au départ, son salaire net était de $${initial.frPretty(2)}\\ \\textrm{€}$.
957
1010
 
958
- Le salaire d'Emma, en $\\textrm{€}$, est donc une suite arithmétique de premier terme $${initial.frenchify()}$ et de raison $${reason.frenchify()}$.`,
1011
+ Le salaire d'Emma, en $\\textrm{€}$, est donc une suite arithmétique de premier terme $${initial.frPretty(2)}$ et de raison $${reason.frPretty(2)}$.`,
959
1012
  };
960
1013
  },
961
1014
  },
962
1015
  variationFindRank: {
963
1016
  getStrQuestion: (_initial, _reason, _firstRank, ...otherArgs) => {
964
1017
  const [valueAsked] = otherArgs;
965
- return `Quel est le rang $p$ pour lequel $u_{p} = ${round(valueAsked, 2).frenchify()} \\ \\textrm{€}$ ?`;
1018
+ return `Quelle est l'année le salaire d'Emma sera de $${round(valueAsked, 2).frPretty(2)} \\ \\textrm{€}$ ?`;
966
1019
  },
967
- getAnswerNode: (initial, reason, firstRank, ...otherArgs) => {
968
- const [valueAsked] = otherArgs;
969
- return seqArithmeticUtils.getAnswerNodeRandomRank(initial, reason, firstRank, valueAsked);
1020
+ getAnswerStuff: (initial, reason, firstRank, ...otherArgs) => {
1021
+ const [valueAsked, rankDecoder] = otherArgs;
1022
+ const rankNode = seqArithmeticUtils.getAnswerNodeRandomRank(initial, reason, firstRank, valueAsked);
1023
+ const answerNode = rankDecoder.targetFromRank(rankNode.evaluate(), firstRank);
1024
+ return { answerNode, rankNode };
970
1025
  },
971
1026
  getHint: (_firstRank, ...otherArgs) => {
972
1027
  const [valueAsked] = otherArgs;
973
1028
  return `Quelle est la nature de la suite $(u_n)$ ?
974
1029
 
975
- Utilise le terme général de $(u_n)$ pour déterminer quand $u_p = ${valueAsked.frenchify()}$.`;
1030
+ Utilise le terme général de $(u_n)$ pour déterminer quand $u_p = ${valueAsked.frPretty(2)}$.`;
976
1031
  },
977
1032
  getCorrectionStuff: (initial, reason, _firstRank) => {
978
1033
  return {
979
- str: `Pour chaque année supplémentaire, le salaire d'Emma augmente de $${reason.frenchify()}\\ \\textrm{€}$.
980
- Le salaire d'Emma, en $\\textrm{€}$, est donc une suite arithmétique de premier terme $${initial.frenchify()}$ et de raison $${reason.frenchify()}$.`,
1034
+ str: `Pour chaque année supplémentaire, le salaire d'Emma augmente de $${reason.frPretty(2)}\\ \\textrm{€}$.
1035
+ Le salaire d'Emma, en $\\textrm{€}$, est donc une suite arithmétique de premier terme $${initial.frPretty(2)}$ et de raison $${reason.frPretty(2)}$.`,
981
1036
  };
982
1037
  },
983
1038
  },
@@ -988,15 +1043,17 @@ Le salaire d'Emma, en $\\textrm{€}$, est donc une suite arithmétique de premi
988
1043
  switch (inequationSymbol.symbol) {
989
1044
  case "<":
990
1045
  case "\\le":
991
- return `Quel est le plus grand rang $p$ $u_{p}$ est ${isStrict ? "strictement" : ""} plus petit que $${valueThreshold.frenchify()} \\ \\textrm{€}$ ?`;
1046
+ return `Quelle sera la dernière année le salaire d'Emma sera ${isStrict ? "inférieur" : "inférieur ou égal"} à $${valueThreshold.frPretty(2)} \\ \\textrm{€}$ ?`;
992
1047
  case ">":
993
1048
  case "\\ge":
994
- return `Quel est le plus petit rang $p$ $u_{p}$ est ${isStrict ? "strictement" : ""} plus grand que $${valueThreshold.frenchify()} \\ \\textrm{€}$ ?`;
1049
+ return `Quelle sera l'année le salaire d'Emma ${isStrict ? "dépassera" : "égalera ou dépassera"} $${valueThreshold.frPretty(2)} \\ \\textrm{€}$ ?`;
995
1050
  }
996
1051
  },
997
- getAnswerNode: (initial, reason, firstRank, ...otherArgs) => {
998
- const [valueThreshold, inequationSymbol] = otherArgs;
999
- return seqArithmeticUtils.getAnswerNodeThresholdRank(initial, reason, firstRank, valueThreshold, inequationSymbol);
1052
+ getAnswerStuff: (initial, reason, firstRank, ...otherArgs) => {
1053
+ const [valueThreshold, inequationSymbol, rankDecoder] = otherArgs;
1054
+ const rankNode = seqArithmeticUtils.getAnswerNodeThresholdRank(initial, reason, firstRank, valueThreshold, inequationSymbol);
1055
+ const answerNode = rankDecoder.targetFromRank(rankNode.evaluate(), firstRank);
1056
+ return { answerNode, rankNode };
1000
1057
  },
1001
1058
  getHint: (_firstRank, ...otherArgs) => {
1002
1059
  const [valueThreshold, inequationSymbol, reason] = otherArgs;
@@ -1013,12 +1070,12 @@ Le salaire d'Emma, en $\\textrm{€}$, est donc une suite arithmétique de premi
1013
1070
  })();
1014
1071
  return `Quelle est la nature de la suite $u_n$ ?
1015
1072
 
1016
- Utilise le terme général de $(u_n)$ pour déterminer ${texP} $p$ tel que $u_p ${inequationSymbol.symbol} ${valueThreshold.frenchify()}$.`;
1073
+ Utilise le terme général de $(u_n)$ pour déterminer ${texP} $p$ tel que $u_p ${inequationSymbol.symbol} ${valueThreshold.frPretty(2)}$.`;
1017
1074
  },
1018
1075
  getCorrectionStuff: (initial, reason, _firstRank) => {
1019
1076
  return {
1020
- str: `Pour chaque année supplémentaire, le salaire d'Emma augmente de $${reason.frenchify()}\\ \\textrm{€}$.
1021
- Le salaire d'Emma, en $\\textrm{€}$, est donc une suite arithmétique de premier terme $${initial.frenchify()}$ et de raison $${reason.frenchify()}$.`,
1077
+ str: `Pour chaque année supplémentaire, le salaire d'Emma augmente de $${reason.frPretty(2)}\\ \\textrm{€}$.
1078
+ Le salaire d'Emma, en $\\textrm{€}$, est donc une suite arithmétique de premier terme $${initial.frPretty(2)}$ et de raison $${reason.frPretty(2)}$.`,
1022
1079
  };
1023
1080
  },
1024
1081
  },
@@ -1053,10 +1110,14 @@ Le salaire d'Emma, en $\\textrm{€}$, est donc une suite arithmétique de premi
1053
1110
  values,
1054
1111
  };
1055
1112
  },
1113
+ rankDecoder: {
1114
+ targetFromRank: (rank, firstRank) => (rank - firstRank).toTree(),
1115
+ rankFromTarget: (nodeTarget, firstRank) => nodeTarget.evaluate() + firstRank,
1116
+ },
1056
1117
  getStrSituation: (initial, reason, firstRank, superfluousData) => {
1057
1118
  if (superfluousData === undefined) {
1058
- return `Manon a gagné un peu d'argent cet été. Début septembre, elle a $${initial.frenchify()}\\ \\textrm{€}$ d'économies.
1059
- Chaque semaine, elle dépense en moyenne $${(-reason).frenchify()}\\ \\textrm{€}$ pour ses loisirs.
1119
+ return `Manon a gagné un peu d'argent cet été. Début septembre, elle a $${initial.frPretty(2)}\\ \\textrm{€}$ d'économies.
1120
+ Chaque semaine, elle dépense en moyenne $${(-reason).frPretty(2)}\\ \\textrm{€}$ pour ses loisirs.
1060
1121
  On note $u_n$ le montant de ses économies (en $\\textrm{€}$), $${getStrFactor(firstRank)}$ semaines après le début de septembre.`;
1061
1122
  }
1062
1123
  else {
@@ -1064,17 +1125,17 @@ On note $u_n$ le montant de ses économies (en $\\textrm{€}$), $${getStrFactor
1064
1125
  case 0:
1065
1126
  {
1066
1127
  const [numberOfFriends] = superfluousData.values;
1067
- return `Manon a gagné un peu d'argent cet été. Début septembre, elle a $${initial.frenchify()}\\ \\textrm{€}$ d'économies.
1128
+ return `Manon a gagné un peu d'argent cet été. Début septembre, elle a $${initial.frPretty(2)}\\ \\textrm{€}$ d'économies.
1068
1129
  Elle sort souvent avec ses $${numberOfFriends}$ amis.
1069
- Chaque semaine, elle dépense en moyenne $${(-reason).frenchify()}\\ \\textrm{€}$ pour ses loisirs.
1130
+ Chaque semaine, elle dépense en moyenne $${(-reason).frPretty(2)}\\ \\textrm{€}$ pour ses loisirs.
1070
1131
  On note $u_n$ le montant de ses économies (en $\\textrm{€}$), $${getStrFactor(firstRank)}$ semaines après le début de septembre.`;
1071
1132
  }
1072
1133
  break;
1073
1134
  case 1:
1074
1135
  {
1075
1136
  const [pocketMoneyOfFriend] = superfluousData.values;
1076
- return `Manon a gagné un peu d'argent cet été. Début septembre, elle a $${initial.frenchify()}\\ \\textrm{€}$ d'économies.
1077
- Chaque semaine, elle dépense en moyenne $${(-reason).frenchify()}\\ \\textrm{€}$ pour ses loisirs.
1137
+ return `Manon a gagné un peu d'argent cet été. Début septembre, elle a $${initial.frPretty(2)}\\ \\textrm{€}$ d'économies.
1138
+ Chaque semaine, elle dépense en moyenne $${(-reason).frPretty(2)}\\ \\textrm{€}$ pour ses loisirs.
1078
1139
  Sa meilleure amie à $${pocketMoneyOfFriend}\\ \\textrm{€}$ d'argent de poche toutes les semaines.
1079
1140
  On note $u_n$ le montant de ses économies (en $\\textrm{€}$), $${getStrFactor(firstRank)}$ semaines après le début de septembre.`;
1080
1141
  }
@@ -1092,12 +1153,12 @@ Inspire toi de ce calcul pour déterminer le montant de ses économies $${getStr
1092
1153
  `,
1093
1154
  getCorrectionStuff: (initial, reason, firstRank) => {
1094
1155
  return {
1095
- str: `Chaque semaine, ses économies diminuent de $${(-reason).frenchify()}\\ \\textrm{€}$.
1096
- Au bout de $${getStrFactor(firstRank)}$ semaines, ses économies auront diminué de $${getStrFactor(firstRank)} \\times ${(-reason).frenchify()}\\ \\textrm{€}$.
1156
+ str: `Chaque semaine, ses économies diminuent de $${(-reason).frPretty(2)}\\ \\textrm{€}$.
1157
+ Au bout de $${getStrFactor(firstRank)}$ semaines, ses économies auront diminué de $${getStrFactor(firstRank)} \\times ${(-reason).frPretty(2)}\\ \\textrm{€}$.
1097
1158
 
1098
- Au départ, le montant de ses économies était de $${initial.frenchify()}\\ \\textrm{€}$.
1159
+ Au départ, le montant de ses économies était de $${initial.frPretty(2)}\\ \\textrm{€}$.
1099
1160
 
1100
- Le montant des économies de Manon, en $\\textrm{€}$, est donc une suite arithmétique de premier terme $${initial.frenchify()}$ et de raison $${reason.frenchify()}$.`,
1161
+ Le montant des économies de Manon, en $\\textrm{€}$, est donc une suite arithmétique de premier terme $${initial.frPretty(2)}$ et de raison $${reason.frPretty(2)}$.`,
1101
1162
  };
1102
1163
  },
1103
1164
  },
@@ -1111,8 +1172,8 @@ Déduis-en comment calculer $u_{n+1}$ à partir de $u_n$.`,
1111
1172
  const target2 = 11;
1112
1173
  const [rank1, rank2] = [target1, target2].map((target) => target + firstRank);
1113
1174
  return {
1114
- str: `Après chaque semaine de dépenses supplémentaire, les économies de Manon diminuent de $${(-reason).frenchify()}\\ \\textrm{€}$.
1115
- Par exemple, le montant de ses économies après $${target2.frenchify()}$ semaines est égal à celui pour $${target1.frenchify()}$ semaines diminué de $${(-reason).frenchify()}\\ \\textrm{€}$.`,
1175
+ str: `Après chaque semaine de dépenses supplémentaire, les économies de Manon diminuent de $${(-reason).frPretty(2)}\\ \\textrm{€}$.
1176
+ Par exemple, le montant de ses économies après $${target2.frPretty(2)}$ semaines est égal à celui pour $${target1.frPretty(2)}$ semaines diminué de $${(-reason).frPretty(2)}\\ \\textrm{€}$.`,
1116
1177
  rank1,
1117
1178
  rank2,
1118
1179
  };
@@ -1128,38 +1189,40 @@ Par exemple, le montant de ses économies après $${target2.frenchify()}$ semain
1128
1189
  const target = rankAsked - firstRank;
1129
1190
  return `Quelle est la nature de la suite $u_n$ ?
1130
1191
 
1131
- Utilise le terme général de $u_n$ pour déterminer le montant des économies de Manon $${target.frenchify()}$ semaines après le début de septembre.`;
1192
+ Utilise le terme général de $u_n$ pour déterminer le montant des économies de Manon $${target.frPretty(2)}$ semaines après le début de septembre.`;
1132
1193
  },
1133
1194
  getCorrectionStuff: (initial, reason, _firstRank, ..._otherArgs) => {
1134
1195
  const target1 = 10;
1135
1196
  const target2 = 11;
1136
1197
  return {
1137
- str: `Après chaque semaine de dépenses supplémentaire, les économies de Manon diminuent de $${(-reason).frenchify()}\\ \\textrm{€}$.
1138
- Par exemple, le montant de ses économies après $${target2.frenchify()}$ semaines est égal à celui pour $${target1.frenchify()}$ semaines diminué de $${(-reason).frenchify()}\\ \\textrm{€}$.
1198
+ str: `Après chaque semaine de dépenses supplémentaire, les économies de Manon diminuent de $${(-reason).frPretty(2)}\\ \\textrm{€}$.
1199
+ Par exemple, le montant de ses économies après $${target2.frPretty(2)}$ semaines est égal à celui pour $${target1.frPretty(2)}$ semaines diminué de $${(-reason).frPretty(2)}\\ \\textrm{€}$.
1139
1200
 
1140
- Le montant des économies de Manon, en $\\textrm{€}$, est donc une suite arithmétique de premier terme $${initial.frenchify()}$ et de raison $${reason.frenchify()}$.`,
1201
+ Le montant des économies de Manon, en $\\textrm{€}$, est donc une suite arithmétique de premier terme $${initial.frPretty(2)}$ et de raison $${reason.frPretty(2)}$.`,
1141
1202
  };
1142
1203
  },
1143
1204
  },
1144
1205
  variationFindRank: {
1145
1206
  getStrQuestion: (_initial, _reason, _firstRank, ...otherArgs) => {
1146
1207
  const [valueAsked] = otherArgs;
1147
- return `Quel est le rang $p$ pour lequel $u_{p} = ${round(valueAsked, 2).frenchify()} \\ \\textrm{€}$ ?`;
1208
+ return `Après combien de semaines les économies de Manon seront elles de $${round(valueAsked, 2).frPretty(2)} \\ \\textrm{€}$ ?`;
1148
1209
  },
1149
- getAnswerNode: (initial, reason, firstRank, ...otherArgs) => {
1150
- const [valueAsked] = otherArgs;
1151
- return seqArithmeticUtils.getAnswerNodeRandomRank(initial, reason, firstRank, valueAsked);
1210
+ getAnswerStuff: (initial, reason, firstRank, ...otherArgs) => {
1211
+ const [valueAsked, rankDecoder] = otherArgs;
1212
+ const rankNode = seqArithmeticUtils.getAnswerNodeRandomRank(initial, reason, firstRank, valueAsked);
1213
+ const answerNode = rankDecoder.targetFromRank(rankNode.evaluate(), firstRank);
1214
+ return { answerNode, rankNode };
1152
1215
  },
1153
1216
  getHint: (_firstRank, ...otherArgs) => {
1154
1217
  const [valueAsked] = otherArgs;
1155
1218
  return `Quelle est la nature de la suite $(u_n)$ ?
1156
1219
 
1157
- Utilise le terme général de $(u_n)$ pour déterminer quand $u_p = ${valueAsked.frenchify()}$.`;
1220
+ Utilise le terme général de $(u_n)$ pour déterminer quand $u_p = ${valueAsked.frPretty(2)}$.`;
1158
1221
  },
1159
1222
  getCorrectionStuff: (initial, reason, _firstRank) => {
1160
1223
  return {
1161
- str: `Après chaque semaine de dépenses supplémentaire, les économies de Manon diminuent de $${(-reason).frenchify()}\\ \\textrm{€}$.
1162
- Le montant des économies de Manon, en $\\textrm{€}$, est donc une suite arithmétique de premier terme $${initial.frenchify()}$ et de raison $${reason.frenchify()}$.`,
1224
+ str: `Après chaque semaine de dépenses supplémentaire, les économies de Manon diminuent de $${(-reason).frPretty(2)}\\ \\textrm{€}$.
1225
+ Le montant des économies de Manon, en $\\textrm{€}$, est donc une suite arithmétique de premier terme $${initial.frPretty(2)}$ et de raison $${reason.frPretty(2)}$.`,
1163
1226
  };
1164
1227
  },
1165
1228
  },
@@ -1170,15 +1233,17 @@ Le montant des économies de Manon, en $\\textrm{€}$, est donc une suite arith
1170
1233
  switch (inequationSymbol.symbol) {
1171
1234
  case "<":
1172
1235
  case "\\le":
1173
- return `Quel est le plus grand rang $p$$u_{p}$ est ${isStrict ? "strictement" : ""} plus petit que $${valueThreshold.frenchify()} \\ \\textrm{€}$ ?`;
1236
+ return `Quelle sera la dernière semaine (comptée à partir du moment elle commence à dépenser) où Manon aura ${isStrict ? "plus que" : "au moins"} $${valueThreshold.frPretty(2)} \\ \\textrm{€}$ ?`;
1174
1237
  case ">":
1175
1238
  case "\\ge":
1176
- return `Quel est le plus petit rang $p$$u_{p}$ est ${isStrict ? "strictement" : ""} plus grand que $${valueThreshold.frenchify()} \\ \\textrm{€}$ ?`;
1239
+ return `Quelle sera la semaine (comptée à partir du moment elle commence à dépenser) où ses économies seront ${isStrict ? "strictement inférieures" : "inférieures"} à $${valueThreshold.frPretty(2)} \\ \\textrm{€}$ ?`;
1177
1240
  }
1178
1241
  },
1179
- getAnswerNode: (initial, reason, firstRank, ...otherArgs) => {
1180
- const [valueThreshold, inequationSymbol] = otherArgs;
1181
- return seqArithmeticUtils.getAnswerNodeThresholdRank(initial, reason, firstRank, valueThreshold, inequationSymbol);
1242
+ getAnswerStuff: (initial, reason, firstRank, ...otherArgs) => {
1243
+ const [valueThreshold, inequationSymbol, rankDecoder] = otherArgs;
1244
+ const rankNode = seqArithmeticUtils.getAnswerNodeThresholdRank(initial, reason, firstRank, valueThreshold, inequationSymbol);
1245
+ const answerNode = rankDecoder.targetFromRank(rankNode.evaluate(), firstRank);
1246
+ return { answerNode, rankNode };
1182
1247
  },
1183
1248
  getHint: (_firstRank, ...otherArgs) => {
1184
1249
  const [valueThreshold, inequationSymbol, reason] = otherArgs;
@@ -1195,12 +1260,12 @@ Le montant des économies de Manon, en $\\textrm{€}$, est donc une suite arith
1195
1260
  })();
1196
1261
  return `Quelle est la nature de la suite $u_n$ ?
1197
1262
 
1198
- Utilise le terme général de $(u_n)$ pour déterminer ${texP} $p$ tel que $u_p ${inequationSymbol.symbol} ${valueThreshold.frenchify()}$.`;
1263
+ Utilise le terme général de $(u_n)$ pour déterminer ${texP} $p$ tel que $u_p ${inequationSymbol.symbol} ${valueThreshold.frPretty(2)}$.`;
1199
1264
  },
1200
1265
  getCorrectionStuff: (initial, reason, _firstRank) => {
1201
1266
  return {
1202
- str: `Après chaque semaine de dépenses supplémentaire, les économies de Manon diminuent de $${(-reason).frenchify()}\\ \\textrm{€}$.
1203
- Le montant des économies de Manon, en $\\textrm{€}$, est donc une suite arithmétique de premier terme $${initial.frenchify()}$ et de raison $${reason.frenchify()}$.`,
1267
+ str: `Après chaque semaine de dépenses supplémentaire, les économies de Manon diminuent de $${(-reason).frPretty(2)}\\ \\textrm{€}$.
1268
+ Le montant des économies de Manon, en $\\textrm{€}$, est donc une suite arithmétique de premier terme $${initial.frPretty(2)}$ et de raison $${reason.frPretty(2)}$.`,
1204
1269
  };
1205
1270
  },
1206
1271
  },
@@ -1232,10 +1297,14 @@ Le montant des économies de Manon, en $\\textrm{€}$, est donc une suite arith
1232
1297
  values,
1233
1298
  };
1234
1299
  },
1300
+ rankDecoder: {
1301
+ targetFromRank: (rank, firstRank) => (rank - firstRank).toTree(),
1302
+ rankFromTarget: (nodeTarget, firstRank) => nodeTarget.evaluate() + firstRank,
1303
+ },
1235
1304
  getStrSituation: (initial, reason, firstRank, superfluousData) => {
1236
1305
  if (superfluousData === undefined) {
1237
- return `Pablo joue à un jeu de quiz. Pour chaque question, le score commence à $${initial.frenchify()}$ points.
1238
- Puis il décroît de $${(-reason).frenchify()}$ points pour chaque seconde qui s'écoule avant que le joueur réponde correctement.
1306
+ return `Pablo joue à un jeu de quiz. Pour chaque question, le score commence à $${initial.frPretty(2)}$ points.
1307
+ Puis il décroît de $${(-reason).frPretty(2)}$ points pour chaque seconde qui s'écoule avant que le joueur réponde correctement.
1239
1308
  On note $u_n$ le score si l'on répond correctement $${getStrFactor(firstRank)}$ secondes après le début de la question.`;
1240
1309
  }
1241
1310
  else {
@@ -1243,8 +1312,8 @@ On note $u_n$ le score si l'on répond correctement $${getStrFactor(firstRank)}$
1243
1312
  case 0:
1244
1313
  {
1245
1314
  const [roundedMeanDuration] = superfluousData.values;
1246
- return `Pablo joue à un jeu de quiz. Pour chaque question, le score commence à $${initial.frenchify()}$ points.
1247
- Puis il décroît de $${(-reason).frenchify()}$ points pour chaque seconde qui s'écoule avant que le joueur réponde correctement.
1315
+ return `Pablo joue à un jeu de quiz. Pour chaque question, le score commence à $${initial.frPretty(2)}$ points.
1316
+ Puis il décroît de $${(-reason).frPretty(2)}$ points pour chaque seconde qui s'écoule avant que le joueur réponde correctement.
1248
1317
  Pablo met, la plupart du temps, $${roundedMeanDuration} \\ \\textrm{s}$ pour répondre.
1249
1318
  On note $u_n$ le score si l'on répond correctement $${getStrFactor(firstRank)}$ secondes après le début de la question.`;
1250
1319
  }
@@ -1252,8 +1321,8 @@ On note $u_n$ le score si l'on répond correctement $${getStrFactor(firstRank)}$
1252
1321
  case 1:
1253
1322
  {
1254
1323
  const [indexOfQuestion] = superfluousData.values;
1255
- return `Pablo joue à un jeu de quiz. Pour chaque question, le score commence à $${initial.frenchify()}$ points.
1256
- Puis il décroît de $${(-reason).frenchify()}$ points pour chaque seconde qui s'écoule avant que le joueur réponde correctement.
1324
+ return `Pablo joue à un jeu de quiz. Pour chaque question, le score commence à $${initial.frPretty(2)}$ points.
1325
+ Puis il décroît de $${(-reason).frPretty(2)}$ points pour chaque seconde qui s'écoule avant que le joueur réponde correctement.
1257
1326
  Pablo est actuellement à la question numéro $${indexOfQuestion}$.
1258
1327
  On note $u_n$ le score si l'on répond correctement $${getStrFactor(firstRank)}$ secondes après le début de la question.`;
1259
1328
  }
@@ -1271,12 +1340,12 @@ Inspire toi de ce calcul pour déterminer le score pour une durée de réponse d
1271
1340
  `,
1272
1341
  getCorrectionStuff: (initial, reason, firstRank) => {
1273
1342
  return {
1274
- str: `Chaque seconde, le score diminue de $${-reason.frenchify()}$ points.
1275
- Au bout de $${getStrFactor(firstRank)}$ secondes, le score aura diminué de $${getStrFactor(firstRank)} \\times ${-reason.frenchify()}$ points.
1343
+ str: `Chaque seconde, le score diminue de $${-reason.frPretty(2)}$ points.
1344
+ Au bout de $${getStrFactor(firstRank)}$ secondes, le score aura diminué de $${getStrFactor(firstRank)} \\times ${-reason.frPretty(2)}$ points.
1276
1345
 
1277
- Au départ, le score est de $${initial.frenchify()}$ points.
1346
+ Au départ, le score est de $${initial.frPretty(2)}$ points.
1278
1347
 
1279
- Le score est donc une suite arithmétique de premier terme $${initial.frenchify()}$ et de raison $${reason.frenchify()}$.`,
1348
+ Le score est donc une suite arithmétique de premier terme $${initial.frPretty(2)}$ et de raison $${reason.frPretty(2)}$.`,
1280
1349
  };
1281
1350
  },
1282
1351
  },
@@ -1290,8 +1359,8 @@ Déduis-en comment calculer $u_{n+1}$ à partir de $u_n$.`,
1290
1359
  const target2 = 11;
1291
1360
  const [rank1, rank2] = [target1, target2].map((target) => target + firstRank);
1292
1361
  return {
1293
- str: `Chaque seconde, le score diminue de $${-reason.frenchify()}$ points.
1294
- Par exemple, le score après $${target2.frenchify()} \\ \\textrm{s}$ est égal à celui après $${target1.frenchify()} \\ \\textrm{s}$ diminué de $${(-reason).frenchify()}$ points.`,
1362
+ str: `Chaque seconde, le score diminue de $${-reason.frPretty(2)}$ points.
1363
+ Par exemple, le score après $${target2.frPretty(2)} \\ \\textrm{s}$ est égal à celui après $${target1.frPretty(2)} \\ \\textrm{s}$ diminué de $${(-reason).frPretty(2)}$ points.`,
1295
1364
  rank1,
1296
1365
  rank2,
1297
1366
  };
@@ -1307,38 +1376,40 @@ Par exemple, le score après $${target2.frenchify()} \\ \\textrm{s}$ est égal
1307
1376
  const target = rankAsked - firstRank;
1308
1377
  return `Quelle est la nature de la suite $u_n$ ?
1309
1378
 
1310
- Utilise le terme général de $u_n$ pour déterminer le score $${target.frenchify()}$ secondes après le début de la question.`;
1379
+ Utilise le terme général de $u_n$ pour déterminer le score $${target.frPretty(2)}$ secondes après le début de la question.`;
1311
1380
  },
1312
1381
  getCorrectionStuff: (initial, reason, firstRank, ..._otherArgs) => {
1313
1382
  return {
1314
- str: `Chaque seconde, le score diminue de $${-reason.frenchify()}$ points.
1315
- Au bout de $${getStrFactor(firstRank)}$ secondes, le score aura diminué de $${getStrFactor(firstRank)} \\times ${-reason.frenchify()}$ points.
1383
+ str: `Chaque seconde, le score diminue de $${-reason.frPretty(2)}$ points.
1384
+ Au bout de $${getStrFactor(firstRank)}$ secondes, le score aura diminué de $${getStrFactor(firstRank)} \\times ${-reason.frPretty(2)}$ points.
1316
1385
 
1317
- Au départ, le score est de $${initial.frenchify()}$ points.
1386
+ Au départ, le score est de $${initial.frPretty(2)}$ points.
1318
1387
 
1319
- Le score est donc une suite arithmétique de premier terme $${initial.frenchify()}$ et de raison $${reason.frenchify()}$.`,
1388
+ Le score est donc une suite arithmétique de premier terme $${initial.frPretty(2)}$ et de raison $${reason.frPretty(2)}$.`,
1320
1389
  };
1321
1390
  },
1322
1391
  },
1323
1392
  variationFindRank: {
1324
1393
  getStrQuestion: (_initial, _reason, _firstRank, ...otherArgs) => {
1325
1394
  const [valueAsked] = otherArgs;
1326
- return `Quel est le rang $p$ pour lequel $u_{p} = ${round(valueAsked, 2).frenchify()}$ points ?`;
1395
+ return `Après combien de secondes le score sera-t-il de $${round(valueAsked, 2).frPretty(2)}$ points ?`;
1327
1396
  },
1328
- getAnswerNode: (initial, reason, firstRank, ...otherArgs) => {
1329
- const [valueAsked] = otherArgs;
1330
- return seqArithmeticUtils.getAnswerNodeRandomRank(initial, reason, firstRank, valueAsked);
1397
+ getAnswerStuff: (initial, reason, firstRank, ...otherArgs) => {
1398
+ const [valueAsked, rankDecoder] = otherArgs;
1399
+ const rankNode = seqArithmeticUtils.getAnswerNodeRandomRank(initial, reason, firstRank, valueAsked);
1400
+ const answerNode = rankDecoder.targetFromRank(rankNode.evaluate(), firstRank);
1401
+ return { answerNode, rankNode };
1331
1402
  },
1332
1403
  getHint: (_firstRank, ...otherArgs) => {
1333
1404
  const [valueAsked] = otherArgs;
1334
1405
  return `Quelle est la nature de la suite $(u_n)$ ?
1335
1406
 
1336
- Utilise le terme général de $(u_n)$ pour déterminer quand $u_p = ${valueAsked.frenchify()}$.`;
1407
+ Utilise le terme général de $(u_n)$ pour déterminer quand $u_p = ${valueAsked.frPretty(2)}$.`;
1337
1408
  },
1338
1409
  getCorrectionStuff: (initial, reason, _firstRank) => {
1339
1410
  return {
1340
- str: `Chaque seconde, le score diminue de $${-reason.frenchify()}$ points.
1341
- Le score est donc une suite arithmétique de premier terme $${initial.frenchify()}$ et de raison $${reason.frenchify()}$.`,
1411
+ str: `Chaque seconde, le score diminue de $${-reason.frPretty(2)}$ points.
1412
+ Le score est donc une suite arithmétique de premier terme $${initial.frPretty(2)}$ et de raison $${reason.frPretty(2)}$.`,
1342
1413
  };
1343
1414
  },
1344
1415
  },
@@ -1349,15 +1420,17 @@ Le score est donc une suite arithmétique de premier terme $${initial.frenchify(
1349
1420
  switch (inequationSymbol.symbol) {
1350
1421
  case "<":
1351
1422
  case "\\le":
1352
- return `Quel est le plus grand rang $p$ $u_{p}$ est ${isStrict ? "strictement" : ""} plus petit que $${valueThreshold.frenchify()}$ points ?`;
1423
+ return `Pour quelle durée de réponse maximum le score sera t-il ${isStrict ? "supérieur" : "supérieur ou égal"} à $${valueThreshold.frPretty(2)}$ points ?`;
1353
1424
  case ">":
1354
1425
  case "\\ge":
1355
- return `Quel est le plus petit rang $p$ $u_{p}$ est ${isStrict ? "strictement" : ""} plus grand que $${valueThreshold.frenchify()}$ points ?`;
1426
+ return `Quelle est la durée de réponse pour laquelle le score ${isStrict ? "sera en dessous de" : "égalera ou sera en dessous de"} $${valueThreshold.frPretty(2)}$ points ?`;
1356
1427
  }
1357
1428
  },
1358
- getAnswerNode: (initial, reason, firstRank, ...otherArgs) => {
1359
- const [valueThreshold, inequationSymbol] = otherArgs;
1360
- return seqArithmeticUtils.getAnswerNodeThresholdRank(initial, reason, firstRank, valueThreshold, inequationSymbol);
1429
+ getAnswerStuff: (initial, reason, firstRank, ...otherArgs) => {
1430
+ const [valueThreshold, inequationSymbol, rankDecoder] = otherArgs;
1431
+ const rankNode = seqArithmeticUtils.getAnswerNodeThresholdRank(initial, reason, firstRank, valueThreshold, inequationSymbol);
1432
+ const answerNode = rankDecoder.targetFromRank(rankNode.evaluate(), firstRank);
1433
+ return { answerNode, rankNode };
1361
1434
  },
1362
1435
  getHint: (_firstRank, ...otherArgs) => {
1363
1436
  const [valueThreshold, inequationSymbol, reason] = otherArgs;
@@ -1374,12 +1447,12 @@ Le score est donc une suite arithmétique de premier terme $${initial.frenchify(
1374
1447
  })();
1375
1448
  return `Quelle est la nature de la suite $u_n$ ?
1376
1449
 
1377
- Utilise le terme général de $(u_n)$ pour déterminer ${texP} $p$ tel que $u_p ${inequationSymbol.symbol} ${valueThreshold.frenchify()}$.`;
1450
+ Utilise le terme général de $(u_n)$ pour déterminer ${texP} $p$ tel que $u_p ${inequationSymbol.symbol} ${valueThreshold.frPretty(2)}$.`;
1378
1451
  },
1379
1452
  getCorrectionStuff: (initial, reason, _firstRank) => {
1380
1453
  return {
1381
- str: `Chaque seconde, le score diminue de $${-reason.frenchify()}$ points.
1382
- Le score est donc une suite arithmétique de premier terme $${initial.frenchify()}$ et de raison $${reason.frenchify()}$.`,
1454
+ str: `Chaque seconde, le score diminue de $${-reason.frPretty(2)}$ points.
1455
+ Le score est donc une suite arithmétique de premier terme $${initial.frPretty(2)}$ et de raison $${reason.frPretty(2)}$.`,
1383
1456
  };
1384
1457
  },
1385
1458
  },
@@ -1411,11 +1484,15 @@ Le score est donc une suite arithmétique de premier terme $${initial.frenchify(
1411
1484
  values,
1412
1485
  };
1413
1486
  },
1487
+ rankDecoder: {
1488
+ targetFromRank: (rank, firstRank) => (rank - firstRank).toTree(),
1489
+ rankFromTarget: (nodeTarget, firstRank) => nodeTarget.evaluate() + firstRank,
1490
+ },
1414
1491
  getStrSituation: (initial, reason, firstRank, superfluousData) => {
1415
1492
  if (superfluousData === undefined) {
1416
1493
  return `Daryl utilise un phare à batterie sur son chantier, qu'il laisse allumé.
1417
- Quand il a commencé la journée, le niveau de charge de la batterie était de $${initial.frenchify()} \\%$.
1418
- Le niveau décroît chaque heure de $${(-reason).frenchify()} \\%$.
1494
+ Quand il a commencé la journée, le niveau de charge de la batterie était de $${initial.frPretty(2)} \\%$.
1495
+ Le niveau décroît chaque heure de $${(-reason).frPretty(2)} \\%$.
1419
1496
  On note $u_n$ le niveau de charge après $${getStrFactor(firstRank)} \\ \\textrm{h}$.`;
1420
1497
  }
1421
1498
  else {
@@ -1424,9 +1501,9 @@ On note $u_n$ le niveau de charge après $${getStrFactor(firstRank)} \\ \\textrm
1424
1501
  {
1425
1502
  const [roundedMeanDuration] = superfluousData.values;
1426
1503
  return `Daryl utilise un phare à batterie sur son chantier, qu'il laisse allumé.
1427
- Quand il a commencé la journée, le niveau de charge de la batterie était de $${initial.frenchify()} \\%$.
1504
+ Quand il a commencé la journée, le niveau de charge de la batterie était de $${initial.frPretty(2)} \\%$.
1428
1505
  La plupart du temps, Daryl utilise le phare $${roundedMeanDuration} \\ \\textrm{h}$.
1429
- Le niveau décroît chaque heure de $${(-reason).frenchify()} \\%$.
1506
+ Le niveau décroît chaque heure de $${(-reason).frPretty(2)} \\%$.
1430
1507
  On note $u_n$ le niveau de charge après $${getStrFactor(firstRank)} \\ \\textrm{h}$.`;
1431
1508
  }
1432
1509
  break;
@@ -1434,9 +1511,9 @@ On note $u_n$ le niveau de charge après $${getStrFactor(firstRank)} \\ \\textrm
1434
1511
  {
1435
1512
  const [thresholdBatteryLow] = superfluousData.values;
1436
1513
  return `Daryl utilise un phare à batterie sur son chantier, qu'il laisse allumé.
1437
- Quand il a commencé la journée, le niveau de charge de la batterie était de $${initial.frenchify()} \\%$.
1438
- Le niveau décroît chaque heure de $${(-reason).frenchify()} \\%$.
1439
- Un signal sonore est émis quand le niveau de charge passe en dessous de $${thresholdBatteryLow.frenchify()} \\%$.
1514
+ Quand il a commencé la journée, le niveau de charge de la batterie était de $${initial.frPretty(2)} \\%$.
1515
+ Le niveau décroît chaque heure de $${(-reason).frPretty(2)} \\%$.
1516
+ Un signal sonore est émis quand le niveau de charge passe en dessous de $${thresholdBatteryLow.frPretty(2)} \\%$.
1440
1517
  On note $u_n$ le niveau de charge après $${getStrFactor(firstRank)} \\ \\textrm{h}$.`;
1441
1518
  }
1442
1519
  break;
@@ -1453,12 +1530,12 @@ Inspire toi de ce calcul pour déterminer le niveau de charge pour une durée d'
1453
1530
  `,
1454
1531
  getCorrectionStuff: (initial, reason, firstRank) => {
1455
1532
  return {
1456
- str: `Chaque heure, le niveau de charge diminue de $${-reason.frenchify()} \\%$.
1457
- Au bout de $${getStrFactor(firstRank)} \\ \\textrm{h}$, le niveau aura diminué de $${getStrFactor(firstRank)} \\times ${-reason.frenchify()} \\%$.
1533
+ str: `Chaque heure, le niveau de charge diminue de $${-reason.frPretty(2)} \\%$.
1534
+ Au bout de $${getStrFactor(firstRank)} \\ \\textrm{h}$, le niveau aura diminué de $${getStrFactor(firstRank)} \\times ${-reason.frPretty(2)} \\%$.
1458
1535
 
1459
- Au départ, le niveau est de $${initial.frenchify()} \\%$.
1536
+ Au départ, le niveau est de $${initial.frPretty(2)} \\%$.
1460
1537
 
1461
- Le niveau de charge est donc une suite arithmétique de premier terme $${initial.frenchify()}$ et de raison $${reason.frenchify()}$.`,
1538
+ Le niveau de charge est donc une suite arithmétique de premier terme $${initial.frPretty(2)}$ et de raison $${reason.frPretty(2)}$.`,
1462
1539
  };
1463
1540
  },
1464
1541
  },
@@ -1472,8 +1549,8 @@ Déduis-en comment calculer $u_{n+1}$ à partir de $u_n$.`,
1472
1549
  const target2 = 5;
1473
1550
  const [rank1, rank2] = [target1, target2].map((target) => target + firstRank);
1474
1551
  return {
1475
- str: `Chaque heure, le niveau de charge diminue de $${-reason.frenchify()} \\%$.
1476
- Par exemple, le niveau après $${target2.frenchify()} \\ \\textrm{h}$ d'utilisation est égal à celui après $${target1.frenchify()} \\ \\textrm{h}$ d'utilisation diminué de $${(-reason).frenchify()} \\%$.`,
1552
+ str: `Chaque heure, le niveau de charge diminue de $${-reason.frPretty(2)} \\%$.
1553
+ Par exemple, le niveau après $${target2.frPretty(2)} \\ \\textrm{h}$ d'utilisation est égal à celui après $${target1.frPretty(2)} \\ \\textrm{h}$ d'utilisation diminué de $${(-reason).frPretty(2)} \\%$.`,
1477
1554
  rank1,
1478
1555
  rank2,
1479
1556
  };
@@ -1489,38 +1566,40 @@ Par exemple, le niveau après $${target2.frenchify()} \\ \\textrm{h}$ d'utilisat
1489
1566
  const target = rankAsked - firstRank;
1490
1567
  return `Quelle est la nature de la suite $u_n$ ?
1491
1568
 
1492
- Utilise le terme général de $u_n$ pour déterminer le niveau de charge après $${target.frenchify()} \\ \\textrm{h}$ d'utilisation.`;
1569
+ Utilise le terme général de $u_n$ pour déterminer le niveau de charge après $${target.frPretty(2)} \\ \\textrm{h}$ d'utilisation.`;
1493
1570
  },
1494
1571
  getCorrectionStuff: (initial, reason, firstRank, ..._otherArgs) => {
1495
1572
  return {
1496
- str: `Chaque heure, le niveau de charge diminue de $${-reason.frenchify()} \\%$.
1497
- Au bout de $${getStrFactor(firstRank)} \\ \\textrm{h}$, le niveau aura diminué de $${getStrFactor(firstRank)} \\times ${-reason.frenchify()} \\%$.
1573
+ str: `Chaque heure, le niveau de charge diminue de $${-reason.frPretty(2)} \\%$.
1574
+ Au bout de $${getStrFactor(firstRank)} \\ \\textrm{h}$, le niveau aura diminué de $${getStrFactor(firstRank)} \\times ${-reason.frPretty(2)} \\%$.
1498
1575
 
1499
- Au départ, le niveau est de $${initial.frenchify()} \\%$.
1576
+ Au départ, le niveau est de $${initial.frPretty(2)} \\%$.
1500
1577
 
1501
- Le niveau de charge est donc une suite arithmétique de premier terme $${initial.frenchify()}$ et de raison $${reason.frenchify()}$.`,
1578
+ Le niveau de charge est donc une suite arithmétique de premier terme $${initial.frPretty(2)}$ et de raison $${reason.frPretty(2)}$.`,
1502
1579
  };
1503
1580
  },
1504
1581
  },
1505
1582
  variationFindRank: {
1506
1583
  getStrQuestion: (_initial, _reason, _firstRank, ...otherArgs) => {
1507
1584
  const [valueAsked] = otherArgs;
1508
- return `Quel est le rang $p$ pour lequel $u_{p} = ${round(valueAsked, 2).frenchify()} \\%$ ?`;
1585
+ return `Après combien d'heures d'utilisation la charge sera-t-elle de $${round(valueAsked, 2).frPretty(2)} \\%$ ?`;
1509
1586
  },
1510
- getAnswerNode: (initial, reason, firstRank, ...otherArgs) => {
1511
- const [valueAsked] = otherArgs;
1512
- return seqArithmeticUtils.getAnswerNodeRandomRank(initial, reason, firstRank, valueAsked);
1587
+ getAnswerStuff: (initial, reason, firstRank, ...otherArgs) => {
1588
+ const [valueAsked, rankDecoder] = otherArgs;
1589
+ const rankNode = seqArithmeticUtils.getAnswerNodeRandomRank(initial, reason, firstRank, valueAsked);
1590
+ const answerNode = rankDecoder.targetFromRank(rankNode.evaluate(), firstRank);
1591
+ return { answerNode, rankNode };
1513
1592
  },
1514
1593
  getHint: (_firstRank, ...otherArgs) => {
1515
1594
  const [valueAsked] = otherArgs;
1516
1595
  return `Quelle est la nature de la suite $(u_n)$ ?
1517
1596
 
1518
- Utilise le terme général de $(u_n)$ pour déterminer quand $u_p = ${valueAsked.frenchify()}$.`;
1597
+ Utilise le terme général de $(u_n)$ pour déterminer quand $u_p = ${valueAsked.frPretty(2)}$.`;
1519
1598
  },
1520
1599
  getCorrectionStuff: (initial, reason, _firstRank) => {
1521
1600
  return {
1522
- str: `Chaque heure, le niveau de charge diminue de $${-reason.frenchify()} \\%$.
1523
- Le niveau de charge est donc une suite arithmétique de premier terme $${initial.frenchify()}$ et de raison $${reason.frenchify()}$.`,
1601
+ str: `Chaque heure, le niveau de charge diminue de $${-reason.frPretty(2)} \\%$.
1602
+ Le niveau de charge est donc une suite arithmétique de premier terme $${initial.frPretty(2)}$ et de raison $${reason.frPretty(2)}$.`,
1524
1603
  };
1525
1604
  },
1526
1605
  },
@@ -1531,15 +1610,17 @@ Le niveau de charge est donc une suite arithmétique de premier terme $${initial
1531
1610
  switch (inequationSymbol.symbol) {
1532
1611
  case "<":
1533
1612
  case "\\le":
1534
- return `Quel est le plus grand rang $p$ $u_{p}$ est ${isStrict ? "strictement" : ""} plus petit que $${valueThreshold.frenchify()} \\%$ ?`;
1613
+ return `Quelle est la durée maximum d'utilisation pour garder un niveau de charge ${isStrict ? "strictement supérieur" : "supérieur"} à $${valueThreshold.frPretty(2)} \\%$ ?`;
1535
1614
  case ">":
1536
1615
  case "\\ge":
1537
- return `Quel est le plus petit rang $p$ $u_{p}$ est ${isStrict ? "strictement" : ""} plus grand que $${valueThreshold.frenchify()} \\%$ ?`;
1616
+ return `Quelle est la durée d'utilisation minimum pour passer le niveau de charge ${isStrict ? "strictement en dessous de" : "en dessous de ou égal à"} $${valueThreshold.frPretty(2)} \\%$ ?`;
1538
1617
  }
1539
1618
  },
1540
- getAnswerNode: (initial, reason, firstRank, ...otherArgs) => {
1541
- const [valueThreshold, inequationSymbol] = otherArgs;
1542
- return seqArithmeticUtils.getAnswerNodeThresholdRank(initial, reason, firstRank, valueThreshold, inequationSymbol);
1619
+ getAnswerStuff: (initial, reason, firstRank, ...otherArgs) => {
1620
+ const [valueThreshold, inequationSymbol, rankDecoder] = otherArgs;
1621
+ const rankNode = seqArithmeticUtils.getAnswerNodeThresholdRank(initial, reason, firstRank, valueThreshold, inequationSymbol);
1622
+ const answerNode = rankDecoder.targetFromRank(rankNode.evaluate(), firstRank);
1623
+ return { answerNode, rankNode };
1543
1624
  },
1544
1625
  getHint: (_firstRank, ...otherArgs) => {
1545
1626
  const [valueThreshold, inequationSymbol, reason] = otherArgs;
@@ -1556,12 +1637,12 @@ Le niveau de charge est donc une suite arithmétique de premier terme $${initial
1556
1637
  })();
1557
1638
  return `Quelle est la nature de la suite $u_n$ ?
1558
1639
 
1559
- Utilise le terme général de $(u_n)$ pour déterminer ${texP} $p$ tel que $u_p ${inequationSymbol.symbol} ${valueThreshold.frenchify()}$.`;
1640
+ Utilise le terme général de $(u_n)$ pour déterminer ${texP} $p$ tel que $u_p ${inequationSymbol.symbol} ${valueThreshold.frPretty(2)}$.`;
1560
1641
  },
1561
1642
  getCorrectionStuff: (initial, reason, _firstRank) => {
1562
1643
  return {
1563
- str: `Chaque heure, le niveau de charge diminue de $${-reason.frenchify()} \\%$.
1564
- Le niveau de charge est donc une suite arithmétique de premier terme $${initial.frenchify()}$ et de raison $${reason.frenchify()}$.`,
1644
+ str: `Chaque heure, le niveau de charge diminue de $${-reason.frPretty(2)} \\%$.
1645
+ Le niveau de charge est donc une suite arithmétique de premier terme $${initial.frPretty(2)}$ et de raison $${reason.frPretty(2)}$.`,
1565
1646
  };
1566
1647
  },
1567
1648
  },
@@ -1593,10 +1674,14 @@ Le niveau de charge est donc une suite arithmétique de premier terme $${initial
1593
1674
  values,
1594
1675
  };
1595
1676
  },
1677
+ rankDecoder: {
1678
+ targetFromRank: (rank, firstRank) => (rank - firstRank).toTree(),
1679
+ rankFromTarget: (nodeTarget, firstRank) => nodeTarget.evaluate() + firstRank,
1680
+ },
1596
1681
  getStrSituation: (initial, reason, firstRank, superfluousData) => {
1597
1682
  if (superfluousData === undefined) {
1598
- return `Un gigantesque buffet est organisé. Au départ, sur les tables de service, il y a $${initial.frenchify()}$ amuse-bouches.
1599
- $${(-reason).frenchify()}$ amuse-bouches sont mangés toutes les minutes.
1683
+ return `Un gigantesque buffet est organisé. Au départ, sur les tables de service, il y a $${initial.frPretty(2)}$ amuse-bouches.
1684
+ $${(-reason).frPretty(2)}$ amuse-bouches sont mangés toutes les minutes.
1600
1685
  On note $u_n$ le nombre d'amuse-bouches restant après $${getStrFactor(firstRank)} \\ \\textrm{min}$.`;
1601
1686
  }
1602
1687
  else {
@@ -1604,18 +1689,18 @@ On note $u_n$ le nombre d'amuse-bouches restant après $${getStrFactor(firstRank
1604
1689
  case 0:
1605
1690
  {
1606
1691
  const [numberOfPeople] = superfluousData.values;
1607
- return `Un gigantesque buffet est organisé. Au départ, sur les tables de service, il y a $${initial.frenchify()}$ amuse-bouches.
1608
- $${(-reason).frenchify()}$ amuse-bouches sont mangés toutes les minutes.
1609
- Il y a en tout $${numberOfPeople.frenchify()}$ convives.
1692
+ return `Un gigantesque buffet est organisé. Au départ, sur les tables de service, il y a $${initial.frPretty(2)}$ amuse-bouches.
1693
+ $${(-reason).frPretty(2)}$ amuse-bouches sont mangés toutes les minutes.
1694
+ Il y a en tout $${numberOfPeople.frPretty(2)}$ convives.
1610
1695
  On note $u_n$ le nombre d'amuse-bouches restant après $${getStrFactor(firstRank)} \\ \\textrm{min}$.`;
1611
1696
  }
1612
1697
  break;
1613
1698
  case 1:
1614
1699
  {
1615
1700
  const [nbOfGlassesPerMinute] = superfluousData.values;
1616
- return `Un gigantesque buffet est organisé. Au départ, sur les tables de service, il y a $${initial.frenchify()}$ amuse-bouches.
1617
- $${nbOfGlassesPerMinute.frenchify()}$ verres sont servis toutes les minutes.
1618
- $${(-reason).frenchify()}$ amuse-bouches sont mangés toutes les minutes.
1701
+ return `Un gigantesque buffet est organisé. Au départ, sur les tables de service, il y a $${initial.frPretty(2)}$ amuse-bouches.
1702
+ $${nbOfGlassesPerMinute.frPretty(2)}$ verres sont servis toutes les minutes.
1703
+ $${(-reason).frPretty(2)}$ amuse-bouches sont mangés toutes les minutes.
1619
1704
  On note $u_n$ le nombre d'amuse-bouches restant après $${getStrFactor(firstRank)} \\ \\textrm{min}$.`;
1620
1705
  }
1621
1706
  break;
@@ -1632,12 +1717,12 @@ Inspire toi de ce calcul pour déterminer le nombre d'amuse-bouches restant apr
1632
1717
  `,
1633
1718
  getCorrectionStuff: (initial, reason, firstRank) => {
1634
1719
  return {
1635
- str: `Chaque minute, le nombre d'amuse-bouches diminue de $${-reason.frenchify()}$.
1636
- Au bout de $${getStrFactor(firstRank)} \\ \\textrm{min}$, le nombre d'amuse-bouches aura diminué de $${getStrFactor(firstRank)} \\times ${-reason.frenchify()}$.
1720
+ str: `Chaque minute, le nombre d'amuse-bouches diminue de $${-reason.frPretty(2)}$.
1721
+ Au bout de $${getStrFactor(firstRank)} \\ \\textrm{min}$, le nombre d'amuse-bouches aura diminué de $${getStrFactor(firstRank)} \\times ${-reason.frPretty(2)}$.
1637
1722
 
1638
- Au départ, il y en a $${initial.frenchify()}$.
1723
+ Au départ, il y en a $${initial.frPretty(2)}$.
1639
1724
 
1640
- Le nombre d'amuse-bouches est donc une suite arithmétique de premier terme $${initial.frenchify()}$ et de raison $${reason.frenchify()}$.`,
1725
+ Le nombre d'amuse-bouches est donc une suite arithmétique de premier terme $${initial.frPretty(2)}$ et de raison $${reason.frPretty(2)}$.`,
1641
1726
  };
1642
1727
  },
1643
1728
  },
@@ -1651,8 +1736,8 @@ Déduis-en comment calculer $u_{n+1}$ à partir de $u_n$.`,
1651
1736
  const target2 = 5;
1652
1737
  const [rank1, rank2] = [target1, target2].map((target) => target + firstRank);
1653
1738
  return {
1654
- str: `Chaque minute, le nombre d'amuse-bouches diminue de $${-reason.frenchify()}$.
1655
- Par exemple, le nombre d'amuse-bouches restant après $${target2.frenchify()} \\ \\textrm{min}$ est égal à celui après $${target1.frenchify()} \\ \\textrm{min}$ d'utilisation diminué de $${(-reason).frenchify()}$.`,
1739
+ str: `Chaque minute, le nombre d'amuse-bouches diminue de $${-reason.frPretty(2)}$.
1740
+ Par exemple, le nombre d'amuse-bouches restant après $${target2.frPretty(2)} \\ \\textrm{min}$ est égal à celui après $${target1.frPretty(2)} \\ \\textrm{min}$ d'utilisation diminué de $${(-reason).frPretty(2)}$.`,
1656
1741
  rank1,
1657
1742
  rank2,
1658
1743
  };
@@ -1668,38 +1753,40 @@ Par exemple, le nombre d'amuse-bouches restant après $${target2.frenchify()} \\
1668
1753
  const target = rankAsked - firstRank;
1669
1754
  return `Quelle est la nature de la suite $u_n$ ?
1670
1755
 
1671
- Utilise le terme général de $u_n$ pour déterminer le nombre d'amuse-bouches restant après $${target.frenchify()} \\ \\textrm{min}$ de buffet.`;
1756
+ Utilise le terme général de $u_n$ pour déterminer le nombre d'amuse-bouches restant après $${target.frPretty(2)} \\ \\textrm{min}$ de buffet.`;
1672
1757
  },
1673
1758
  getCorrectionStuff: (initial, reason, firstRank, ..._otherArgs) => {
1674
1759
  return {
1675
- str: `Chaque minute, le nombre d'amuse-bouches diminue de $${-reason.frenchify()}$.
1676
- Au bout de $${getStrFactor(firstRank)} \\ \\textrm{min}$, le nombre d'amuse-bouches aura diminué de $${getStrFactor(firstRank)} \\times ${-reason.frenchify()}$.
1760
+ str: `Chaque minute, le nombre d'amuse-bouches diminue de $${-reason.frPretty(2)}$.
1761
+ Au bout de $${getStrFactor(firstRank)} \\ \\textrm{min}$, le nombre d'amuse-bouches aura diminué de $${getStrFactor(firstRank)} \\times ${-reason.frPretty(2)}$.
1677
1762
 
1678
- Au départ, il y en a $${initial.frenchify()}$.
1763
+ Au départ, il y en a $${initial.frPretty(2)}$.
1679
1764
 
1680
- Le nombre d'amuse-bouches est donc une suite arithmétique de premier terme $${initial.frenchify()}$ et de raison $${reason.frenchify()}$.`,
1765
+ Le nombre d'amuse-bouches est donc une suite arithmétique de premier terme $${initial.frPretty(2)}$ et de raison $${reason.frPretty(2)}$.`,
1681
1766
  };
1682
1767
  },
1683
1768
  },
1684
1769
  variationFindRank: {
1685
1770
  getStrQuestion: (_initial, _reason, _firstRank, ...otherArgs) => {
1686
1771
  const [valueAsked] = otherArgs;
1687
- return `Quel est le rang $p$ pour lequel $u_{p} = ${round(valueAsked, 2).frenchify()}$ ?`;
1772
+ return `Après combien de minutes le nombre d'amuse-bouches sera-t-il de $${round(valueAsked, 2).frPretty(2)}$ ?`;
1688
1773
  },
1689
- getAnswerNode: (initial, reason, firstRank, ...otherArgs) => {
1690
- const [valueAsked] = otherArgs;
1691
- return seqArithmeticUtils.getAnswerNodeRandomRank(initial, reason, firstRank, valueAsked);
1774
+ getAnswerStuff: (initial, reason, firstRank, ...otherArgs) => {
1775
+ const [valueAsked, rankDecoder] = otherArgs;
1776
+ const rankNode = seqArithmeticUtils.getAnswerNodeRandomRank(initial, reason, firstRank, valueAsked);
1777
+ const answerNode = rankDecoder.targetFromRank(rankNode.evaluate(), firstRank);
1778
+ return { answerNode, rankNode };
1692
1779
  },
1693
1780
  getHint: (_firstRank, ...otherArgs) => {
1694
1781
  const [valueAsked] = otherArgs;
1695
1782
  return `Quelle est la nature de la suite $(u_n)$ ?
1696
1783
 
1697
- Utilise le terme général de $(u_n)$ pour déterminer quand $u_p = ${valueAsked.frenchify()}$.`;
1784
+ Utilise le terme général de $(u_n)$ pour déterminer quand $u_p = ${valueAsked.frPretty(2)}$.`;
1698
1785
  },
1699
1786
  getCorrectionStuff: (initial, reason, _firstRank) => {
1700
1787
  return {
1701
- str: `Chaque minute, le nombre d'amuse-bouches diminue de $${-reason.frenchify()}$.
1702
- Le nombre d'amuse-bouches est donc une suite arithmétique de premier terme $${initial.frenchify()}$ et de raison $${reason.frenchify()}$.`,
1788
+ str: `Chaque minute, le nombre d'amuse-bouches diminue de $${-reason.frPretty(2)}$.
1789
+ Le nombre d'amuse-bouches est donc une suite arithmétique de premier terme $${initial.frPretty(2)}$ et de raison $${reason.frPretty(2)}$.`,
1703
1790
  };
1704
1791
  },
1705
1792
  },
@@ -1710,15 +1797,19 @@ Le nombre d'amuse-bouches est donc une suite arithmétique de premier terme $${i
1710
1797
  switch (inequationSymbol.symbol) {
1711
1798
  case "<":
1712
1799
  case "\\le":
1713
- return `Quel est le plus grand rang $p$ $u_{p}$ est ${isStrict ? "strictement" : ""} plus petit que $${valueThreshold.frenchify()} \\ \\textrm{€}$ ?`;
1800
+ return `Quelle sera la dernière minute le nombre d'amuse-bouches sera ${isStrict ? "supérieur" : "supérieur ou égal"} à $${valueThreshold.frPretty(2)}$ ?`;
1714
1801
  case ">":
1715
1802
  case "\\ge":
1716
- return `Quel est le plus petit rang $p$ $u_{p}$ est ${isStrict ? "strictement" : ""} plus grand que $${valueThreshold.frenchify()} \\ \\textrm{€}$ ?`;
1803
+ return `Quelle sera la minute le nombre d'amuse-bouches ${isStrict
1804
+ ? "passera strictement en dessous de"
1805
+ : "égalera ou passera en dessous de"} $${valueThreshold.frPretty(2)} \\ \\textrm{€}$ ?`;
1717
1806
  }
1718
1807
  },
1719
- getAnswerNode: (initial, reason, firstRank, ...otherArgs) => {
1720
- const [valueThreshold, inequationSymbol] = otherArgs;
1721
- return seqArithmeticUtils.getAnswerNodeThresholdRank(initial, reason, firstRank, valueThreshold, inequationSymbol);
1808
+ getAnswerStuff: (initial, reason, firstRank, ...otherArgs) => {
1809
+ const [valueThreshold, inequationSymbol, rankDecoder] = otherArgs;
1810
+ const rankNode = seqArithmeticUtils.getAnswerNodeThresholdRank(initial, reason, firstRank, valueThreshold, inequationSymbol);
1811
+ const answerNode = rankDecoder.targetFromRank(rankNode.evaluate(), firstRank);
1812
+ return { answerNode, rankNode };
1722
1813
  },
1723
1814
  getHint: (_firstRank, ...otherArgs) => {
1724
1815
  const [valueThreshold, inequationSymbol, reason] = otherArgs;
@@ -1735,12 +1826,12 @@ Le nombre d'amuse-bouches est donc une suite arithmétique de premier terme $${i
1735
1826
  })();
1736
1827
  return `Quelle est la nature de la suite $u_n$ ?
1737
1828
 
1738
- Utilise le terme général de $(u_n)$ pour déterminer ${texP} $p$ tel que $u_p ${inequationSymbol.symbol} ${valueThreshold.frenchify()}$.`;
1829
+ Utilise le terme général de $(u_n)$ pour déterminer ${texP} $p$ tel que $u_p ${inequationSymbol.symbol} ${valueThreshold.frPretty(2)}$.`;
1739
1830
  },
1740
1831
  getCorrectionStuff: (initial, reason, _firstRank) => {
1741
1832
  return {
1742
- str: `Chaque minute, le nombre d'amuse-bouches diminue de $${-reason.frenchify()}$.
1743
- Le nombre d'amuse-bouches est donc une suite arithmétique de premier terme $${initial.frenchify()}$ et de raison $${reason.frenchify()}$.`,
1833
+ str: `Chaque minute, le nombre d'amuse-bouches diminue de $${-reason.frPretty(2)}$.
1834
+ Le nombre d'amuse-bouches est donc une suite arithmétique de premier terme $${initial.frPretty(2)}$ et de raison $${reason.frPretty(2)}$.`,
1744
1835
  };
1745
1836
  },
1746
1837
  },
@@ -1772,10 +1863,14 @@ Le nombre d'amuse-bouches est donc une suite arithmétique de premier terme $${i
1772
1863
  values,
1773
1864
  };
1774
1865
  },
1866
+ rankDecoder: {
1867
+ targetFromRank: (rank, firstRank) => (rank - firstRank).toTree(),
1868
+ rankFromTarget: (nodeTarget, firstRank) => nodeTarget.evaluate() + firstRank,
1869
+ },
1775
1870
  getStrSituation: (initial, reason, firstRank, superfluousData) => {
1776
1871
  if (superfluousData === undefined) {
1777
- return `L'année de la sortie du jeu vidéo Locket Rig, ce même jeu avait $${initial.frenchify()}$ joueurs réguliers.
1778
- Tous les ans, $${(-reason).frenchify()}$ joueurs arrêtent de jouer régulièrement à Locket Rig.
1872
+ return `L'année de la sortie du jeu vidéo Locket Rig, ce même jeu avait $${initial.frPretty(2)}$ joueurs réguliers.
1873
+ Tous les ans, $${(-reason).frPretty(2)}$ joueurs arrêtent de jouer régulièrement à Locket Rig.
1779
1874
  On note $u_n$ le nombre de joueurs réguliers de Locket Rig $${getStrFactor(firstRank)}$ années après sa sortie.`;
1780
1875
  }
1781
1876
  else {
@@ -1783,18 +1878,18 @@ On note $u_n$ le nombre de joueurs réguliers de Locket Rig $${getStrFactor(firs
1783
1878
  case 0:
1784
1879
  {
1785
1880
  const [numberOfPlayersOfNordFight] = superfluousData.values;
1786
- return `L'année de la sortie du jeu vidéo Locket Rig, ce même jeu avait $${initial.frenchify()}$ joueurs réguliers.
1787
- Tous les ans, $${(-reason).frenchify()}$ joueurs arrêtent de jouer régulièrement à Locket Rig.
1788
- Actuellement, $${numberOfPlayersOfNordFight.frenchify()}$ jouent régulièrement au jeu vidéo Nord Fight.
1881
+ return `L'année de la sortie du jeu vidéo Locket Rig, ce même jeu avait $${initial.frPretty(2)}$ joueurs réguliers.
1882
+ Tous les ans, $${(-reason).frPretty(2)}$ joueurs arrêtent de jouer régulièrement à Locket Rig.
1883
+ Actuellement, $${numberOfPlayersOfNordFight.frPretty(2)}$ jouent régulièrement au jeu vidéo Nord Fight.
1789
1884
  On note $u_n$ le nombre de joueurs réguliers de Locket Rig $${getStrFactor(firstRank)}$ années après sa sortie.`;
1790
1885
  }
1791
1886
  break;
1792
1887
  case 1:
1793
1888
  {
1794
1889
  const [nbOfSpectatorsAtPhysicalEvent] = superfluousData.values;
1795
- return `L'année de la sortie du jeu vidéo Locket Rig, ce même jeu avait $${initial.frenchify()}$ joueurs réguliers.
1796
- Il y avait $${nbOfSpectatorsAtPhysicalEvent.frenchify()}$ spectateurs au premier tournoi organisé dans une grande salle de concert.
1797
- Tous les ans, $${(-reason).frenchify()}$ joueurs arrêtent de jouer régulièrement à Locket Rig.
1890
+ return `L'année de la sortie du jeu vidéo Locket Rig, ce même jeu avait $${initial.frPretty(2)}$ joueurs réguliers.
1891
+ Il y avait $${nbOfSpectatorsAtPhysicalEvent.frPretty(2)}$ spectateurs au premier tournoi organisé dans une grande salle de concert.
1892
+ Tous les ans, $${(-reason).frPretty(2)}$ joueurs arrêtent de jouer régulièrement à Locket Rig.
1798
1893
  On note $u_n$ le nombre de joueurs réguliers de Locket Rig $${getStrFactor(firstRank)}$ années après sa sortie.`;
1799
1894
  }
1800
1895
  break;
@@ -1811,12 +1906,12 @@ Inspire toi de ce calcul pour déterminer le nombre de joueurs $${getStrFactor(f
1811
1906
  `,
1812
1907
  getCorrectionStuff: (initial, reason, firstRank) => {
1813
1908
  return {
1814
- str: `Chaque année, le nombre de joueurs diminue de $${-reason.frenchify()}$.
1815
- Au bout de $${getStrFactor(firstRank)}$ années, le nombre de joueurs aura diminué de $${getStrFactor(firstRank)} \\times ${-reason.frenchify()}$.
1909
+ str: `Chaque année, le nombre de joueurs diminue de $${-reason.frPretty(2)}$.
1910
+ Au bout de $${getStrFactor(firstRank)}$ années, le nombre de joueurs aura diminué de $${getStrFactor(firstRank)} \\times ${-reason.frPretty(2)}$.
1816
1911
 
1817
- Au départ, il y en avait $${initial.frenchify()}$.
1912
+ Au départ, il y en avait $${initial.frPretty(2)}$.
1818
1913
 
1819
- Le nombre de joueurs réguliers de Locket Rig est donc une suite arithmétique de premier terme $${initial.frenchify()}$ et de raison $${reason.frenchify()}$.`,
1914
+ Le nombre de joueurs réguliers de Locket Rig est donc une suite arithmétique de premier terme $${initial.frPretty(2)}$ et de raison $${reason.frPretty(2)}$.`,
1820
1915
  };
1821
1916
  },
1822
1917
  },
@@ -1830,8 +1925,8 @@ Déduis-en comment calculer $u_{n+1}$ à partir de $u_n$.`,
1830
1925
  const target2 = 5;
1831
1926
  const [rank1, rank2] = [target1, target2].map((target) => target + firstRank);
1832
1927
  return {
1833
- str: `Chaque année, le nombre de joueurs diminue de $${-reason.frenchify()}$.
1834
- Par exemple, le nombre de joueurs restant après $${target2.frenchify()}$ années est égal à celui après $${target1.frenchify()}$ années diminué de $${(-reason).frenchify()}$.`,
1928
+ str: `Chaque année, le nombre de joueurs diminue de $${-reason.frPretty(2)}$.
1929
+ Par exemple, le nombre de joueurs restant après $${target2.frPretty(2)}$ années est égal à celui après $${target1.frPretty(2)}$ années diminué de $${(-reason).frPretty(2)}$.`,
1835
1930
  rank1,
1836
1931
  rank2,
1837
1932
  };
@@ -1847,38 +1942,40 @@ Par exemple, le nombre de joueurs restant après $${target2.frenchify()}$ année
1847
1942
  const target = rankAsked - firstRank;
1848
1943
  return `Quelle est la nature de la suite $u_n$ ?
1849
1944
 
1850
- Utilise le terme général de $u_n$ pour déterminer le nombre de joueurs restant après $${target.frenchify()}$ années.`;
1945
+ Utilise le terme général de $u_n$ pour déterminer le nombre de joueurs restant après $${target.frPretty(2)}$ années.`;
1851
1946
  },
1852
1947
  getCorrectionStuff: (initial, reason, firstRank, ..._otherArgs) => {
1853
1948
  return {
1854
- str: `Chaque année, le nombre de joueurs diminue de $${-reason.frenchify()}$.
1855
- Au bout de $${getStrFactor(firstRank)}$ années, le nombre de joueurs aura diminué de $${getStrFactor(firstRank)} \\times ${-reason.frenchify()}$.
1949
+ str: `Chaque année, le nombre de joueurs diminue de $${-reason.frPretty(2)}$.
1950
+ Au bout de $${getStrFactor(firstRank)}$ années, le nombre de joueurs aura diminué de $${getStrFactor(firstRank)} \\times ${-reason.frPretty(2)}$.
1856
1951
 
1857
- Au départ, il y en avait $${initial.frenchify()}$.
1952
+ Au départ, il y en avait $${initial.frPretty(2)}$.
1858
1953
 
1859
- Le nombre de joueurs réguliers de Locket Rig est donc une suite arithmétique de premier terme $${initial.frenchify()}$ et de raison $${reason.frenchify()}$.`,
1954
+ Le nombre de joueurs réguliers de Locket Rig est donc une suite arithmétique de premier terme $${initial.frPretty(2)}$ et de raison $${reason.frPretty(2)}$.`,
1860
1955
  };
1861
1956
  },
1862
1957
  },
1863
1958
  variationFindRank: {
1864
1959
  getStrQuestion: (_initial, _reason, _firstRank, ...otherArgs) => {
1865
1960
  const [valueAsked] = otherArgs;
1866
- return `Quel est le rang $p$ pour lequel $u_{p} = ${round(valueAsked, 2).frenchify()}$ ?`;
1961
+ return `Après combien d'années le nombre de joueurs sera-t-il de $${round(valueAsked, 2).frPretty(2)}$ ?`;
1867
1962
  },
1868
- getAnswerNode: (initial, reason, firstRank, ...otherArgs) => {
1869
- const [valueAsked] = otherArgs;
1870
- return seqArithmeticUtils.getAnswerNodeRandomRank(initial, reason, firstRank, valueAsked);
1963
+ getAnswerStuff: (initial, reason, firstRank, ...otherArgs) => {
1964
+ const [valueAsked, rankDecoder] = otherArgs;
1965
+ const rankNode = seqArithmeticUtils.getAnswerNodeRandomRank(initial, reason, firstRank, valueAsked);
1966
+ const answerNode = rankDecoder.targetFromRank(rankNode.evaluate(), firstRank);
1967
+ return { answerNode, rankNode };
1871
1968
  },
1872
1969
  getHint: (_firstRank, ...otherArgs) => {
1873
1970
  const [valueAsked] = otherArgs;
1874
1971
  return `Quelle est la nature de la suite $(u_n)$ ?
1875
1972
 
1876
- Utilise le terme général de $(u_n)$ pour déterminer quand $u_p = ${valueAsked.frenchify()}$.`;
1973
+ Utilise le terme général de $(u_n)$ pour déterminer quand $u_p = ${valueAsked.frPretty(2)}$.`;
1877
1974
  },
1878
1975
  getCorrectionStuff: (initial, reason, _firstRank) => {
1879
1976
  return {
1880
- str: `Chaque année, le nombre de joueurs diminue de $${-reason.frenchify()}$.
1881
- Le nombre de joueurs réguliers de Locket Rig est donc une suite arithmétique de premier terme $${initial.frenchify()}$ et de raison $${reason.frenchify()}$.`,
1977
+ str: `Chaque année, le nombre de joueurs diminue de $${-reason.frPretty(2)}$.
1978
+ Le nombre de joueurs réguliers de Locket Rig est donc une suite arithmétique de premier terme $${initial.frPretty(2)}$ et de raison $${reason.frPretty(2)}$.`,
1882
1979
  };
1883
1980
  },
1884
1981
  },
@@ -1889,15 +1986,19 @@ Le nombre de joueurs réguliers de Locket Rig est donc une suite arithmétique d
1889
1986
  switch (inequationSymbol.symbol) {
1890
1987
  case "<":
1891
1988
  case "\\le":
1892
- return `Quel est le plus grand rang $p$ $u_{p}$ est ${isStrict ? "strictement" : ""} plus petit que $${valueThreshold.frenchify()} \\ \\textrm{€}$ ?`;
1989
+ return `Quelle sera la dernière année le nombre de joueurs sera ${isStrict ? "supérieur" : "supérieur ou égal"} à $${valueThreshold.frPretty(2)}$ ?`;
1893
1990
  case ">":
1894
1991
  case "\\ge":
1895
- return `Quel est le plus petit rang $p$ $u_{p}$ est ${isStrict ? "strictement" : ""} plus grand que $${valueThreshold.frenchify()} \\ \\textrm{€}$ ?`;
1992
+ return `Quelle sera l'année le nombre de joueurs ${isStrict
1993
+ ? "passera strictement en dessous de"
1994
+ : "égalera ou passera en dessous de"} $${valueThreshold.frPretty(2)}$ ?`;
1896
1995
  }
1897
1996
  },
1898
- getAnswerNode: (initial, reason, firstRank, ...otherArgs) => {
1899
- const [valueThreshold, inequationSymbol] = otherArgs;
1900
- return seqArithmeticUtils.getAnswerNodeThresholdRank(initial, reason, firstRank, valueThreshold, inequationSymbol);
1997
+ getAnswerStuff: (initial, reason, firstRank, ...otherArgs) => {
1998
+ const [valueThreshold, inequationSymbol, rankDecoder] = otherArgs;
1999
+ const rankNode = seqArithmeticUtils.getAnswerNodeThresholdRank(initial, reason, firstRank, valueThreshold, inequationSymbol);
2000
+ const answerNode = rankDecoder.targetFromRank(rankNode.evaluate(), firstRank);
2001
+ return { answerNode, rankNode };
1901
2002
  },
1902
2003
  getHint: (_firstRank, ...otherArgs) => {
1903
2004
  const [valueThreshold, inequationSymbol, reason] = otherArgs;
@@ -1914,12 +2015,12 @@ Le nombre de joueurs réguliers de Locket Rig est donc une suite arithmétique d
1914
2015
  })();
1915
2016
  return `Quelle est la nature de la suite $u_n$ ?
1916
2017
 
1917
- Utilise le terme général de $(u_n)$ pour déterminer ${texP} $p$ tel que $u_p ${inequationSymbol.symbol} ${valueThreshold.frenchify()}$.`;
2018
+ Utilise le terme général de $(u_n)$ pour déterminer ${texP} $p$ tel que $u_p ${inequationSymbol.symbol} ${valueThreshold.frPretty(2)}$.`;
1918
2019
  },
1919
2020
  getCorrectionStuff: (initial, reason, _firstRank) => {
1920
2021
  return {
1921
- str: `Chaque année, le nombre de joueurs diminue de $${-reason.frenchify()}$.
1922
- Le nombre de joueurs réguliers de Locket Rig est donc une suite arithmétique de premier terme $${initial.frenchify()}$ et de raison $${reason.frenchify()}$.`,
2022
+ str: `Chaque année, le nombre de joueurs diminue de $${-reason.frPretty(2)}$.
2023
+ Le nombre de joueurs réguliers de Locket Rig est donc une suite arithmétique de premier terme $${initial.frPretty(2)}$ et de raison $${reason.frPretty(2)}$.`,
1923
2024
  };
1924
2025
  },
1925
2026
  },