math-exercises 3.0.215 → 3.0.216

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 (114) hide show
  1. package/lib/exercises/math/arithmetic/whichDayInXDays.d.ts.map +1 -1
  2. package/lib/exercises/math/arithmetic/whichDayInXDays.js +2 -1
  3. package/lib/exercises/math/complex/unitRoots/giveOneSolutionToComplexPowNEqualsOne.js +1 -1
  4. package/lib/exercises/math/conversion/clock/index.d.ts +0 -1
  5. package/lib/exercises/math/conversion/clock/index.d.ts.map +1 -1
  6. package/lib/exercises/math/conversion/clock/index.js +1 -1
  7. package/lib/exercises/math/graphs/adjacentMatrixPath.d.ts +10 -0
  8. package/lib/exercises/math/graphs/adjacentMatrixPath.d.ts.map +1 -0
  9. package/lib/exercises/math/graphs/adjacentMatrixPath.js +89 -0
  10. package/lib/exercises/math/graphs/edgesNumberFromSummitsDegrees.d.ts +7 -0
  11. package/lib/exercises/math/graphs/edgesNumberFromSummitsDegrees.d.ts.map +1 -0
  12. package/lib/exercises/math/graphs/edgesNumberFromSummitsDegrees.js +98 -0
  13. package/lib/exercises/math/graphs/eulerianChainFromAdjacentMatrix.d.ts +8 -0
  14. package/lib/exercises/math/graphs/eulerianChainFromAdjacentMatrix.d.ts.map +1 -0
  15. package/lib/exercises/math/graphs/eulerianChainFromAdjacentMatrix.js +96 -0
  16. package/lib/exercises/math/graphs/graphsChainOrPathOfLengthN.d.ts +15 -0
  17. package/lib/exercises/math/graphs/graphsChainOrPathOfLengthN.d.ts.map +1 -0
  18. package/lib/exercises/math/graphs/graphsChainOrPathOfLengthN.js +262 -0
  19. package/lib/exercises/math/graphs/graphsCheckIsConnectedUndirectedGraph.d.ts +11 -0
  20. package/lib/exercises/math/graphs/graphsCheckIsConnectedUndirectedGraph.d.ts.map +1 -0
  21. package/lib/exercises/math/graphs/graphsCheckIsConnectedUndirectedGraph.js +178 -0
  22. package/lib/exercises/math/graphs/graphsCheckIsSameGraph.d.ts +19 -0
  23. package/lib/exercises/math/graphs/graphsCheckIsSameGraph.d.ts.map +1 -0
  24. package/lib/exercises/math/graphs/graphsCheckIsSameGraph.js +301 -0
  25. package/lib/exercises/math/graphs/graphsCheckIsVerticesAdjacent.d.ts +16 -0
  26. package/lib/exercises/math/graphs/graphsCheckIsVerticesAdjacent.d.ts.map +1 -0
  27. package/lib/exercises/math/graphs/graphsCheckIsVerticesAdjacent.js +207 -0
  28. package/lib/exercises/math/graphs/graphsDegreeOfVertex.d.ts +15 -0
  29. package/lib/exercises/math/graphs/graphsDegreeOfVertex.d.ts.map +1 -0
  30. package/lib/exercises/math/graphs/graphsDegreeOfVertex.js +232 -0
  31. package/lib/exercises/math/graphs/graphsOrderOfGraph.d.ts +14 -0
  32. package/lib/exercises/math/graphs/graphsOrderOfGraph.d.ts.map +1 -0
  33. package/lib/exercises/math/graphs/graphsOrderOfGraph.js +222 -0
  34. package/lib/exercises/math/graphs/index.d.ts +10 -0
  35. package/lib/exercises/math/graphs/index.d.ts.map +1 -0
  36. package/lib/exercises/math/graphs/index.js +9 -0
  37. package/lib/exercises/math/index.d.ts +1 -0
  38. package/lib/exercises/math/index.d.ts.map +1 -1
  39. package/lib/exercises/math/index.js +1 -0
  40. package/lib/exercises/math/matrices/areMatricesInverse.d.ts +9 -0
  41. package/lib/exercises/math/matrices/areMatricesInverse.d.ts.map +1 -0
  42. package/lib/exercises/math/matrices/areMatricesInverse.js +106 -0
  43. package/lib/exercises/math/matrices/computeFixedMatrixInRecurrenceSequence.d.ts +9 -0
  44. package/lib/exercises/math/matrices/computeFixedMatrixInRecurrenceSequence.d.ts.map +1 -0
  45. package/lib/exercises/math/matrices/computeFixedMatrixInRecurrenceSequence.js +144 -0
  46. package/lib/exercises/math/matrices/findInversedMatrixFromSystem.d.ts +8 -0
  47. package/lib/exercises/math/matrices/findInversedMatrixFromSystem.d.ts.map +1 -0
  48. package/lib/exercises/math/matrices/findInversedMatrixFromSystem.js +148 -0
  49. package/lib/exercises/math/matrices/index.d.ts +12 -0
  50. package/lib/exercises/math/matrices/index.d.ts.map +1 -1
  51. package/lib/exercises/math/matrices/index.js +12 -0
  52. package/lib/exercises/math/matrices/isMatrixTransitionMatrix.d.ts +8 -0
  53. package/lib/exercises/math/matrices/isMatrixTransitionMatrix.d.ts.map +1 -0
  54. package/lib/exercises/math/matrices/isMatrixTransitionMatrix.js +132 -0
  55. package/lib/exercises/math/matrices/matrixBuildMatrixFromCoefficients.d.ts +8 -0
  56. package/lib/exercises/math/matrices/matrixBuildMatrixFromCoefficients.d.ts.map +1 -0
  57. package/lib/exercises/math/matrices/matrixBuildMatrixFromCoefficients.js +152 -0
  58. package/lib/exercises/math/matrices/matrixCheckIsSymmetrical.d.ts +8 -0
  59. package/lib/exercises/math/matrices/matrixCheckIsSymmetrical.d.ts.map +1 -0
  60. package/lib/exercises/math/matrices/matrixCheckIsSymmetrical.js +155 -0
  61. package/lib/exercises/math/matrices/matrixComputeDetOfMat2.d.ts +8 -0
  62. package/lib/exercises/math/matrices/matrixComputeDetOfMat2.d.ts.map +1 -0
  63. package/lib/exercises/math/matrices/matrixComputeDetOfMat2.js +142 -0
  64. package/lib/exercises/math/matrices/matrixComputeInverseOfMat2.d.ts +8 -0
  65. package/lib/exercises/math/matrices/matrixComputeInverseOfMat2.d.ts.map +1 -0
  66. package/lib/exercises/math/matrices/matrixComputeInverseOfMat2.js +237 -0
  67. package/lib/exercises/math/matrices/matrixComputeLinearCombination.d.ts +15 -0
  68. package/lib/exercises/math/matrices/matrixComputeLinearCombination.d.ts.map +1 -0
  69. package/lib/exercises/math/matrices/matrixComputeLinearCombination.js +232 -0
  70. package/lib/exercises/math/matrices/matrixComputePower.d.ts +12 -0
  71. package/lib/exercises/math/matrices/matrixComputePower.d.ts.map +1 -0
  72. package/lib/exercises/math/matrices/matrixComputePower.js +230 -0
  73. package/lib/exercises/math/matrices/matrixComputeProduct.d.ts +9 -0
  74. package/lib/exercises/math/matrices/matrixComputeProduct.d.ts.map +1 -0
  75. package/lib/exercises/math/matrices/matrixComputeProduct.js +178 -0
  76. package/lib/exercises/math/matrices/writeMatrixAssociatedToSystem.d.ts +8 -0
  77. package/lib/exercises/math/matrices/writeMatrixAssociatedToSystem.d.ts.map +1 -0
  78. package/lib/exercises/math/matrices/writeMatrixAssociatedToSystem.js +105 -0
  79. package/lib/exercises/vea/matrixVEA.d.ts +2 -0
  80. package/lib/exercises/vea/matrixVEA.d.ts.map +1 -0
  81. package/lib/exercises/vea/matrixVEA.js +1 -0
  82. package/lib/index.d.ts +86 -13
  83. package/lib/index.d.ts.map +1 -1
  84. package/lib/math/geometry/point.d.ts.map +1 -1
  85. package/lib/math/geometry/point.js +3 -1
  86. package/lib/math/graphs/graph.d.ts +43 -0
  87. package/lib/math/graphs/graph.d.ts.map +1 -0
  88. package/lib/math/graphs/graph.js +391 -0
  89. package/lib/math/matrices/matrix.d.ts +42 -3
  90. package/lib/math/matrices/matrix.d.ts.map +1 -1
  91. package/lib/math/matrices/matrix.js +173 -7
  92. package/lib/math/matrices/parseMatrix.d.ts +3 -0
  93. package/lib/math/matrices/parseMatrix.d.ts.map +1 -0
  94. package/lib/math/matrices/parseMatrix.js +22 -0
  95. package/lib/math/systems/generalSystem.d.ts +2 -0
  96. package/lib/math/systems/generalSystem.d.ts.map +1 -1
  97. package/lib/math/systems/generalSystem.js +5 -0
  98. package/lib/math/utils/graphs/graphRenderer.d.ts +25 -0
  99. package/lib/math/utils/graphs/graphRenderer.d.ts.map +1 -0
  100. package/lib/math/utils/graphs/graphRenderer.js +123 -0
  101. package/lib/playground.d.ts +6 -1
  102. package/lib/playground.d.ts.map +1 -1
  103. package/lib/playground.js +6 -5
  104. package/lib/tree/parsers/latexParser.d.ts +1 -1
  105. package/lib/tree/utilities/nodeSimplifier.d.ts +1 -1
  106. package/lib/types/keyIds.d.ts +2 -0
  107. package/lib/types/keyIds.d.ts.map +1 -1
  108. package/lib/utils/arrays/arrayChunks.d.ts +9 -0
  109. package/lib/utils/arrays/arrayChunks.d.ts.map +1 -0
  110. package/lib/utils/arrays/arrayChunks.js +34 -0
  111. package/lib/utils/strings/ordinalSuffixed.d.ts +2 -0
  112. package/lib/utils/strings/ordinalSuffixed.d.ts.map +1 -0
  113. package/lib/utils/strings/ordinalSuffixed.js +5 -0
  114. package/package.json +7 -1
