math-exercises 3.0.161 → 3.0.163

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.
@@ -72,7 +72,7 @@ $$
72
72
  `;
73
73
  };
74
74
  const getHint = () => {
75
- return "Développe et réduit chacun des produits d'abord. Puis, additionne les deux résultats.";
75
+ return "Développe et réduis chacun des produits d'abord. Puis, additionne les deux résultats.";
76
76
  };
77
77
  const getCorrection = (identifiers) => {
78
78
  const { affine1, affine2, affine3, type, affine4 } = identifiers;
@@ -72,7 +72,7 @@ $$
72
72
  `;
73
73
  };
74
74
  const getHint = () => {
75
- return "Développe et réduit chacun des produits d'abord. Puis, soustrait les deux résultats.";
75
+ return "Développe et réduis chacun des produits d'abord. Puis, soustrais les deux résultats.";
76
76
  };
77
77
  const getCorrection = (identifiers) => {
78
78
  const { affine1, affine2, affine3, type, affine4 } = identifiers;
@@ -1 +1 @@
1
- {"version":3,"file":"inverseImageFunctionGeogebra.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/functions/basics/inverseImageFunctionGeogebra.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAiBT,MAAM,6BAA6B,CAAC;AAcrC,KAAK,WAAW,GAAG;IAEjB,MAAM,EAAE,MAAM,CAAC;IAIf,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC;CACpB,CAAC;AAwRF,eAAO,MAAM,4BAA4B,EAAE,QAAQ,CAAC,WAAW,CAoB9D,CAAC"}
1
+ {"version":3,"file":"inverseImageFunctionGeogebra.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/functions/basics/inverseImageFunctionGeogebra.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAiBT,MAAM,6BAA6B,CAAC;AAgBrC,KAAK,WAAW,GAAG;IAEjB,MAAM,EAAE,MAAM,CAAC;IAIf,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC;CACpB,CAAC;AA8bF,eAAO,MAAM,4BAA4B,EAAE,QAAQ,CAAC,WAAW,CAoB9D,CAAC"}
@@ -3,7 +3,9 @@ import { getDistinctQuestions } from "../../../../exercises/utils/getDistinctQue
3
3
  import { GeogebraConstructor } from "../../../../geogebra/geogebraConstructor.js";
4
4
  import { Line } from "../../../../math/geometry/line.js";
5
5
  import { Parabola } from "../../../../math/geometry/parabola.js";
6
- import { Point } from "../../../../math/geometry/point.js";
6
+ import { Point, PointConstructor } from "../../../../math/geometry/point.js";
7
+ import { GeneralAffineConstructor } from "../../../../math/polynomials/generalAffine.js";
8
+ import { TrinomConstructor } from "../../../../math/polynomials/trinom.js";
7
9
  import { randfloat } from "../../../../math/utils/random/randfloat.js";
8
10
  import { randint } from "../../../../math/utils/random/randint.js";
9
11
  import { round } from "../../../../math/utils/round.js";
@@ -44,7 +46,15 @@ const getGGBOptions = (identifiers) => {
44
46
  const xMax = Math.max(...Xs);
45
47
  const yMin = Math.min(...Ys);
46
48
  const yMax = Math.max(...Ys);
47
- const ggb = new GeogebraConstructor({ commands });
49
+ const ggb = new GeogebraConstructor({
50
+ commands,
51
+ xAxis: {
52
+ steps: 1,
53
+ },
54
+ yAxis: {
55
+ steps: 1,
56
+ },
57
+ });
48
58
  return ggb.getOptions({
49
59
  coords: ggb.getAdaptedCoords({
50
60
  xMin,
@@ -209,26 +219,50 @@ const isAnswerValid = (ans, { answer, points, yValue }) => {
209
219
  }
210
220
  return true;
211
221
  };
212
- const getFeedback = (ans, { answer: _answer, ...identifiers }) => {
213
- const { points } = identifiers;
214
- //A3-1. Image au lieu d'antécédent
215
- //A3-2. Intersection axe abscisse
216
- //A3-3. Intersection ordonnée
217
- //A3-4. Abscisse maximum
218
- //A3-5. Abscisse minimum
219
- //C3-1. Une seule solution au lieu de deux
220
- //D. Lecture graphique peu précise (réponse proche mais pas correcte)
221
- if (points.length === 1) {
222
+ const getFeedback = (ans, { answer, ...identifiers }) => {
223
+ const { points, yValue } = identifiers;
224
+ if (points.length === 2) {
222
225
  const studentAns = valueParser(ans);
223
226
  if (studentAns === false)
224
227
  return {
225
228
  errorType: "X",
226
229
  feedback: "Réponse mal écrite",
227
230
  };
228
- if (points.some((p) => p[1] === studentAns)) {
231
+ const pointA = new Point("A", points[0][0], points[0][1]);
232
+ const pointB = new Point("B", points[1][0], points[1][1]);
233
+ const affine = GeneralAffineConstructor.fromPoints(pointA, pointB);
234
+ const image = affine.image(yValue);
235
+ if (Math.abs(studentAns - image.evaluate()) < 0.3) {
229
236
  return {
230
237
  errorType: "A3-1",
231
- feedback: "Tu as donné l'image au lieu de l'antécédent",
238
+ feedback: `Pour lire une image, la technique est la suivante (ici l'image de $4$ est $2$) :
239
+
240
+ ![](https://heureuxhasarddocsbucket.s3.eu-west-3.amazonaws.com/mathliveV2/activities/quizzes/generator/imageReading.png)
241
+
242
+ Et pour lire un antécédent, comment fait-on ? Sur quel axe, lit-on les antécédents ?`,
243
+ };
244
+ }
245
+ if (affine.a.evaluate() !== 0) {
246
+ const root = affine.getRoot();
247
+ if (Math.abs(studentAns - root.evaluate()) < 0.3) {
248
+ return {
249
+ errorType: "A3-2",
250
+ feedback: "Tu as trouvé l'intersection de la courbe avec l'axe des abscisses. Cette technique est pertinente pour trouver les antécédents de 0, mais pas pour trouver les antécédents d'un nombre différent de 0. De manière générale, comment fait-on pour lire les antécédents d'un nombre ?",
251
+ };
252
+ }
253
+ }
254
+ const ordOrigine = affine.b.evaluate();
255
+ if (Math.abs(studentAns - ordOrigine) < 0.3) {
256
+ return {
257
+ errorType: "A3-3",
258
+ feedback: "Tu as trouvé l'intersection de la courbe avec l'axe des ordonnés, mais cela n'a a priori pas de rapports avec la recherche d'antécédent. Comment fait-on pour lire un antécédent ?",
259
+ };
260
+ }
261
+ const ansNb = answer.unfrenchify();
262
+ if (Math.abs(studentAns - ansNb) < 1) {
263
+ return {
264
+ errorType: "D",
265
+ feedback: "Ta lecture sur le graphique n'est pas assez précise, mais tu as bien compris la procédure à suivre pour répondre à la question.",
232
266
  };
233
267
  }
234
268
  return {
@@ -237,17 +271,136 @@ const getFeedback = (ans, { answer: _answer, ...identifiers }) => {
237
271
  };
238
272
  }
239
273
  else {
240
- return {
241
- errorType: "X",
242
- feedback: "Non corrélable",
274
+ const trinom = TrinomConstructor.fromPoints(points.map((p) => PointConstructor.fromCoords(p)));
275
+ const studentAns = ans.split("\\text{ et }");
276
+ if (studentAns.length === 1) {
277
+ const v = valueParser(studentAns[0]);
278
+ if (v === false)
279
+ return { errorType: "X", feedback: "Réponse mal écrite" };
280
+ const validPoints = points.filter((p) => p[1] === yValue);
281
+ if (validPoints.length === 2 &&
282
+ validPoints.some((p) => Math.abs(p[0] - v) < 0.2)) {
283
+ return {
284
+ errorType: "C3-1",
285
+ feedback: "Tu as trouvé une partie de la réponse, mais ce n'est pas complet. Combien un nombre peut-il avoir d'antécédent ?",
286
+ };
287
+ }
288
+ }
289
+ const values = studentAns.map((e) => valueParser(e));
290
+ const extrema = round(trinom.getBeta(), 5);
291
+ const image = round(trinom.calculate(yValue), 5);
292
+ const roots = trinom.getRoots();
293
+ const c = trinom.c;
294
+ const checkValue = (v) => {
295
+ if (Math.abs(v - image) < 0.2) {
296
+ return {
297
+ errorType: "A3-1",
298
+ feedback: `Pour lire une image, la technique est la suivante (ici l'image de $4$ est $2$) :
299
+
300
+ ![](https://heureuxhasarddocsbucket.s3.eu-west-3.amazonaws.com/mathliveV2/activities/quizzes/generator/imageReading.png)
301
+
302
+ Et pour lire un antécédent, comment fait-on ? Sur quel axe, lit-on les antécédents ?`,
303
+ };
304
+ }
305
+ if (Math.abs(v - c) < 0.2)
306
+ return {
307
+ errorType: "A3-3",
308
+ feedback: "Tu as trouvé l'intersection de la courbe avec l'axe des ordonnés, mais cela n'a a priori pas de rapports avec la recherche d'antécédent. Comment fait-on pour lire un antécédent ?",
309
+ };
310
+ if (Math.abs(v - extrema) < 0.2)
311
+ if (trinom.a < 0)
312
+ return {
313
+ errorType: "A3-4",
314
+ feedback: "Tu as trouvé le maximum de la courbe, mais cela n'a a priori pas de rapports avec la recherche d'antécédent. Comment fait-on pour lire un antécédent ?",
315
+ };
316
+ else {
317
+ return {
318
+ errorType: "A3-5",
319
+ feedback: "Tu as trouvé le minimum de la courbe, mais cela n'a a priori pas de rapports avec la recherche d'antécédent. Comment fait-on pour lire un antécédent ?",
320
+ };
321
+ }
322
+ if (roots.length) {
323
+ if (Math.abs(v - roots[0]) < 0.2 || Math.abs(v - roots[1]) < 0.2) {
324
+ return {
325
+ errorType: "A3-2",
326
+ feedback: "Tu as trouvé l'intersection de la courbe avec l'axe des abscisses. Cette technique est pertinente pour trouver les antécédents de 0, mais pas pour trouver les antécédents d'un nombre différent de 0. De manière générale, comment fait-on pour lire les antécédents d'un nombre ?",
327
+ };
328
+ }
329
+ }
330
+ return {
331
+ errorType: "X",
332
+ feedback: "Non corrélable",
333
+ };
243
334
  };
335
+ const types = values.map((v) => checkValue(v));
336
+ if (values.length === 1)
337
+ return types[0];
338
+ if (types[0].errorType === types[1].errorType) {
339
+ return types[0];
340
+ }
341
+ if (types[0].errorType === "X" && types[1].errorType !== "X") {
342
+ return types[1];
343
+ }
344
+ else
345
+ return types[0];
244
346
  }
245
347
  };
246
348
  const getMethodology = () => {
349
+ // const commands = [
350
+ // "f(x) = (x+2)(x-1)",
351
+ // `Conique_1 : 1.76x^2+6.43y^2+0.77x-51.42y = -102.21`,
352
+ // `step = Slider(1, 4, 1, 1, 100, false, true, true, false)`,
353
+ // "C = (2,4)",
354
+ // `SetVisibleInView(step, 1, false)`,
355
+ // `ShowLabel(C, false)`,
356
+ // "SetFixed(C, true, false)",
357
+ // `SetConditionToShowObject(C, step>1)`,
358
+ // "D = (-3,4)",
359
+ // `ShowLabel(D, false)`,
360
+ // "SetFixed(D, true, false)",
361
+ // `SetConditionToShowObject(D, step>1)`,
362
+ // `g: y=4`,
363
+ // `SetConditionToShowObject(g, step>1)`,
364
+ // "A = (-3,0)",
365
+ // `ShowLabel(A, false)`,
366
+ // "SetFixed(A, true, false)",
367
+ // `SetConditionToShowObject(A, step>2)`,
368
+ // "B = (2,0)",
369
+ // `ShowLabel(B, false)`,
370
+ // "SetFixed(B, true, false)",
371
+ // `SetConditionToShowObject(B, step>2)`,
372
+ // "S_1 = Segment(B,C)",
373
+ // `SetConditionToShowObject(B, step>2)`,
374
+ // `SetLineStyle(S_1, 2)`,
375
+ // "S_2 = Segment(A,D)",
376
+ // `SetConditionToShowObject(B, step>2)`,
377
+ // `SetLineStyle(S_2, 2)`,
378
+ // `text1 = Text("$\\scriptsize 2\\text{ est un}\\\\ \\text{antécédent de }4\\\\ \\text{ par la fonction }f$", (2.69357, 1.61646))`,
379
+ // `SetConditionToShowObject(text1, step>2)`,
380
+ // `SetConditionToShowObject(text1, step>2)`,
381
+ // `I = (2.64071, 0.39819)`,
382
+ // `SetVisibleInView(I, 1, false)`,
383
+ // `v = Vector(I, B)`,
384
+ // `SetConditionToShowObject(v, step>2)`,
385
+ // `text2 = Text("$\\scriptsize -3 \\text{ est un autre} \\\\ \\text{antécédent de } 4 \\\\ \\text{par la fonction }f$", (-6.27307, 1.61256))`,
386
+ // `SetConditionToShowObject(text2, step>3)`,
387
+ // `H = (-3.83865, 0.62044)`,
388
+ // `SetVisibleInView(H, 1, false)`,
389
+ // `u = Vector(H, A)`,
390
+ // `SetConditionToShowObject(u, step>3)`,
391
+ // `StartAnimation(step, true)`,
392
+ // ];
247
393
  return {
248
- methodology: `Voici la méthodologie blah blah blah
394
+ methodology: `Chercher des antécédents d'un réel $4$ par la fonction f, c'est déterminer les réels $x$ tels que $f(x)=4$.
395
+
396
+ La donnée $4$ se trouve donc sur l'axe des ordonnées et les antécédents cherchés doivent donc se trouver sur l'axe des abscisses !
397
+
398
+ Voici la technique à employer pour trouver les antécédents de $4$ :
249
399
 
250
- ![](https://heureuxhasarddocsbucket.s3.eu-west-3.amazonaws.com/mathliveV2/activities/quizzes/generator/antecedentReading.png)`,
400
+ ![](https://heureuxhasarddocsbucket.s3.eu-west-3.amazonaws.com/mathliveV2/activities/quizzes/generator/antecedentMethodo.gif)`,
401
+ // methodologyGGBOptions: ggb.getOptions({
402
+ // coords: [-8, 6, -3, 5],
403
+ // }),
251
404
  };
252
405
  };
253
406
  export const inverseImageFunctionGeogebra = {
@@ -1 +1 @@
1
- {"version":3,"file":"isPointOnCubicFunction.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/functions/cube/isPointOnCubicFunction.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAaT,MAAM,6BAA6B,CAAC;AAKrC,OAAO,EACL,eAAe,EAEhB,MAAM,qCAAqC,CAAC;AAK7C,KAAK,WAAW,GAAG;IACjB,CAAC,EAAE,eAAe,CAAC;IACnB,CAAC,EAAE,eAAe,CAAC;CACpB,CAAC;AA0FF,eAAO,MAAM,sBAAsB,EAAE,QAAQ,CAAC,WAAW,CAiBxD,CAAC"}
1
+ {"version":3,"file":"isPointOnCubicFunction.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/functions/cube/isPointOnCubicFunction.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAaT,MAAM,6BAA6B,CAAC;AAKrC,OAAO,EACL,eAAe,EAEhB,MAAM,qCAAqC,CAAC;AAK7C,KAAK,WAAW,GAAG;IACjB,CAAC,EAAE,eAAe,CAAC;IACnB,CAAC,EAAE,eAAe,CAAC;CACpB,CAAC;AAgGF,eAAO,MAAM,sBAAsB,EAAE,QAAQ,CAAC,WAAW,CAiBxD,CAAC"}
@@ -34,7 +34,13 @@ const getInstruction = (identifiers) => {
34
34
  return `Le point $${point.toTexWithCoords()}$ appartient-il à la courbe de la fonction cube ?`;
35
35
  };
36
36
  const getHint = () => {
37
- return `Un point de coordonnées $(x;y)$ appartient à la courbe d'une fonction $f$ si et seulement $y = f(x)$.`;
37
+ return `Un point de coordonnées $(x;y)$ appartient à la courbe d'une fonction $f$ si et seulement $y = f(x)$.
38
+
39
+ On rappelle de plus que la fonction cube est la fonction $f$ définie sur $\\mathbb{R}$ par :
40
+
41
+ $$
42
+ f(x) = x^3
43
+ $$`;
38
44
  };
39
45
  const getCorrection = (identifiers) => {
40
46
  const { x, y } = identifiers;
@@ -15,6 +15,7 @@ export declare abstract class PointConstructor {
15
15
  static origin(name?: string): Point;
16
16
  static random(name: string, min?: number, max?: number): Point;
17
17
  static fromIdentifiers(identifiers: PointIdentifiers): Point;
18
+ static fromCoords(coords: number[], name?: string): Point;
18
19
  static onSegment(segment: Segment, name: string, { spacing, coefficient, }?: {
19
20
  spacing?: number;
20
21
  coefficient?: number;
@@ -1 +1 @@
1
- {"version":3,"file":"point.d.ts","sourceRoot":"","sources":["../../../src/math/geometry/point.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"point.d.ts","sourceRoot":"","sources":["../../../src/math/geometry/point.ts"],"names":[],"mappings":"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"}
@@ -35,6 +35,9 @@ export class PointConstructor {
35
35
  static fromIdentifiers(identifiers) {
36
36
  return new Point(identifiers.name, NodeConstructor.fromIdentifiers(identifiers.x), NodeConstructor.fromIdentifiers(identifiers.y));
37
37
  }
38
+ static fromCoords(coords, name = "A") {
39
+ return new Point(name, new NumberNode(coords[0]), new NumberNode(coords[1]));
40
+ }
38
41
  static onSegment(segment, name, { spacing = 0.1, coefficient, } = {}) {
39
42
  const coeff = coefficient ?? randfloat(spacing, 1 - spacing);
40
43
  const vector = VectorConstructor.fromSegment(segment).times(coeff.toTree());
@@ -1,11 +1,13 @@
1
1
  import { AlgebraicNode } from "../../tree/nodes/algebraicNode.js";
2
2
  import { NodeIdentifiers } from "../../tree/nodes/nodeConstructor.js";
3
3
  import { IntervalNode } from "../../tree/nodes/sets/intervalNode.js";
4
+ import { Point } from "../geometry/point.js";
4
5
  export declare abstract class GeneralAffineConstructor {
5
6
  static fromIdentifiers(identifiers: GeneralAffineIdentifiers): GeneralAffine;
6
7
  static randomInts({ allowBNull }: {
7
8
  allowBNull?: boolean | undefined;
8
9
  }, variable?: string): GeneralAffine;
10
+ static fromPoints(pointA: Point, pointB: Point): GeneralAffine;
9
11
  }
10
12
  export type GeneralAffineIdentifiers = {
11
13
  id: "affine";
@@ -25,5 +27,6 @@ export declare class GeneralAffine {
25
27
  toTree(): import("../../tree/nodes/operators/addNode.js").AddNode | import("../../tree/nodes/operators/multiplyNode.js").MultiplyNode;
26
28
  xIntersect(aff: GeneralAffine): AlgebraicNode | undefined;
27
29
  opposite(): GeneralAffine;
30
+ image(x: AlgebraicNode | number): AlgebraicNode;
28
31
  }
29
32
  //# sourceMappingURL=generalAffine.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"generalAffine.d.ts","sourceRoot":"","sources":["../../../src/math/polynomials/generalAffine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAElE,OAAO,EACL,eAAe,EAEhB,MAAM,qCAAqC,CAAC;AAU7C,OAAO,EAAE,YAAY,EAAE,MAAM,uCAAuC,CAAC;AAGrE,8BAAsB,wBAAwB;IAC5C,MAAM,CAAC,eAAe,CAAC,WAAW,EAAE,wBAAwB;IAM5D,MAAM,CAAC,UAAU,CAAC,EAAE,UAAiB,EAAE;;KAAA,EAAE,QAAQ,SAAM;CAOxD;AACD,MAAM,MAAM,wBAAwB,GAAG;IACrC,EAAE,EAAE,QAAQ,CAAC;IACb,CAAC,EAAE,eAAe,CAAC;IACnB,CAAC,EAAE,eAAe,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AACF,qBAAa,aAAa;IACxB,CAAC,EAAE,aAAa,CAAC;IACjB,CAAC,EAAE,aAAa,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;gBAGf,CAAC,EAAE,MAAM,GAAG,aAAa,EACzB,CAAC,EAAE,MAAM,GAAG,aAAa,EACzB,QAAQ,GAAE,MAAY;IAUxB,aAAa,IAAI,wBAAwB;IAQzC,OAAO,IAAI,aAAa;IAGxB,mBAAmB,IAAI,YAAY;IAQnC,mBAAmB,IAAI,YAAY;IASnC,MAAM;IAMN,UAAU,CAAC,GAAG,EAAE,aAAa;IAI7B,QAAQ;CAMT"}
1
+ {"version":3,"file":"generalAffine.d.ts","sourceRoot":"","sources":["../../../src/math/polynomials/generalAffine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAElE,OAAO,EACL,eAAe,EAEhB,MAAM,qCAAqC,CAAC;AAU7C,OAAO,EAAE,YAAY,EAAE,MAAM,uCAAuC,CAAC;AACrE,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAG7C,8BAAsB,wBAAwB;IAC5C,MAAM,CAAC,eAAe,CAAC,WAAW,EAAE,wBAAwB;IAM5D,MAAM,CAAC,UAAU,CAAC,EAAE,UAAiB,EAAE;;KAAA,EAAE,QAAQ,SAAM;IAOvD,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK;CAU/C;AACD,MAAM,MAAM,wBAAwB,GAAG;IACrC,EAAE,EAAE,QAAQ,CAAC;IACb,CAAC,EAAE,eAAe,CAAC;IACnB,CAAC,EAAE,eAAe,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AACF,qBAAa,aAAa;IACxB,CAAC,EAAE,aAAa,CAAC;IACjB,CAAC,EAAE,aAAa,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;gBAGf,CAAC,EAAE,MAAM,GAAG,aAAa,EACzB,CAAC,EAAE,MAAM,GAAG,aAAa,EACzB,QAAQ,GAAE,MAAY;IAUxB,aAAa,IAAI,wBAAwB;IAQzC,OAAO,IAAI,aAAa;IAKxB,mBAAmB,IAAI,YAAY;IAQnC,mBAAmB,IAAI,YAAY;IASnC,MAAM;IAMN,UAAU,CAAC,GAAG,EAAE,aAAa;IAI7B,QAAQ;IAMR,KAAK,CAAC,CAAC,EAAE,aAAa,GAAG,MAAM;CAGhC"}
@@ -15,6 +15,13 @@ export class GeneralAffineConstructor {
15
15
  static randomInts({ allowBNull = true }, variable = "x") {
16
16
  return new GeneralAffine(randint(-10, 11, [0]), randint(-10, 11, allowBNull ? [] : [0]), variable);
17
17
  }
18
+ static fromPoints(pointA, pointB) {
19
+ if (pointA.x.equals(pointB.x))
20
+ throw new Error("Not an affine function");
21
+ const a = frac(substract(pointB.y, pointA.y), substract(pointB.x, pointA.x)).simplify();
22
+ const b = substract(pointA.y, multiply(a, pointA.x)).simplify();
23
+ return new GeneralAffine(a, b);
24
+ }
18
25
  }
19
26
  export class GeneralAffine {
20
27
  a;
@@ -25,8 +32,6 @@ export class GeneralAffine {
25
32
  this.a = a.toTree();
26
33
  else
27
34
  this.a = a;
28
- if (this.a.evaluate() === 0)
29
- throw new Error("Forbidden division by zero");
30
35
  if (typeof b === "number")
31
36
  this.b = b.toTree();
32
37
  else
@@ -42,6 +47,8 @@ export class GeneralAffine {
42
47
  };
43
48
  }
44
49
  getRoot() {
50
+ if (this.a.evaluate() === 0)
51
+ throw new Error("No root for constant function");
45
52
  return frac(opposite(this.b), this.a).simplify();
46
53
  }
47
54
  getPositiveInterval() {
@@ -76,4 +83,7 @@ export class GeneralAffine {
76
83
  opposite() {
77
84
  return new GeneralAffine(opposite(this.a).simplify(), opposite(this.b).simplify());
78
85
  }
86
+ image(x) {
87
+ return add(multiply(this.a, x), this.b).simplify();
88
+ }
79
89
  }
@@ -55,6 +55,7 @@ export declare abstract class TrinomConstructor {
55
55
  a: number;
56
56
  }): Trinom;
57
57
  static fromRootsAndSummitY(roots: number[], ySummit: number): Trinom;
58
+ static fromPoints(points: Point[]): Trinom;
58
59
  }
59
60
  type TrinomOptions = {
60
61
  variable: string;
@@ -1 +1 @@
1
- {"version":3,"file":"trinom.d.ts","sourceRoot":"","sources":["../../../src/math/polynomials/trinom.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,wCAAwC,CAAC;AACpE,OAAO,EAAO,OAAO,EAAE,MAAM,uCAAuC,CAAC;AAErE,OAAO,EAEL,YAAY,EACb,MAAM,4CAA4C,CAAC;AAGpD,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAG7C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAM7C,OAAO,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAKlE,8BAAsB,iBAAiB;IACrC,MAAM,CAAC,MAAM,CACX,KAAK,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,EAC3D,KAAK,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,EAC3D,KAAK,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,GAC1D,MAAM;IAmBT,MAAM,CAAC,eAAe,CACpB,KAAK,CAAC,EAAE;QACN,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;QACpB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;KACjB,EACD,SAAS,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,EAC/D,QAAQ,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,GAC7D,MAAM;IAmBT,MAAM,CAAC,gBAAgB,CACrB,KAAK,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,EAC3D,MAAM,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,EAC5D,MAAM,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,GAC3D,MAAM;IAoBT,MAAM,CAAC,eAAe,CAAC,SAAS,GAAE,MAAU;IAsB5C,MAAM,CAAC,wBAAwB;IAO/B,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE;IAIlC,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM;IAM3C,MAAM,CAAC,aAAa,CAAC,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE;IAOvE,MAAM,CAAC,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,MAAM;CAK5D;AAED,KAAK,aAAa,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC;AAC1C,qBAAa,MAAO,SAAQ,UAAU;IACpC,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,QAAQ,EAAE,MAAM,CAAC;gBAEL,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,aAAa;IAQjE,QAAQ;IAGR,YAAY,IAAI,UAAU;IAI1B,QAAQ;IAUR,YAAY,IAAI,aAAa,EAAE;IAyD/B,2BAA2B,CAAC,eAAe,CAAC,EAAE,OAAO;IAarD,QAAQ;IAGR,YAAY;IAIZ,OAAO;IAIP,WAAW;IAIX,YAAY;IAeZ,gBAAgB;IAsBhB,SAAS;IAIT,SAAS;IAYT,QAAQ;IAkCR,aAAa,CACX,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE;;;;KAA4C;CAYrE"}
1
+ {"version":3,"file":"trinom.d.ts","sourceRoot":"","sources":["../../../src/math/polynomials/trinom.ts"],"names":[],"mappings":"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"}
@@ -14,6 +14,7 @@ import { gcd } from "../utils/arithmetic/gcd.js";
14
14
  import { randint } from "../utils/random/randint.js";
15
15
  import { random } from "../../utils/alea/random.js";
16
16
  import { blueMain } from "../../geogebra/colors.js";
17
+ import { round } from "../utils/round.js";
17
18
  export class TrinomConstructor {
18
19
  static random(aOpts, bOpts, cOpts) {
19
20
  const a = randint(aOpts?.min ?? -9, aOpts?.max ?? 10, aOpts?.excludes ?? [0]);
@@ -86,6 +87,18 @@ export class TrinomConstructor {
86
87
  const a = ySummit / ((x2 - x1) / 2) ** 2;
87
88
  return this.fromRoots(roots, a);
88
89
  }
90
+ static fromPoints(points) {
91
+ const sorted = [...points.sort((a, b) => a.x.evaluate() - b.x.evaluate())];
92
+ const [x1, y1] = [sorted[0].x.evaluate(), sorted[0].y.evaluate()];
93
+ const [x2, y2] = [sorted[1].x.evaluate(), sorted[1].y.evaluate()];
94
+ const [x3, y3] = [sorted[2].x.evaluate(), sorted[2].y.evaluate()];
95
+ const delta1 = round((y2 - y1) / (x2 - x1), 5);
96
+ const delta2 = round((y3 - y2) / (x3 - x2), 5);
97
+ const a = round((delta2 - delta1) / (x3 - x1), 5);
98
+ const b = round(delta1 - a * (x1 + x2), 5);
99
+ const c = round(y1 - a * x1 * x1 - b * x1, 5);
100
+ return new Trinom(a, b, c);
101
+ }
89
102
  }
90
103
  export class Trinom extends Polynomial {
91
104
  a;
package/lib/server.js CHANGED
@@ -226,6 +226,27 @@ const runServer = () => {
226
226
  .id,
227
227
  });
228
228
  });
229
+ app.post("/feedback", jsonParser, (req, res) => {
230
+ const exoId = req.query.exoId;
231
+ const options = req.query.options
232
+ ? JSON.parse(decodeURIComponent(req.query.options))
233
+ : undefined;
234
+ const { ans, feedbackProps } = req.body;
235
+ const exoIndex = allExercises.findIndex((exo) => exo.id == exoId);
236
+ const exo = allExercises[exoIndex];
237
+ if (!exo) {
238
+ res.send("Exo not found");
239
+ return;
240
+ }
241
+ if (!exo.getFeedback) {
242
+ res.send("No Feedback implemented");
243
+ return;
244
+ }
245
+ const result = exo.getFeedback(ans, feedbackProps, options) ?? false;
246
+ res.json({
247
+ result,
248
+ });
249
+ });
229
250
  app.post("/vea", jsonParser, (req, res) => {
230
251
  const exoId = req.query.exoId;
231
252
  const options = req.query.options
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "math-exercises",
3
3
  "type": "module",
4
- "version": "3.0.161",
4
+ "version": "3.0.163",
5
5
  "description": "Math exercises generator for middle school and high school",
6
6
  "main": "lib/index.js",
7
7
  "files": [