@@ -1 +1 @@
1
- {"version":3,"file":"whichDayInXDays.d.ts","sourceRoot":"","sources":["../../../../src/exercises/math/arithmetic/whichDayInXDays.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAaT,MAAM,6BAA6B,CAAC;AAOrC,KAAK,WAAW,GAAG;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAyEF,eAAO,MAAM,eAAe,EAAE,QAAQ,CAAC,WAAW,CAiBjD,CAAC"}
1
+ {"version":3,"file":"whichDayInXDays.d.ts","sourceRoot":"","sources":["../../../../src/exercises/math/arithmetic/whichDayInXDays.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAaT,MAAM,6BAA6B,CAAC;AAQrC,KAAK,WAAW,GAAG;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAyEF,eAAO,MAAM,eAAe,EAAE,QAAQ,CAAC,WAAW,CAiBjD,CAAC"}
@@ -4,6 +4,7 @@ import { randint } from "../../../math/utils/random/randint.js";
4
4
  import { random } from "../../../utils/alea/random.js";
5
5
  import { doWhile } from "../../../utils/doWhile.js";
6
6
  import { frenchDays } from "../../../utils/strings/frenchDays.js";
7
+ import { pluralize } from "../../../utils/strings/pluralize.js";
7
8
  const getPropositions = (n, { answer }) => {
8
9
  const propositions = [];
9
10
  addValidProp(propositions, answer, "raw");
@@ -39,7 +40,7 @@ $$
39
40
  ${step} = 7\\times ${quot} + ${left}
40
41
  $$
41
42
 
42
- En ajoutant $${left}$ jours à ${day}, on obtient ${answer}.
43
+ En ajoutant $${left}$ ${pluralize("jour", left)} à ${day}, on obtient ${answer}.
43
44
 
44
45
  Dans $${step}$ jours, nous serons donc ${answer}.
45
46
  `;
@@ -56,7 +56,7 @@ si et seulement si $${substract("z", a)
56
56
  const getCorrection = (identifiers) => {
57
57
  const { a, n } = identifiers;
58
58
  const root = `e^{i${frac(multiply(2, PiNode), n).simplify().toTex()}}`;
59
- const equa = `${power(substract("z", a).simplify().toTex(), n)} = 1`;
59
+ const equa = `${power(substract("z", a).simplify(), n).toTex()} = 1`;
60
60
  return `$z$ est une solution de l'équation
61
61
 
62
62
  $$
@@ -1,3 +1,2 @@
1
1
  export * from "./clockReading.js";
2
- export * from "./dateTimeOperationAdd.js";
3
2
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/conversion/clock/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAGlC,cAAc,2BAA2B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/conversion/clock/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC"}
@@ -1,4 +1,4 @@
1
1
  export * from "./clockReading.js";
2
2
  // export * from "./clockReadingPlusTimeOperation.js";
3
3
  // export * from "./clockWritingByManipulatingNeedles.js";
4
- export * from "./dateTimeOperationAdd.js";
4
+ // export * from "./dateTimeOperationAdd.js"; //TODO: à fix
@@ -0,0 +1,10 @@
1
+ import { Exercise } from "../../../exercises/exercise.js";
2
+ import { MatrixIdentifiers } from "../../../math/matrices/matrix.js";
3
+ type Identifiers = {
4
+ matrixIds: MatrixIdentifiers;
5
+ startIndex: number;
6
+ endIndex: number;
7
+ };
8
+ export declare const adjacentMatrixPath: Exercise<Identifiers>;
9
+ export {};
10
+ //# sourceMappingURL=adjacentMatrixPath.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adjacentMatrixPath.d.ts","sourceRoot":"","sources":["../../../../src/exercises/math/graphs/adjacentMatrixPath.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAYT,MAAM,6BAA6B,CAAC;AAErC,OAAO,EAEL,iBAAiB,EAClB,MAAM,+BAA+B,CAAC;AAIvC,KAAK,WAAW,GAAG;IACjB,SAAS,EAAE,iBAAiB,CAAC;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AA6FF,eAAO,MAAM,kBAAkB,EAAE,QAAQ,CAAC,WAAW,CAmBpD,CAAC"}
@@ -0,0 +1,89 @@
1
+ import { addValidProp, shuffleProps, tryToAddWrongProp, } from "../../../exercises/exercise.js";
2
+ import { getDistinctQuestions } from "../../../exercises/utils/getDistinctQuestions.js";
3
+ import { MatrixConstructor, } from "../../../math/matrices/matrix.js";
4
+ import { randint } from "../../../math/utils/random/randint.js";
5
+ import { ordinalSuffixed } from "../../../utils/strings/ordinalSuffixed.js";
6
+ const getPropositions = (n, { answer }) => {
7
+ const propositions = [];
8
+ addValidProp(propositions, answer, "raw");
9
+ tryToAddWrongProp(propositions, "Oui", "raw");
10
+ tryToAddWrongProp(propositions, "Non", "raw");
11
+ return shuffleProps(propositions, n);
12
+ };
13
+ const getAnswer = (identifiers) => {
14
+ const { matrixIds, endIndex, startIndex } = identifiers;
15
+ const matrix = MatrixConstructor.fromIdentifiers(matrixIds);
16
+ return matrix.elements[startIndex][endIndex].toTex() === "0" ? "Non" : "Oui";
17
+ };
18
+ const getInstruction = (identifiers) => {
19
+ const { matrixIds, endIndex, startIndex } = identifiers;
20
+ const matrix = MatrixConstructor.fromIdentifiers(matrixIds);
21
+ const length = matrix.rows;
22
+ const summitNames = Array.from({ length: length }, (_, index) => `$${String.fromCharCode(65 + index)}$`);
23
+ return `La matrice d'adjacence d'un graphe non-orienté $G$ de sommets ${summitNames.join(", ")} est donnée ci-dessous (les sommets sont classés par ordre alphabétique).
24
+
25
+ $$
26
+ ${matrix.toTex()}
27
+ $$
28
+
29
+ Existe-t-il une arête reliant les sommets ${summitNames[startIndex]} et ${summitNames[endIndex]} ? `;
30
+ };
31
+ const getHint = () => {
32
+ return `Dans une matrice d'adjacence, le terme de la $i$-ème ligne et de la $j$-ème colonne est le nombre d'arêtes reliant les sommets $i$ et $j$.`;
33
+ };
34
+ const getCorrection = (identifiers) => {
35
+ const { matrixIds, endIndex, startIndex } = identifiers;
36
+ const matrix = MatrixConstructor.fromIdentifiers(matrixIds);
37
+ const length = matrix.rows;
38
+ const summitNames = Array.from({ length: length }, (_, index) => `$${String.fromCharCode(65 + index)}$`);
39
+ const hasNoEdge = matrix.elements[startIndex][endIndex].toTex() === "0";
40
+ return `Dans une matrice d'adjacence d'un graphe non-orienté, le terme de la $i$-ème ligne et de la $j$-ème colonne est le nombre d'arêtes reliant les sommets $i$ et $j$.
41
+
42
+ Ici, on regarde donc le terme à la ${ordinalSuffixed(startIndex + 1)} ligne et ${ordinalSuffixed(endIndex + 1)} colonne : c'est $${matrix.elements[startIndex][endIndex].toTex()}$.
43
+
44
+ ${!hasNoEdge
45
+ ? `Il y a donc bien une arête reliant les sommets ${summitNames[startIndex]} et ${summitNames[endIndex]}.`
46
+ : `Il n'y a donc pas d'arête reliant les sommets ${summitNames[startIndex]} et ${summitNames[endIndex]}.`}
47
+ `;
48
+ };
49
+ const getAdjacentMatrixPathQuestion = () => {
50
+ const length = randint(4, 6);
51
+ const m = MatrixConstructor.randomAdjacent(length);
52
+ const startIndex = randint(0, length);
53
+ const endIndex = randint(0, length, [startIndex]);
54
+ const identifiers = {
55
+ matrixIds: m.toIdentifiers(),
56
+ startIndex,
57
+ endIndex,
58
+ };
59
+ return getQuestionFromIdentifiers(identifiers);
60
+ };
61
+ const getQuestionFromIdentifiers = (identifiers) => {
62
+ return {
63
+ answer: getAnswer(identifiers),
64
+ instruction: getInstruction(identifiers),
65
+ keys: [],
66
+ answerFormat: "raw",
67
+ identifiers,
68
+ hint: getHint(identifiers),
69
+ correction: getCorrection(identifiers),
70
+ };
71
+ };
72
+ export const adjacentMatrixPath = {
73
+ id: "adjacentMatrixPath",
74
+ connector: "=",
75
+ label: "Vérifier si deux sommets d'un graphe sont reliés grâce à la matrice d'adjacence",
76
+ isSingleStep: true,
77
+ generator: (nb, opts) => getDistinctQuestions(() => getAdjacentMatrixPathQuestion(opts), nb),
78
+ qcmTimer: 60,
79
+ freeTimer: 60,
80
+ getPropositions,
81
+ subject: "Mathématiques",
82
+ getInstruction,
83
+ getHint,
84
+ getCorrection,
85
+ getAnswer,
86
+ getQuestionFromIdentifiers,
87
+ answerType: "QCU",
88
+ hasHintAndCorrection: true,
89
+ };
@@ -0,0 +1,7 @@
1
+ import { Exercise } from "../../../exercises/exercise.js";
2
+ type Identifiers = {
3
+ degrees: number[];
4
+ };
5
+ export declare const edgesNumberFromSummitsDegrees: Exercise<Identifiers>;
6
+ export {};
7
+ //# sourceMappingURL=edgesNumberFromSummitsDegrees.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edgesNumberFromSummitsDegrees.d.ts","sourceRoot":"","sources":["../../../../src/exercises/math/graphs/edgesNumberFromSummitsDegrees.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAeT,MAAM,6BAA6B,CAAC;AAYrC,KAAK,WAAW,GAAG;IACjB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB,CAAC;AA4FF,eAAO,MAAM,6BAA6B,EAAE,QAAQ,CAAC,WAAW,CAsB/D,CAAC"}
@@ -0,0 +1,98 @@
1
+ import { addValidProp, shuffleProps, propWhile, tryToAddWrongProp, } from "../../../exercises/exercise.js";
2
+ import { getDistinctQuestions } from "../../../exercises/utils/getDistinctQuestions.js";
3
+ import { rationalVEA } from "../../../exercises/vea/rationalVEA.js";
4
+ import { randint } from "../../../math/utils/random/randint.js";
5
+ import { randTupleInt } from "../../../math/utils/random/randTupleInt.js";
6
+ import { AddNode } from "../../../tree/nodes/operators/addNode.js";
7
+ import { frac } from "../../../tree/nodes/operators/fractionNode.js";
8
+ import { operatorComposition } from "../../../tree/utilities/operatorComposition.js";
9
+ import { doWhile } from "../../../utils/doWhile.js";
10
+ import { handleVEAError } from "../../../utils/errors/handleVEAError.js";
11
+ import { mdTable } from "../../../utils/markdown/mdTable.js";
12
+ const getPropositions = (n, { answer, degrees }) => {
13
+ const propositions = [];
14
+ addValidProp(propositions, answer);
15
+ tryToAddWrongProp(propositions, degrees.reduce((acc, curr) => acc + curr, 0).frenchify());
16
+ propWhile(propositions, n, () => {
17
+ tryToAddWrongProp(propositions, randint(0, 10).frenchify());
18
+ });
19
+ return shuffleProps(propositions, n);
20
+ };
21
+ const getAnswer = (identifiers) => {
22
+ const { degrees } = identifiers;
23
+ const sum = degrees.reduce((acc, curr) => acc + curr, 0);
24
+ return frac(sum, 2).simplify().toTex();
25
+ };
26
+ const getInstruction = (identifiers) => {
27
+ const { degrees } = identifiers;
28
+ const summitNames = Array.from({ length: degrees.length }, (_, index) => String.fromCharCode(65 + index));
29
+ return `On considère un graphe non-orienté $G$ dont les degrés des sommets sont donnés dans le tableau suivant :
30
+
31
+ ${mdTable([
32
+ ["Sommet", ...summitNames.map((el) => `$${el}$`)],
33
+ ["Degré", ...degrees.map((el) => `$${el}$`)],
34
+ ])}
35
+
36
+ Quel est le nombre d'arêtes de $G$ ?`;
37
+ };
38
+ const getHint = () => {
39
+ return `Le degré d'un sommet est le nombre d'arêtes incidentes à ce sommet. Or, chaque arête relie deux sommets...`;
40
+ };
41
+ const getCorrection = (identifiers) => {
42
+ const { degrees } = identifiers;
43
+ return `Dans un graphe non-orienté, la somme des degrés des sommets est égale au double du nombre d'arêtes.
44
+
45
+ En effet, chaque arête possède deux extrémités, donc chaque arête est comptée deux fois dans la somme des degrés des sommets. Le raisonnement reste valable pour les boucles, qui comptent pour deux dans le degré d'un sommet.
46
+
47
+ Il suffit donc de calculer la somme des degrés et de diviser par $2$ pour obtenir le nombre d'arêtes :
48
+
49
+ $$
50
+ ${operatorComposition(AddNode, degrees.map((e) => e.toTree())).toTex()} = ${getAnswer(identifiers)}
51
+ $$`;
52
+ };
53
+ const getKeys = () => {
54
+ return [];
55
+ };
56
+ const isAnswerValid = (ans, { answer }) => {
57
+ try {
58
+ return rationalVEA(ans, answer);
59
+ }
60
+ catch (err) {
61
+ return handleVEAError(err);
62
+ }
63
+ };
64
+ const getEdgesNumberFromSummitsDegreesQuestion = () => {
65
+ const length = randint(4, 6);
66
+ const degrees = doWhile(() => randTupleInt(length, { from: 2, to: length + 2 }), (arr) => arr.filter((x) => x % 2 !== 0).length % 2 !== 0);
67
+ const identifiers = { degrees };
68
+ return getQuestionFromIdentifiers(identifiers);
69
+ };
70
+ const getQuestionFromIdentifiers = (identifiers) => {
71
+ return {
72
+ answer: getAnswer(identifiers),
73
+ instruction: getInstruction(identifiers),
74
+ keys: getKeys(identifiers),
75
+ answerFormat: "tex",
76
+ identifiers,
77
+ hint: getHint(identifiers),
78
+ correction: getCorrection(identifiers),
79
+ };
80
+ };
81
+ export const edgesNumberFromSummitsDegrees = {
82
+ id: "edgesNumberFromSummitsDegrees",
83
+ connector: "=",
84
+ label: "Déterminer le nombre d'arêtes d'un graphe non-orienté à partir du degré de ses sommets",
85
+ isSingleStep: true,
86
+ generator: (nb, opts) => getDistinctQuestions(() => getEdgesNumberFromSummitsDegreesQuestion(opts), nb),
87
+ qcmTimer: 60,
88
+ freeTimer: 60,
89
+ getPropositions,
90
+ isAnswerValid,
91
+ subject: "Mathématiques",
92
+ getInstruction,
93
+ getHint,
94
+ getCorrection,
95
+ getAnswer,
96
+ getQuestionFromIdentifiers,
97
+ hasHintAndCorrection: true,
98
+ };
@@ -0,0 +1,8 @@
1
+ import { Exercise } from "../../../exercises/exercise.js";
2
+ import { MatrixIdentifiers } from "../../../math/matrices/matrix.js";
3
+ type Identifiers = {
4
+ matrixIds: MatrixIdentifiers;
5
+ };
6
+ export declare const eulerianChainFromAdjacentMatrix: Exercise<Identifiers>;
7
+ export {};
8
+ //# sourceMappingURL=eulerianChainFromAdjacentMatrix.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eulerianChainFromAdjacentMatrix.d.ts","sourceRoot":"","sources":["../../../../src/exercises/math/graphs/eulerianChainFromAdjacentMatrix.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAYT,MAAM,6BAA6B,CAAC;AAErC,OAAO,EAEL,iBAAiB,EAClB,MAAM,+BAA+B,CAAC;AAGvC,KAAK,WAAW,GAAG;IACjB,SAAS,EAAE,iBAAiB,CAAC;CAC9B,CAAC;AA8FF,eAAO,MAAM,+BAA+B,EAAE,QAAQ,CAAC,WAAW,CAqBjE,CAAC"}
@@ -0,0 +1,96 @@
1
+ import { addValidProp, shuffleProps, tryToAddWrongProp, } from "../../../exercises/exercise.js";
2
+ import { getDistinctQuestions } from "../../../exercises/utils/getDistinctQuestions.js";
3
+ import { MatrixConstructor, } from "../../../math/matrices/matrix.js";
4
+ import { randint } from "../../../math/utils/random/randint.js";
5
+ const getPropositions = (n, { answer }) => {
6
+ const propositions = [];
7
+ addValidProp(propositions, answer, "raw");
8
+ tryToAddWrongProp(propositions, "Oui", "raw");
9
+ tryToAddWrongProp(propositions, "Non", "raw");
10
+ return shuffleProps(propositions, n);
11
+ };
12
+ const getAnswer = (identifiers) => {
13
+ const matrix = MatrixConstructor.fromIdentifiers(identifiers.matrixIds);
14
+ const degrees = [];
15
+ for (let i = 0; i < matrix.rows; i++) {
16
+ degrees.push(matrix.elements[i].reduce((acc, el) => acc + el.evaluate(), 0));
17
+ }
18
+ const unEvenDegrees = degrees.filter((deg) => deg % 2 !== 0).length;
19
+ return unEvenDegrees === 0 || unEvenDegrees === 2 ? "Oui" : "Non";
20
+ };
21
+ const getInstruction = (identifiers) => {
22
+ const matrix = MatrixConstructor.fromIdentifiers(identifiers.matrixIds);
23
+ return `La matrice d'adjacence d'un graphe non-orienté $G$ est donnée ci-dessous.
24
+
25
+ $$
26
+ ${matrix.toTex()}
27
+ $$
28
+
29
+ Le graphe $G$ admet-il une chaîne eulérienne ?
30
+ `;
31
+ };
32
+ const getHint = () => {
33
+ return `Une chaîne eulérienne est une chaîne (donc une suite de sommets adjacents) qui contient chaque arête du graphe une et une seule fois.
34
+
35
+ Un certain théorème du cours permet de déterminer si une telle chaîne existe dans un graphe !`;
36
+ };
37
+ const getCorrection = (identifiers) => {
38
+ const matrix = MatrixConstructor.fromIdentifiers(identifiers.matrixIds);
39
+ const degrees = [];
40
+ for (let i = 0; i < matrix.rows; i++) {
41
+ degrees.push(matrix.elements[i].reduce((acc, el) => acc + el.evaluate(), 0));
42
+ }
43
+ const unEvenDegrees = degrees.filter((deg) => deg % 2 !== 0).length;
44
+ return `D'après le théorème d'Euler, un graphe connexe non-orienté admet une chaîne eulérienne si et seulement si le nombre de sommets de degré impair vaut $0$ ou $2$.
45
+
46
+ Il s'agit donc ici de déterminer les degrés de chaque sommet. Pour cela, il suffit d'additionner les termes de chaque ligne de la matrice d'adjacence.
47
+
48
+ On obtient :
49
+
50
+ $$
51
+ ${degrees.map((e) => `${e.frenchify()}`).join("\\ ; \\ ")}
52
+ $$
53
+
54
+ Il y a donc $${unEvenDegrees.frenchify()}$ sommet(s) de degré impair.
55
+
56
+ ${unEvenDegrees === 0 || unEvenDegrees === 2
57
+ ? "Il existe donc bien une chaîne eulérienne dans ce graphe."
58
+ : "Il n'existe donc pas de chaîne eulérienne dans ce graphe."}
59
+ `;
60
+ };
61
+ const getEulerianChainFromAdjacentMatrixQuestion = () => {
62
+ const length = randint(4, 6);
63
+ const mat = MatrixConstructor.randomAdjacent(length);
64
+ const identifiers = {
65
+ matrixIds: mat.toIdentifiers(),
66
+ };
67
+ return getQuestionFromIdentifiers(identifiers);
68
+ };
69
+ const getQuestionFromIdentifiers = (identifiers) => {
70
+ return {
71
+ answer: getAnswer(identifiers),
72
+ instruction: getInstruction(identifiers),
73
+ keys: [],
74
+ answerFormat: "tex",
75
+ identifiers,
76
+ hint: getHint(identifiers),
77
+ correction: getCorrection(identifiers),
78
+ };
79
+ };
80
+ export const eulerianChainFromAdjacentMatrix = {
81
+ id: "eulerianChainFromAdjacentMatrix",
82
+ label: "Déterminer si un graphe admet une chaîne eulérienne à partir de sa matrice d'adjacence",
83
+ isSingleStep: true,
84
+ generator: (nb, opts) => getDistinctQuestions(() => getEulerianChainFromAdjacentMatrixQuestion(opts), nb),
85
+ qcmTimer: 60,
86
+ freeTimer: 60,
87
+ getPropositions,
88
+ answerType: "QCU",
89
+ subject: "Mathématiques",
90
+ getInstruction,
91
+ getHint,
92
+ getCorrection,
93
+ getAnswer,
94
+ getQuestionFromIdentifiers,
95
+ hasHintAndCorrection: true,
96
+ };
@@ -0,0 +1,15 @@
1
+ import { Exercise } from "../../../exercises/exercise.js";
2
+ import { GraphIdentifiers } from "../../../math/graphs/graph.js";
3
+ import { GraphEdge, GraphNode } from "../../../math/utils/graphs/graphRenderer.js";
4
+ type Identifiers = {
5
+ graphIds: GraphIdentifiers;
6
+ lengthAsked: number;
7
+ graphNodes: GraphNode[];
8
+ graphEdges: GraphEdge[];
9
+ };
10
+ type Options = {
11
+ graphType: string;
12
+ };
13
+ export declare const graphsChainOrPathOfLengthN: Exercise<Identifiers, Options>;
14
+ export {};
15
+ //# sourceMappingURL=graphsChainOrPathOfLengthN.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graphsChainOrPathOfLengthN.d.ts","sourceRoot":"","sources":["../../../../src/exercises/math/graphs/graphsChainOrPathOfLengthN.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAoBT,MAAM,6BAA6B,CAAC;AAKrC,OAAO,EAAoB,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAChF,OAAO,EACL,SAAS,EACT,SAAS,EAEV,MAAM,0CAA0C,CAAC;AAWlD,KAAK,WAAW,GAAG;IACjB,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC;IAGpB,UAAU,EAAE,SAAS,EAAE,CAAC;IACxB,UAAU,EAAE,SAAS,EAAE,CAAC;CACzB,CAAC;AA8SF,KAAK,OAAO,GAAG;IACb,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAsBF,eAAO,MAAM,0BAA0B,EAAE,QAAQ,CAAC,WAAW,EAAE,OAAO,CAerE,CAAC"}
@@ -0,0 +1,262 @@
1
+ import { addValidProp, shuffleProps, tryToAddWrongProp, propWhile, GeneratorOptionTarget, GeneratorOptionType, } from "../../../exercises/exercise.js";
2
+ import { getDistinctQuestions } from "../../../exercises/utils/getDistinctQuestions.js";
3
+ import { defaultArrayedOptsWhereNeeded } from "../../../exercises/utils/options/arrayedOptions.js";
4
+ import { GeogebraConstructor } from "../../../geogebra/geogebraConstructor.js";
5
+ import { Point } from "../../../math/geometry/point.js";
6
+ import { GraphConstructor } from "../../../math/graphs/graph.js";
7
+ import { GraphRenderer, } from "../../../math/utils/graphs/graphRenderer.js";
8
+ import { randint } from "../../../math/utils/random/randint.js";
9
+ import { coinFlip } from "../../../utils/alea/coinFlip.js";
10
+ import { random } from "../../../utils/alea/random.js";
11
+ import { handleVEAError } from "../../../utils/errors/handleVEAError.js";
12
+ const getStrSeparator = (isDirected) => isDirected ? "\\ \\rightarrow\\ " : "\\ -\\ ";
13
+ const getHydrated = (identifiers) => {
14
+ const { graphIds, lengthAsked } = identifiers;
15
+ const graph = GraphConstructor.fromIdentifiers(graphIds);
16
+ const arrTexPath = [...Array(3).keys()]
17
+ .flatMap(() => graph
18
+ .getSomePathsWithNbEdges(lengthAsked, 1)
19
+ .map((arrIndex) => arrIndex.map((i) => graph.vertexNames[i]))
20
+ .map((arrNameVertex) => arrNameVertex.join(getStrSeparator(graph.isDirected))))
21
+ .filter((texPath) => texPath !== "");
22
+ return {
23
+ graph,
24
+ arrTexPath,
25
+ };
26
+ };
27
+ const getInstruction = (identifiers) => {
28
+ const { graphIds, lengthAsked } = identifiers;
29
+ return `Un graphe ${graphIds.isDirected ? "orienté" : "non orienté"} est représenté ci-dessous.
30
+ Déterminer ${graphIds.isDirected ? "un chemin" : "une chaîne"} de longueur $${lengthAsked}$ ?`;
31
+ };
32
+ const getAnswer = (identifiers) => {
33
+ const { arrTexPath } = getHydrated(identifiers);
34
+ const [texPath] = arrTexPath;
35
+ return texPath;
36
+ };
37
+ const getHint = (identifiers) => {
38
+ const { graphIds: { isDirected }, lengthAsked, } = identifiers;
39
+ if (isDirected) {
40
+ return `Cherche une succession de $${lengthAsked}$ flèches, puis inscrit le chemin sous la forme : $P\\ \\rightarrow \\ Q\\ \\rightarrow \\ R\\ \\rightarrow \\ ...$`;
41
+ }
42
+ else {
43
+ return `Cherche une succession de $${lengthAsked}$ arêtes, puis inscrit la chaîne sous la forme : $P\\ - \\ Q\\ - \\ R \\ - \\ ...$`;
44
+ }
45
+ };
46
+ const getCorrection = (identifiers) => {
47
+ const { graphIds: { isDirected }, lengthAsked, } = identifiers;
48
+ const { arrTexPath } = getHydrated(identifiers);
49
+ if (isDirected) {
50
+ return `Voici quelque(s) chemin(s) de longueur $${lengthAsked}$ :
51
+
52
+ ${arrTexPath.map((texPath) => `- $${texPath}$`).join(`
53
+
54
+ `)}`;
55
+ }
56
+ else {
57
+ return `Voici quelque(s) chaîne(s) de longueur $${lengthAsked}$ :
58
+
59
+ ${arrTexPath.map((texPath) => `- $${texPath}$`).join(`
60
+
61
+ `)}`;
62
+ }
63
+ };
64
+ const getGGBOptions = (identifiers) => {
65
+ const { graphNodes, graphEdges } = identifiers;
66
+ const { graph } = getHydrated(identifiers);
67
+ const arrPoint = graphNodes.map(({ label, x, y }) => new Point(label, x, y));
68
+ const pointCommands = arrPoint.flatMap((point) => point.toGGBCommand({
69
+ isFixed: false,
70
+ isSelectionnable: true,
71
+ showLabel: true,
72
+ style: 0,
73
+ size: 8,
74
+ }));
75
+ const edgeCommands = graphEdges.map((e, i) => graph.isDirected
76
+ ? `v${i + 1} = Vector(${e.from}, ${e.to})`
77
+ : `s${i + 1} = Segment(${e.from}, ${e.to})`);
78
+ const arrGGBCommandForGraph = [...pointCommands, ...edgeCommands];
79
+ const ggb = new GeogebraConstructor({
80
+ commands: [...arrGGBCommandForGraph],
81
+ fontSize: 16,
82
+ hideAxes: true,
83
+ hideGrid: true,
84
+ });
85
+ return ggb.getOptions({
86
+ coords: ggb.getCoordsForPoints(arrPoint),
87
+ });
88
+ };
89
+ const getPropositions = (n, { answer, ...identifiers }) => {
90
+ const propositions = [];
91
+ addValidProp(propositions, answer);
92
+ const { lengthAsked: lengthAskedPure } = identifiers;
93
+ const { graph } = getHydrated(identifiers);
94
+ const lengthAsked = (() => {
95
+ const isTerror = coinFlip();
96
+ return isTerror ? lengthAskedPure - 1 : lengthAskedPure;
97
+ })();
98
+ //student: number of edges -> number of nodes
99
+ {
100
+ const identifiersWrong = {
101
+ ...identifiers,
102
+ lengthAsked: lengthAsked - 1,
103
+ };
104
+ tryToAddWrongProp(propositions, getAnswer(identifiersWrong));
105
+ }
106
+ if (graph.isDirected) {
107
+ const graphUndirected = graph.undirectedGraph();
108
+ //student: path -> chain
109
+ {
110
+ const arrTexPath = [...Array(2).keys()]
111
+ .flatMap(() => graphUndirected
112
+ .getSomePathsWithNbEdges(lengthAsked, 1)
113
+ .map((arrIndex) => arrIndex.map((i) => graph.vertexNames[i]))
114
+ .filter((arrName) => !graph.isValidPath(arrName)))
115
+ .map((arrNameVertex) => arrNameVertex.join(getStrSeparator(graph.isDirected)));
116
+ arrTexPath.forEach((texPath) => {
117
+ tryToAddWrongProp(propositions, texPath);
118
+ });
119
+ }
120
+ }
121
+ //filler
122
+ {
123
+ function createRandomPath(vertexNames, length) {
124
+ const arrIndexVertex = [...Array(length).keys()].reduce((acc, _) => {
125
+ const indexPrev = acc[acc.length - 1];
126
+ const index = randint(0, vertexNames.length, [indexPrev]);
127
+ return [...acc, index];
128
+ }, [randint(0, vertexNames.length)]);
129
+ return arrIndexVertex.map((i) => vertexNames[i]);
130
+ }
131
+ propWhile(propositions, n, () => {
132
+ const arrVertex = createRandomPath(graph.vertexNames, lengthAsked);
133
+ if (!graph.isValidPath(arrVertex)) {
134
+ const texPath = arrVertex.join(getStrSeparator(graph.isDirected));
135
+ tryToAddWrongProp(propositions, texPath);
136
+ }
137
+ if (coinFlip()) {
138
+ if (lengthAsked >= 3) {
139
+ const arrVertex = createRandomPath(graph.vertexNames, lengthAsked - 1);
140
+ if (!graph.isValidPath(arrVertex)) {
141
+ const texPath = arrVertex.join(getStrSeparator(graph.isDirected));
142
+ tryToAddWrongProp(propositions, texPath);
143
+ }
144
+ }
145
+ }
146
+ });
147
+ }
148
+ return shuffleProps(propositions, n);
149
+ };
150
+ const getKeys = (identifiers) => {
151
+ const { graphIds: { vertexNames, isDirected }, } = identifiers;
152
+ return [
153
+ ...vertexNames,
154
+ (() => {
155
+ const tex = getStrSeparator(isDirected);
156
+ return {
157
+ id: "custom",
158
+ label: tex,
159
+ labelType: "tex",
160
+ mathfieldInstructions: {
161
+ method: "write",
162
+ content: tex,
163
+ },
164
+ };
165
+ })(),
166
+ ];
167
+ };
168
+ const isAnswerValid = (ans, { answer, ...identifiers }) => {
169
+ try {
170
+ const { graphIds: { isDirected }, lengthAsked, } = identifiers;
171
+ const strSeparator = getStrSeparator(isDirected);
172
+ const arrNameVertexAns = ans.split(strSeparator);
173
+ console.log("arrNameVertexAns", arrNameVertexAns);
174
+ if (arrNameVertexAns.length !== lengthAsked + 1) {
175
+ return false;
176
+ }
177
+ const { graph } = getHydrated(identifiers);
178
+ return graph.isValidPath(arrNameVertexAns);
179
+ }
180
+ catch (err) {
181
+ return handleVEAError(err);
182
+ }
183
+ };
184
+ const createRandomIdentifiers = (isDirected) => {
185
+ const nbVertices = randint(5, 9);
186
+ const minDensity = (() => {
187
+ switch (nbVertices) {
188
+ case 5:
189
+ return isDirected ? 0.4 : 0.62;
190
+ case 6:
191
+ return isDirected ? 0.35 : 0.57;
192
+ case 7:
193
+ return isDirected ? 0.3 : 0.52;
194
+ case 8:
195
+ return isDirected ? 0.27 : 0.37;
196
+ case 9:
197
+ return isDirected ? 0.24 : 0.32;
198
+ default:
199
+ throw new Error("Unsupported nbVertices: " + nbVertices);
200
+ }
201
+ })();
202
+ const lengthAsked = randint(3, 4);
203
+ const graph = GraphConstructor.randomChain(nbVertices, "ABCDEFGHIJKLM".split(""), isDirected).densifyUpTo(minDensity);
204
+ const { nodes: graphNodes, edges: graphEdges } = GraphRenderer.renderToNodesAndEdges(graph);
205
+ const identifiers = {
206
+ graphIds: graph.toIdentifiers(),
207
+ lengthAsked,
208
+ graphNodes,
209
+ graphEdges,
210
+ };
211
+ return identifiers;
212
+ };
213
+ const getGraphsChainOrPathOfLengthNQuestion = (optsIn) => {
214
+ const arrayedOpts = defaultArrayedOptsWhereNeeded(optsIn, arrayedOptsDefault);
215
+ const opts = {
216
+ graphType: random(arrayedOpts.graphType),
217
+ };
218
+ const isDirected = opts.graphType === "orienté";
219
+ const identifiers = createRandomIdentifiers(isDirected);
220
+ return getQuestionFromIdentifiers(identifiers);
221
+ };
222
+ const getQuestionFromIdentifiers = (identifiers, opts) => {
223
+ const question = {
224
+ answer: getAnswer(identifiers, opts),
225
+ instruction: getInstruction(identifiers, opts),
226
+ keys: getKeys(identifiers, opts),
227
+ answerFormat: "tex",
228
+ identifiers,
229
+ hint: getHint(identifiers, opts),
230
+ correction: getCorrection(identifiers, opts),
231
+ ggbOptions: getGGBOptions(identifiers, opts),
232
+ };
233
+ return question;
234
+ };
235
+ const arrayedOptsDefault = {
236
+ graphType: ["non orienté"],
237
+ };
238
+ const options = [
239
+ {
240
+ id: "graphType",
241
+ label: "Types de graphes",
242
+ target: GeneratorOptionTarget.generation,
243
+ type: GeneratorOptionType.multiselect,
244
+ values: ["non orienté", "orienté"],
245
+ defaultValue: arrayedOptsDefault.graphType,
246
+ },
247
+ ];
248
+ export const graphsChainOrPathOfLengthN = {
249
+ id: "graphsChainOrPathOfLengthN",
250
+ label: "Déterminer une chaîne ou un chemin de longueur $n$",
251
+ isSingleStep: true,
252
+ generator: (nb, opts) => getDistinctQuestions(() => getGraphsChainOrPathOfLengthNQuestion(opts), nb),
253
+ options,
254
+ qcmTimer: 60,
255
+ freeTimer: 60,
256
+ isAnswerValid,
257
+ getPropositions,
258
+ subject: "Mathématiques",
259
+ getQuestionFromIdentifiers,
260
+ hasHintAndCorrection: true,
261
+ hasGeogebra: true,
262
+ };