math-exercises 3.0.216 → 3.0.217

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 (22) hide show
  1. package/lib/exercises/math/calculLitteral/equation/exp/expOfFEqualsExpOfGEquation.d.ts.map +1 -1
  2. package/lib/exercises/math/calculLitteral/equation/exp/expOfFEqualsExpOfGEquation.js +19 -32
  3. package/lib/exercises/math/derivation/derivative/trigo/sinCosDerivativeRewriteUsingCos2PlusSin2Equals1.js +2 -2
  4. package/lib/exercises/math/graphs/graphsCheckIsConnectedGraph.d.ts +11 -0
  5. package/lib/exercises/math/graphs/graphsCheckIsConnectedGraph.d.ts.map +1 -0
  6. package/lib/exercises/math/graphs/graphsCheckIsConnectedGraph.js +178 -0
  7. package/lib/exercises/math/graphs/graphsCheckIsConnectedUndirectedGraph.js +1 -1
  8. package/lib/exercises/math/graphs/index.d.ts +1 -1
  9. package/lib/exercises/math/graphs/index.d.ts.map +1 -1
  10. package/lib/exercises/math/graphs/index.js +1 -1
  11. package/lib/exercises/math/integration/fromExpr/integralFromExpr.d.ts.map +1 -1
  12. package/lib/exercises/math/integration/fromExpr/integralFromExpr.js +2 -0
  13. package/lib/exercises/math/spaceGeometry/parametricLine/lineLineRelativePositionsFromParametricLines.d.ts.map +1 -1
  14. package/lib/exercises/math/spaceGeometry/parametricLine/lineLineRelativePositionsFromParametricLines.js +56 -3
  15. package/lib/exercises/math/spaceGeometry/planes/findNormalVectorFromPlaneEquation.d.ts.map +1 -1
  16. package/lib/exercises/math/spaceGeometry/planes/findNormalVectorFromPlaneEquation.js +6 -0
  17. package/lib/exercises/vea/treeTableVEA.d.ts.map +1 -1
  18. package/lib/exercises/vea/treeTableVEA.js +2 -0
  19. package/lib/math/graphs/graph.d.ts +1 -1
  20. package/lib/math/graphs/graph.d.ts.map +1 -1
  21. package/lib/math/graphs/graph.js +86 -30
  22. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"expOfFEqualsExpOfGEquation.d.ts","sourceRoot":"","sources":["../../../../../../src/exercises/math/calculLitteral/equation/exp/expOfFEqualsExpOfGEquation.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAoBT,MAAM,6BAA6B,CAAC;AA4DrC;;GAEG;AACH,KAAK,WAAW,GAAG;IACjB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB,CAAC;AAyaF,KAAK,OAAO,GAAG;IACb,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC;AAkCF,eAAO,MAAM,0BAA0B,EAAE,QAAQ,CAAC,WAAW,EAAE,OAAO,CAoBrE,CAAC"}
1
+ {"version":3,"file":"expOfFEqualsExpOfGEquation.d.ts","sourceRoot":"","sources":["../../../../../../src/exercises/math/calculLitteral/equation/exp/expOfFEqualsExpOfGEquation.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAoBT,MAAM,6BAA6B,CAAC;AA4DrC;;GAEG;AACH,KAAK,WAAW,GAAG;IACjB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB,CAAC;AA2ZF,KAAK,OAAO,GAAG;IACb,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC;AAkCF,eAAO,MAAM,0BAA0B,EAAE,QAAQ,CAAC,WAAW,EAAE,OAAO,CAoBrE,CAAC"}
@@ -268,6 +268,8 @@ const getKeys = (_, optsIn) => {
268
268
  ];
269
269
  };
270
270
  const isAnswerValid = (ans, { answer, ...identifiers }, optsIn) => {
271
+ console.log("ans", ans);
272
+ console.log("answer", answer);
271
273
  const opts = optsIn ?? optsDefault;
272
274
  const answerInputTypes = getAnswerInputTypes(opts);
273
275
  const answerNode = getAnswerNode(identifiers);
@@ -276,27 +278,23 @@ const isAnswerValid = (ans, { answer, ...identifiers }, optsIn) => {
276
278
  .elements;
277
279
  function getParsedNodesForAnswerInputType(ans, answerInputType) {
278
280
  switch (answerInputType) {
279
- case "x=... ou x=...":
280
- {
281
- const formated = ans
282
- .replaceAll("text{ ou }", ";")
283
- .replaceAll("x", "")
284
- .replaceAll("=", "");
285
- const elements = formated.split(";").map((e) => parseAlgebraic(e));
286
- return elements;
281
+ case "x=... ou x=...": {
282
+ const formated = ans
283
+ .replaceAll("text{ ou }", ";")
284
+ .replaceAll("x", "")
285
+ .replaceAll("=", "");
286
+ const elements = formated.split(";").map((e) => parseAlgebraic(e));
287
+ return elements;
288
+ }
289
+ case "S={...;...}": {
290
+ const discreteSetNodeCandidate = discreteSetParser(ans);
291
+ if (discreteSetNodeCandidate) {
292
+ return discreteSetNodeCandidate.elements;
287
293
  }
288
- break;
289
- case "S={...;...}":
290
- {
291
- const discreteSetNodeCandidate = discreteSetParser(ans);
292
- if (discreteSetNodeCandidate) {
293
- return discreteSetNodeCandidate.elements;
294
- }
295
- else {
296
- return [];
297
- }
294
+ else {
295
+ return [];
298
296
  }
299
- break;
297
+ }
300
298
  default:
301
299
  throw new Error("Unsupported answerInputType: " + answerInputType);
302
300
  }
@@ -325,19 +323,8 @@ const isAnswerValid = (ans, { answer, ...identifiers }, optsIn) => {
325
323
  return answerInputTypes.some((answerInputType) => isAnswerValidForAnswerInputType(answerInputType));
326
324
  }
327
325
  else {
328
- const inequationSolutionNode = answerNode;
329
- const texInterval = inequationSolutionNode.intervalSolution.toTex();
330
- function isAnswerValidForAnswerInputType(answerInputType) {
331
- switch (answerInputType) {
332
- case "x=... ou x=...":
333
- return `x\\in${texInterval}`;
334
- case "S={...;...}":
335
- return `S=${texInterval}`;
336
- default:
337
- throw new Error("Unsupported answerInputType: " + answerInputType);
338
- }
339
- }
340
- return answerInputTypes.some((answerInputType) => isAnswerValidForAnswerInputType(answerInputType));
326
+ //answer is mathbbR
327
+ return ans === answer;
341
328
  }
342
329
  };
343
330
  const getExpOfFEqualsExpOfGEquationQuestion = (optsIn) => {
@@ -388,10 +388,10 @@ const getPropositions = (n, { answer: _answer, ...identifiers }) => {
388
388
  }
389
389
  return shuffleProps(propositions, n);
390
390
  };
391
- const isAnswerValid = (ans, { answer, ...identifiers }) => {
391
+ const isAnswerValid = (ans, { answer }) => {
392
392
  try {
393
393
  const nodeAns = parseAlgebraic(ans);
394
- const nodeAnswer = getAnswerNode(identifiers);
394
+ const nodeAnswer = parseAlgebraic(answer);
395
395
  return NodeComparator.isEqualViaRandomSubstitutions(nodeAns, nodeAnswer, 3);
396
396
  }
397
397
  catch (e) {
@@ -0,0 +1,11 @@
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
+ graphNodes: GraphNode[];
7
+ graphEdges: GraphEdge[];
8
+ };
9
+ export declare const graphsCheckIsConnectedGraph: Exercise<Identifiers>;
10
+ export {};
11
+ //# sourceMappingURL=graphsCheckIsConnectedGraph.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graphsCheckIsConnectedGraph.d.ts","sourceRoot":"","sources":["../../../../src/exercises/math/graphs/graphsCheckIsConnectedGraph.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAaT,MAAM,6BAA6B,CAAC;AAIrC,OAAO,EAGL,gBAAgB,EACjB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,SAAS,EACT,SAAS,EAEV,MAAM,0CAA0C,CAAC;AASlD,KAAK,WAAW,GAAG;IACjB,QAAQ,EAAE,gBAAgB,CAAC;IAG3B,UAAU,EAAE,SAAS,EAAE,CAAC;IACxB,UAAU,EAAE,SAAS,EAAE,CAAC;CACzB,CAAC;AA2OF,eAAO,MAAM,2BAA2B,EAAE,QAAQ,CAAC,WAAW,CAiB7D,CAAC"}
@@ -0,0 +1,178 @@
1
+ import { addValidProp, tryToAddWrongProp, } from "../../../exercises/exercise.js";
2
+ import { getDistinctQuestions } from "../../../exercises/utils/getDistinctQuestions.js";
3
+ import { GeogebraConstructor } from "../../../geogebra/geogebraConstructor.js";
4
+ import { Point } from "../../../math/geometry/point.js";
5
+ import { GraphConstructor, } from "../../../math/graphs/graph.js";
6
+ import { GraphRenderer, } from "../../../math/utils/graphs/graphRenderer.js";
7
+ import { randint } from "../../../math/utils/random/randint.js";
8
+ import { coinFlip } from "../../../utils/alea/coinFlip.js";
9
+ import { shuffle } from "../../../utils/alea/shuffle.js";
10
+ import { splitIntoRandomChunks } from "../../../utils/arrays/arrayChunks.js";
11
+ import { joinanded } from "../../../utils/strings/joinanded.js";
12
+ import * as Flatten from "@flatten-js/core";
13
+ const getHydrated = (identifiers) => {
14
+ const { graphIds } = identifiers;
15
+ const graph = GraphConstructor.fromIdentifiers(graphIds);
16
+ return {
17
+ graph,
18
+ };
19
+ };
20
+ const getInstruction = () => {
21
+ return `Un graphe non orienté est représenté ci-dessous.
22
+ Le graphe est-il connexe ?
23
+ *On peut déplacer les points sur la figure.*`;
24
+ };
25
+ const getAnswer = (identifiers) => {
26
+ const { graph } = getHydrated(identifiers);
27
+ return graph.isWeaklyConnected() ? "Oui" : "Non";
28
+ };
29
+ const getHint = () => {
30
+ return `Un graphe non orienté est connexe si et seulement si chaque couple de ses sommets peut être relié par une chaîne.`;
31
+ };
32
+ const getCorrection = (identifiers) => {
33
+ const { graph } = getHydrated(identifiers);
34
+ const arrWeaklyConnectedSubgraph = graph
35
+ .getWeaklyConnectedSubgraphCoveringChainsAsArrIndex()
36
+ .map((chain) => chain.map((index) => graph.vertexNames[index]));
37
+ if (graph.isWeaklyConnected()) {
38
+ const [chain0] = arrWeaklyConnectedSubgraph;
39
+ return `On peut former une chaîne qui relie tous les sommets : ${chain0
40
+ .map((str) => `$${str}$`)
41
+ .join("-")}.
42
+ Le graphe est donc connexe.`;
43
+ }
44
+ else {
45
+ return `On ne peut pas former une chaîne qui relie tous les sommets.
46
+ Le graphe contient des sous-graphes disjoints contenant les chaînes ${joinanded(arrWeaklyConnectedSubgraph.map((chain) => chain.map((str) => `$${str}$`).join("-")), ", ", " et ")}.
47
+ Le graphe n'est donc pas connexe.`;
48
+ }
49
+ };
50
+ const getGGBOptions = (identifiers) => {
51
+ const { graphNodes, graphEdges } = identifiers;
52
+ const { graph } = getHydrated(identifiers);
53
+ const arrPoint = graphNodes.map(({ label, x, y }) => new Point(label, x, y));
54
+ const pointCommands = arrPoint.flatMap((point) => point.toGGBCommand({
55
+ isFixed: false,
56
+ isSelectionnable: true,
57
+ showLabel: true,
58
+ style: 0,
59
+ size: 8,
60
+ }));
61
+ const edgeCommands = graphEdges.map((e, i) => graph.isDirected
62
+ ? `v${i + 1} = Vector(${e.from}, ${e.to})`
63
+ : `s${i + 1} = Segment(${e.from}, ${e.to})`);
64
+ const arrGGBCommandForGraph = [...pointCommands, ...edgeCommands];
65
+ const ggb = new GeogebraConstructor({
66
+ commands: [...arrGGBCommandForGraph],
67
+ fontSize: 16,
68
+ hideAxes: true,
69
+ hideGrid: true,
70
+ });
71
+ return ggb.getOptions({
72
+ coords: ggb.getCoordsForPoints(arrPoint),
73
+ });
74
+ };
75
+ const getPropositions = (_, { answer }) => {
76
+ const propositions = [];
77
+ ["Oui", "Non"].forEach((str) => {
78
+ if (str === answer) {
79
+ addValidProp(propositions, str, "raw");
80
+ }
81
+ else {
82
+ tryToAddWrongProp(propositions, str, "raw");
83
+ }
84
+ });
85
+ return propositions;
86
+ };
87
+ const createRandomIdentifiers = () => {
88
+ const nbVertices = randint(7, 9);
89
+ const isSimple = true;
90
+ const minDensity = 0.4;
91
+ const isConnected = coinFlip();
92
+ const vertexNames = "ABCDEFGHIJKLM".split("").slice(0, nbVertices);
93
+ const { graph, graphNodes, graphEdges } = (() => {
94
+ let isFound = false;
95
+ let graph;
96
+ let graphNodes;
97
+ let arrGraphEdges;
98
+ while (!isFound) {
99
+ const graphForPoints = GraphConstructor.randomConnected(nbVertices, isSimple, false, minDensity, vertexNames);
100
+ const { nodes: graphNodes0, edges: graphEdges0 } = GraphRenderer.renderToNodesAndEdges(graphForPoints, "circo");
101
+ graphNodes = graphNodes0;
102
+ let arrGraphNodes; //to check overlapping
103
+ [graph, arrGraphEdges, arrGraphNodes] = (() => {
104
+ if (isConnected) {
105
+ return [graphForPoints, [graphEdges0], [graphNodes0]];
106
+ }
107
+ else {
108
+ const arrVertexNamesChunk = splitIntoRandomChunks(shuffle(vertexNames), 3);
109
+ const arrSubGraph = arrVertexNamesChunk.map((vertexNamesChunk) => GraphConstructor.randomConnected(vertexNamesChunk.length, isSimple, false, minDensity, vertexNamesChunk));
110
+ const graph = GraphConstructor.graphByMergingSimpleGraphs(arrSubGraph);
111
+ const arrGraphEdges = arrSubGraph.map((graph) => graph.arrConnection().map(([from, to, _]) => {
112
+ return { from, to };
113
+ }));
114
+ const dictGraphNodes = Object.fromEntries(graphNodes.map((graphNode) => [graphNode.label, graphNode]));
115
+ const arrGraphNodes = arrSubGraph.map((graph) => graph.vertexNames.map((nameVertex) => dictGraphNodes[nameVertex]));
116
+ return [graph, arrGraphEdges, arrGraphNodes];
117
+ }
118
+ })();
119
+ const arrGraphNodes1GraphNodes2 = [...Array(arrGraphNodes.length).keys()]
120
+ .flatMap((i) => [...Array(i + 1).keys()].map((j) => [i, j]))
121
+ .map(([i, j]) => [arrGraphNodes[i], arrGraphNodes[j]]);
122
+ try {
123
+ isFound = arrGraphNodes1GraphNodes2.every(([graphNodes1, graphNodes2]) => {
124
+ const [polygon1, polygon2] = [graphNodes1, graphNodes2].map((graphNodes) => {
125
+ const arrPoint = graphNodes.map(({ x, y }) => new Flatten.Point(x, y));
126
+ const polygon = new Flatten.Polygon(arrPoint);
127
+ return polygon;
128
+ });
129
+ return Flatten.Relations.intersect(polygon1, polygon2);
130
+ });
131
+ }
132
+ catch {
133
+ isFound = false;
134
+ }
135
+ }
136
+ const graphEdges = arrGraphEdges.reduce((acc, graphEdges) => {
137
+ acc = [...acc, ...graphEdges];
138
+ return acc;
139
+ }, []);
140
+ return { graph: graph, graphNodes: graphNodes, graphEdges };
141
+ })();
142
+ const identifiers = {
143
+ graphIds: graph.toIdentifiers(),
144
+ graphNodes,
145
+ graphEdges,
146
+ };
147
+ return identifiers;
148
+ };
149
+ const getGraphsCheckIsConnectedGraphQuestion = () => {
150
+ const identifiers = createRandomIdentifiers();
151
+ return getQuestionFromIdentifiers(identifiers);
152
+ };
153
+ const getQuestionFromIdentifiers = (identifiers, opts) => {
154
+ const question = {
155
+ answer: getAnswer(identifiers, opts),
156
+ instruction: getInstruction(identifiers, opts),
157
+ answerFormat: "raw",
158
+ identifiers,
159
+ hint: getHint(identifiers, opts),
160
+ correction: getCorrection(identifiers, opts),
161
+ ggbOptions: getGGBOptions(identifiers, opts),
162
+ };
163
+ return question;
164
+ };
165
+ export const graphsCheckIsConnectedGraph = {
166
+ id: "graphsCheckIsConnectedGraph",
167
+ label: "Déterminer si un graphe est connexe",
168
+ isSingleStep: true,
169
+ generator: (nb, opts) => getDistinctQuestions(() => getGraphsCheckIsConnectedGraphQuestion(opts), nb),
170
+ qcmTimer: 60,
171
+ freeTimer: 60,
172
+ getPropositions,
173
+ subject: "Mathématiques",
174
+ getQuestionFromIdentifiers,
175
+ hasHintAndCorrection: true,
176
+ hasGeogebra: true,
177
+ answerType: "QCU",
178
+ };
@@ -32,7 +32,7 @@ const getHint = () => {
32
32
  const getCorrection = (identifiers) => {
33
33
  const { graph } = getHydrated(identifiers);
34
34
  const arrWeaklyConnectedSubgraph = graph
35
- .getWeaklyConnectedSubgraphChainsAsArrIndex()
35
+ .getWeaklyConnectedSubgraphCoveringChainsAsArrIndex()
36
36
  .map((chain) => chain.map((index) => graph.vertexNames[index]));
37
37
  if (graph.isWeaklyConnected()) {
38
38
  const [chain0] = arrWeaklyConnectedSubgraph;
@@ -2,7 +2,7 @@ export * from "./graphsOrderOfGraph.js";
2
2
  export * from "./graphsDegreeOfVertex.js";
3
3
  export * from "./graphsCheckIsVerticesAdjacent.js";
4
4
  export * from "./graphsCheckIsSameGraph.js";
5
- export * from "./graphsCheckIsConnectedUndirectedGraph.js";
5
+ export * from "./graphsCheckIsConnectedGraph.js";
6
6
  export * from "./graphsChainOrPathOfLengthN.js";
7
7
  export * from "./edgesNumberFromSummitsDegrees.js";
8
8
  export * from "./adjacentMatrixPath.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/exercises/math/graphs/index.ts"],"names":[],"mappings":"AAAA,cAAc,yBAAyB,CAAC;AACxC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,oCAAoC,CAAC;AACnD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,4CAA4C,CAAC;AAC3D,cAAc,iCAAiC,CAAC;AAChD,cAAc,oCAAoC,CAAC;AACnD,cAAc,yBAAyB,CAAC;AACxC,cAAc,sCAAsC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/exercises/math/graphs/index.ts"],"names":[],"mappings":"AAAA,cAAc,yBAAyB,CAAC;AACxC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,oCAAoC,CAAC;AACnD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,kCAAkC,CAAC;AACjD,cAAc,iCAAiC,CAAC;AAChD,cAAc,oCAAoC,CAAC;AACnD,cAAc,yBAAyB,CAAC;AACxC,cAAc,sCAAsC,CAAC"}
@@ -2,7 +2,7 @@ export * from "./graphsOrderOfGraph.js";
2
2
  export * from "./graphsDegreeOfVertex.js";
3
3
  export * from "./graphsCheckIsVerticesAdjacent.js";
4
4
  export * from "./graphsCheckIsSameGraph.js";
5
- export * from "./graphsCheckIsConnectedUndirectedGraph.js";
5
+ export * from "./graphsCheckIsConnectedGraph.js";
6
6
  export * from "./graphsChainOrPathOfLengthN.js";
7
7
  export * from "./edgesNumberFromSummitsDegrees.js";
8
8
  export * from "./adjacentMatrixPath.js";
@@ -1 +1 @@
1
- {"version":3,"file":"integralFromExpr.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/integration/fromExpr/integralFromExpr.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAiBT,MAAM,6BAA6B,CAAC;AAcrC,OAAO,EAEL,eAAe,EAChB,MAAM,qCAAqC,CAAC;AAe7C,KAAK,WAAW,GAAG;IACjB,QAAQ,EAAE,eAAe,CAAC;IAC1B,aAAa,EAAE,CAAC,eAAe,EAAE,eAAe,CAAC,CAAC;IAClD,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAqWF,KAAK,OAAO,GAAG;IACb,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB,CAAC;AA2CF,eAAO,MAAM,gBAAgB,EAAE,QAAQ,CAAC,WAAW,EAAE,OAAO,CAe3D,CAAC"}
1
+ {"version":3,"file":"integralFromExpr.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/integration/fromExpr/integralFromExpr.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAiBT,MAAM,6BAA6B,CAAC;AAcrC,OAAO,EAEL,eAAe,EAChB,MAAM,qCAAqC,CAAC;AAe7C,KAAK,WAAW,GAAG;IACjB,QAAQ,EAAE,eAAe,CAAC;IAC1B,aAAa,EAAE,CAAC,eAAe,EAAE,eAAe,CAAC,CAAC;IAClD,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAuWF,KAAK,OAAO,GAAG;IACb,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB,CAAC;AA2CF,eAAO,MAAM,gBAAgB,EAAE,QAAQ,CAAC,WAAW,EAAE,OAAO,CAe3D,CAAC"}
@@ -252,7 +252,9 @@ const isIdentifiersQCPassed = (identifiers) => {
252
252
  const isExploding = (identifiers) => {
253
253
  let isExploding = false;
254
254
  try {
255
+ //anything that contain exploding simplify()
255
256
  getAnswer(identifiers);
257
+ getCorrection(identifiers);
256
258
  }
257
259
  catch (_) {
258
260
  isExploding = true;
@@ -1 +1 @@
1
- {"version":3,"file":"lineLineRelativePositionsFromParametricLines.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/spaceGeometry/parametricLine/lineLineRelativePositionsFromParametricLines.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAYT,MAAM,6BAA6B,CAAC;AAGrC,OAAO,EAGL,qBAAqB,EACtB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAGL,sBAAsB,EACvB,MAAM,oCAAoC,CAAC;AAgH5C,KAAK,YAAY,GAAG;IAClB,aAAa,EAAE,qBAAqB,CAAC;IACrC,cAAc,EAAE,sBAAsB,CAAC;CACxC,CAAC;AAEF,KAAK,WAAW,GAAG;IACjB,eAAe,EAAE,qBAAqB,EAAE,CAAC;IACzC,YAAY,EAAE,YAAY,EAAE,CAAC;CAC9B,CAAC;AAyTF,eAAO,MAAM,4CAA4C,EAAE,QAAQ,CAAC,WAAW,CAoB5E,CAAC"}
1
+ {"version":3,"file":"lineLineRelativePositionsFromParametricLines.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/spaceGeometry/parametricLine/lineLineRelativePositionsFromParametricLines.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAYT,MAAM,6BAA6B,CAAC;AAGrC,OAAO,EAGL,qBAAqB,EACtB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAGL,sBAAsB,EACvB,MAAM,oCAAoC,CAAC;AAgH5C,KAAK,YAAY,GAAG;IAClB,aAAa,EAAE,qBAAqB,CAAC;IACrC,cAAc,EAAE,sBAAsB,CAAC;CACxC,CAAC;AAEF,KAAK,WAAW,GAAG;IACjB,eAAe,EAAE,qBAAqB,EAAE,CAAC;IACzC,YAAY,EAAE,YAAY,EAAE,CAAC;CAC9B,CAAC;AA6XF,eAAO,MAAM,4CAA4C,EAAE,QAAQ,CAAC,WAAW,CAoB5E,CAAC"}
@@ -1,8 +1,8 @@
1
1
  import { addValidProp, tryToAddWrongProp, } from "../../../../exercises/exercise.js";
2
2
  import { getDistinctQuestions } from "../../../../exercises/utils/getDistinctQuestions.js";
3
3
  import { ParametricLine } from "../../../../math/geometry/parametricLine.js";
4
- import { SpacePointConstructor, } from "../../../../math/geometry/spacePoint.js";
5
- import { SpaceVectorConstructor, } from "../../../../math/geometry/spaceVector.js";
4
+ import { SpacePoint, SpacePointConstructor, } from "../../../../math/geometry/spacePoint.js";
5
+ import { SpaceVector, SpaceVectorConstructor, } from "../../../../math/geometry/spaceVector.js";
6
6
  import { nodeBySubstitutingVar } from "../../../../math/utils/functions/functionComposition.js";
7
7
  import { randint } from "../../../../math/utils/random/randint.js";
8
8
  import { frac } from "../../../../tree/nodes/operators/fractionNode.js";
@@ -293,8 +293,61 @@ const createRandomIdentifiers = () => {
293
293
  };
294
294
  return identifiers;
295
295
  };
296
+ const isIdentifiersQCPassed = (identifiers) => {
297
+ const isExploding = (identifiers) => {
298
+ let isExploding = false;
299
+ try {
300
+ //ensure only one valid proposition
301
+ const n = 4;
302
+ const answer = getAnswer(identifiers);
303
+ const propositions = getPropositions(n, { answer, ...identifiers });
304
+ const nbRightAnswers = propositions.filter((proposition) => proposition.isRightAnswer).length;
305
+ if (nbRightAnswers !== 1) {
306
+ throw new Error("nbRightAnswers !== 1");
307
+ }
308
+ }
309
+ catch (_) {
310
+ isExploding = true;
311
+ }
312
+ return isExploding;
313
+ };
314
+ return !isExploding(identifiers);
315
+ };
316
+ const createQCPassedIdentifiers = () => {
317
+ let identifiers;
318
+ let counter = -1;
319
+ let isValid = false;
320
+ while (!isValid && counter < 100) {
321
+ counter++;
322
+ const identifiersCandidate = createRandomIdentifiers();
323
+ isValid = isIdentifiersQCPassed(identifiersCandidate);
324
+ if (isValid) {
325
+ identifiers = identifiersCandidate;
326
+ }
327
+ }
328
+ if (!isValid) {
329
+ const vec1 = new SpaceVector("v1", (1).toTree(), (0).toTree(), (0).toTree());
330
+ const vec2 = new SpaceVector("v2", (2).toTree(), (0).toTree(), (0).toTree());
331
+ const A = new SpacePoint("A", (0).toTree(), (1).toTree(), (0).toTree());
332
+ const B = new SpacePoint("B", (0).toTree(), (0).toTree(), (2).toTree());
333
+ const identifiersDefault = {
334
+ spacePointIdsAB: [A, B].map((spacePoint) => spacePoint.toIdentifiers()),
335
+ spaceLineIds: [
336
+ [A, vec1],
337
+ [B, vec2],
338
+ ].map(([spacePoint, spaceVector]) => {
339
+ return {
340
+ spacePointIds: spacePoint.toIdentifiers(),
341
+ spaceVectorIds: spaceVector.toIdentifiers(),
342
+ };
343
+ }),
344
+ };
345
+ identifiers = identifiersDefault;
346
+ }
347
+ return identifiers;
348
+ };
296
349
  const getLineLineRelativePositionsFromParametricLinesQuestion = () => {
297
- const identifiers = createRandomIdentifiers();
350
+ const identifiers = createQCPassedIdentifiers();
298
351
  return getQuestionFromIdentifiers(identifiers);
299
352
  };
300
353
  const getQuestionFromIdentifiers = (identifiers, _opts) => {
@@ -1 +1 @@
1
- {"version":3,"file":"findNormalVectorFromPlaneEquation.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/spaceGeometry/planes/findNormalVectorFromPlaneEquation.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAgBT,MAAM,6BAA6B,CAAC;AASrC,OAAO,EAEL,eAAe,EAChB,MAAM,qCAAqC,CAAC;AAsF7C,KAAK,WAAW,GAAG;IACjB,oBAAoB,EAAE,eAAe,CAAC;CACvC,CAAC;AA+QF,eAAO,MAAM,iCAAiC,EAAE,QAAQ,CAAC,WAAW,CAmBnE,CAAC"}
1
+ {"version":3,"file":"findNormalVectorFromPlaneEquation.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/spaceGeometry/planes/findNormalVectorFromPlaneEquation.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAgBT,MAAM,6BAA6B,CAAC;AASrC,OAAO,EAEL,eAAe,EAChB,MAAM,qCAAqC,CAAC;AAsF7C,KAAK,WAAW,GAAG;IACjB,oBAAoB,EAAE,eAAe,CAAC;CACvC,CAAC;AAuRF,eAAO,MAAM,iCAAiC,EAAE,QAAQ,CAAC,WAAW,CAmBnE,CAAC"}
@@ -140,7 +140,9 @@ const getPropositions = (n, { answer, ...identifiers }) => {
140
140
  }
141
141
  }
142
142
  }
143
+ let counter = -1;
143
144
  propWhile(propositions, n, () => {
145
+ counter++;
144
146
  const nodeFactorW = randint(-4, 5, [0, 1]).toTree();
145
147
  const arr = [nodeA, nodeB, nodeC, nodeD].map((node) => multiply(nodeFactorW, node).simplify({ towardsDistribute: true }));
146
148
  {
@@ -160,6 +162,10 @@ const getPropositions = (n, { answer, ...identifiers }) => {
160
162
  }
161
163
  }
162
164
  }
165
+ if (counter > 50) {
166
+ const identifiersWrong = createRandomIdentifiers();
167
+ tryToAddWrongProp(propositions, getAnswer(identifiersWrong));
168
+ }
163
169
  });
164
170
  return shuffleProps(propositions, n);
165
171
  };
@@ -1 +1 @@
1
- {"version":3,"file":"treeTableVEA.d.ts","sourceRoot":"","sources":["../../../src/exercises/vea/treeTableVEA.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,YAAY,GACvB,KAAK,MAAM,EAAE,EAAE,EAAE,EAAE,EACnB,aAAa,MAAM,EAAE,EAAE,EAAE,EAAE,YAgB5B,CAAC"}
1
+ {"version":3,"file":"treeTableVEA.d.ts","sourceRoot":"","sources":["../../../src/exercises/vea/treeTableVEA.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,YAAY,GACvB,KAAK,MAAM,EAAE,EAAE,EAAE,EAAE,EACnB,aAAa,MAAM,EAAE,EAAE,EAAE,EAAE,YAiB5B,CAAC"}
@@ -1,3 +1,4 @@
1
+ import { percentVEA } from "./percentVEA.js";
1
2
  import { rationalVEA } from "./rationalVEA.js";
2
3
  // type Options = {
3
4
  // }
@@ -6,5 +7,6 @@ export const treeTableVEA = (ans, answerTable) => {
6
7
  //les branches peuvent commuter au sein d'un block
7
8
  //les blocks peuvent commuter au sein d'un step
8
9
  return ans.every((step, i) => step.every((block, j) => block.every((branch, k) => branch.every((value, l) => value === answerTable[i][j][k][l] ||
10
+ percentVEA(value, answerTable[i][j][k][l]) ||
9
11
  rationalVEA(value, answerTable[i][j][k][l])))));
10
12
  };
@@ -26,7 +26,7 @@ export declare class Graph {
26
26
  densifyUpTo(minDensity: number): Graph;
27
27
  undirectedGraph(): Graph;
28
28
  isWeaklyConnected(): boolean;
29
- getWeaklyConnectedSubgraphChainsAsArrIndex(): number[][];
29
+ getWeaklyConnectedSubgraphCoveringChainsAsArrIndex(): number[][];
30
30
  getSomePathsWithNbEdges(nbEdges: number, nbToFindIfPossible: number): number[][];
31
31
  /**
32
32
  *
@@ -1 +1 @@
1
- {"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../../../src/math/graphs/graph.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,MAAM,EAEN,iBAAiB,EAClB,MAAM,uBAAuB,CAAC;AAE/B,8BAAsB,gBAAgB;IACpC,MAAM,CAAC,eAAe,CACpB,UAAU,EAAE,MAAM,EAClB,QAAQ,GAAE,OAAc,EAAE,yBAAyB;IACnD,UAAU,GAAE,OAAe,EAC3B,UAAU,GAAE,MAAa,EAEzB,cAAc,GAAE,MAAM,EAA8B;IA6EtD,MAAM,CAAC,MAAM,CACX,UAAU,EAAE,MAAM,EAClB,QAAQ,GAAE,OAAc,EAAE,yBAAyB;IACnD,UAAU,GAAE,OAAe,EAC3B,UAAU,GAAE,MAAa,EACzB,cAAc,GAAE,MAAM,EAA8B,EACpD,WAAW,GAAE,OAAc;IAkC7B,MAAM,CAAC,WAAW,CAChB,UAAU,EAAE,MAAM,EAClB,cAAc,EAAE,MAAM,EAAE,YAA4B,EACpD,UAAU,EAAE,OAAO;IAuErB,MAAM,CAAC,0BAA0B,CAAC,QAAQ,EAAE,KAAK,EAAE;IAgCnD,MAAM,CAAC,uBAAuB,CAAC,KAAK,EAAE,KAAK,GAAG,KAAK;IA0BnD,MAAM,CAAC,eAAe,CAAC,WAAW,EAAE,gBAAgB;CAKrD;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,MAAM,EAAE,iBAAiB,CAAC;IAC1B,UAAU,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,qBAAa,KAAK;IAChB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,OAAO,CAAC;gBACR,WAAW,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,OAAO;IAMpE,aAAa;IASb,eAAe,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAmB1D,aAAa,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;IAc5C,OAAO,IAAI,MAAM;IAIjB,WAAW,CAAC,UAAU,EAAE,MAAM;IAc9B,eAAe,IAAI,KAAK;IASxB,iBAAiB,IAAI,OAAO;IAoC5B,0CAA0C,IAAI,MAAM,EAAE,EAAE;IA8CxD,uBAAuB,CACrB,OAAO,EAAE,MAAM,EACf,kBAAkB,EAAE,MAAM,GACzB,MAAM,EAAE,EAAE;IAmCb;;;;OAIG;IACH,oBAAoB,CAAC,gBAAgB,EAAE,MAAM,GAAG,MAAM,EAAE;IAqBxD,wBAAwB,CAAC,gBAAgB,EAAE,MAAM;IAUjD,+BAA+B,CAC7B,gBAAgB,EAAE,MAAM,EACxB,kBAAkB,EAAE,OAAO;IAmB7B,WAAW,CAAC,aAAa,EAAE,MAAM,EAAE,GAAG,OAAO;IAQ7C,eAAe;IAWf,MAAM,CAAC,MAAM,EAAE,KAAK;CAQrB"}
1
+ {"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../../../src/math/graphs/graph.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,MAAM,EAEN,iBAAiB,EAClB,MAAM,uBAAuB,CAAC;AAE/B,8BAAsB,gBAAgB;IACpC,MAAM,CAAC,eAAe,CACpB,UAAU,EAAE,MAAM,EAClB,QAAQ,GAAE,OAAc,EAAE,yBAAyB;IACnD,UAAU,GAAE,OAAe,EAC3B,UAAU,GAAE,MAAa,EAEzB,cAAc,GAAE,MAAM,EAA8B;IA6EtD,MAAM,CAAC,MAAM,CACX,UAAU,EAAE,MAAM,EAClB,QAAQ,GAAE,OAAc,EAAE,yBAAyB;IACnD,UAAU,GAAE,OAAe,EAC3B,UAAU,GAAE,MAAa,EACzB,cAAc,GAAE,MAAM,EAA8B,EACpD,WAAW,GAAE,OAAc;IAkC7B,MAAM,CAAC,WAAW,CAChB,UAAU,EAAE,MAAM,EAClB,cAAc,EAAE,MAAM,EAAE,YAA4B,EACpD,UAAU,EAAE,OAAO;IAuErB,MAAM,CAAC,0BAA0B,CAAC,QAAQ,EAAE,KAAK,EAAE;IAgCnD,MAAM,CAAC,uBAAuB,CAAC,KAAK,EAAE,KAAK,GAAG,KAAK;IA0BnD,MAAM,CAAC,eAAe,CAAC,WAAW,EAAE,gBAAgB;CAKrD;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,MAAM,EAAE,iBAAiB,CAAC;IAC1B,UAAU,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,qBAAa,KAAK;IAChB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,OAAO,CAAC;gBACR,WAAW,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,OAAO;IAMpE,aAAa;IASb,eAAe,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAmB1D,aAAa,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;IAc5C,OAAO,IAAI,MAAM;IAIjB,WAAW,CAAC,UAAU,EAAE,MAAM;IAc9B,eAAe,IAAI,KAAK;IASxB,iBAAiB,IAAI,OAAO;IAoC5B,kDAAkD,IAAI,MAAM,EAAE,EAAE;IAuGhE,uBAAuB,CACrB,OAAO,EAAE,MAAM,EACf,kBAAkB,EAAE,MAAM,GACzB,MAAM,EAAE,EAAE;IAmCb;;;;OAIG;IACH,oBAAoB,CAAC,gBAAgB,EAAE,MAAM,GAAG,MAAM,EAAE;IAqBxD,wBAAwB,CAAC,gBAAgB,EAAE,MAAM;IAUjD,+BAA+B,CAC7B,gBAAgB,EAAE,MAAM,EACxB,kBAAkB,EAAE,OAAO;IAmB7B,WAAW,CAAC,aAAa,EAAE,MAAM,EAAE,GAAG,OAAO;IAQ7C,eAAe;IAWf,MAAM,CAAC,MAAM,EAAE,KAAK;CAQrB"}
@@ -265,44 +265,100 @@ export class Graph {
265
265
  return visited.every((v) => v);
266
266
  //AI CODE (Edge) }
267
267
  }
268
- getWeaklyConnectedSubgraphChainsAsArrIndex() {
268
+ getWeaklyConnectedSubgraphCoveringChainsAsArrIndex() {
269
269
  const adjMatrix = (this.isDirected ? this.undirectedGraph() : this)
270
270
  .adjacencyMatrix()
271
271
  .elements.map((row) => row.map((elt) => elt.evaluate()));
272
- //AI CODE (Edge) {
273
- // Validate input
274
- if (!Array.isArray(adjMatrix) || adjMatrix.length === 0) {
275
- throw new Error("Adjacency matrix must be a non-empty 2D array.");
276
- }
277
272
  const n = adjMatrix.length;
278
- if (!adjMatrix.every((row) => Array.isArray(row) && row.length === n)) {
279
- throw new Error("Adjacency matrix must be square.");
280
- }
281
- const visited = new Array(n).fill(false);
282
- const subgraphs = [];
283
- // DFS to collect connected nodes
284
- function dfs(node, component) {
285
- visited[node] = true;
286
- component.push(node);
287
- for (let neighbor = 0; neighbor < n; neighbor++) {
288
- if (adjMatrix[node][neighbor] !== 0 && !visited[neighbor]) {
289
- dfs(neighbor, component);
273
+ const linked = (i, j) => i !== j &&
274
+ ((adjMatrix[i]?.[j] ?? 0) !== 0 || (adjMatrix[j]?.[i] ?? 0) !== 0);
275
+ // Voisinage non orienté
276
+ const neighbors = Array.from({ length: n }, (_, i) => {
277
+ const list = [];
278
+ for (let j = 0; j < n; j++)
279
+ if (linked(i, j))
280
+ list.push(j);
281
+ return list;
282
+ });
283
+ // 1. Composantes connexes
284
+ const seen = new Array(n).fill(false);
285
+ const components = [];
286
+ for (let start = 0; start < n; start++) {
287
+ if (seen[start])
288
+ continue;
289
+ const component = [];
290
+ const stack = [start];
291
+ seen[start] = true;
292
+ while (stack.length > 0) {
293
+ const node = stack.pop();
294
+ component.push(node);
295
+ for (const nb of neighbors[node]) {
296
+ if (!seen[nb]) {
297
+ seen[nb] = true;
298
+ stack.push(nb);
299
+ }
290
300
  }
291
301
  }
302
+ components.push(component.sort((a, b) => a - b));
292
303
  }
293
- // Find connected components
294
- for (let i = 0; i < n; i++) {
295
- if (!visited[i]) {
296
- const component = [];
297
- dfs(i, component);
298
- if (component.length > 1) {
299
- // Only keep subgraphs with ≥ 2 nodes
300
- subgraphs.push(component);
304
+ // 2. Chaîne couvrant une composante
305
+ const coveringChain = (component) => {
306
+ if (component.length === 1)
307
+ return [...component];
308
+ // Arbre couvrant en profondeur (donne des branches longues)
309
+ const tree = new Map(component.map((v) => [v, []]));
310
+ const inTree = new Set([component[0]]);
311
+ const grow = (u) => {
312
+ for (const v of neighbors[u]) {
313
+ if (!inTree.has(v)) {
314
+ inTree.add(v);
315
+ tree.get(u).push(v);
316
+ tree.get(v).push(u);
317
+ grow(v);
318
+ }
301
319
  }
302
- }
303
- }
304
- return subgraphs;
305
- //AI CODE (Edge) }
320
+ };
321
+ grow(component[0]);
322
+ // Sommet le plus éloigné (BFS dans l'arbre) + parents pour remonter la branche
323
+ const farthest = (src) => {
324
+ const parent = new Map([[src, -1]]);
325
+ const queue = [src];
326
+ for (let i = 0; i < queue.length; i++) {
327
+ for (const v of tree.get(queue[i])) {
328
+ if (!parent.has(v)) {
329
+ parent.set(v, queue[i]);
330
+ queue.push(v);
331
+ }
332
+ }
333
+ }
334
+ return { last: queue[queue.length - 1], parent };
335
+ };
336
+ // Diamètre de l'arbre : de a à b
337
+ const a = farthest(component[0]).last;
338
+ const { last: b, parent } = farthest(a);
339
+ const onDiameter = new Set();
340
+ for (let v = b; v !== -1; v = parent.get(v))
341
+ onDiameter.add(v);
342
+ // Parcours depuis a : les sous-arbres annexes d'abord (avec retour),
343
+ // la branche du diamètre en dernier (sans retour)
344
+ const chain = [];
345
+ const visit = (u, from) => {
346
+ chain.push(u);
347
+ const children = tree
348
+ .get(u)
349
+ .filter((v) => v !== from)
350
+ .sort((x, y) => Number(onDiameter.has(x)) - Number(onDiameter.has(y)));
351
+ for (const child of children) {
352
+ visit(child, u);
353
+ if (!onDiameter.has(child))
354
+ chain.push(u); // retour arrière
355
+ }
356
+ };
357
+ visit(a, -1);
358
+ // Normalisation : commencer par la plus petite extrémité
359
+ return chain[0] > chain[chain.length - 1] ? chain.reverse() : chain;
360
+ };
361
+ return components.map(coveringChain);
306
362
  }
307
363
  getSomePathsWithNbEdges(nbEdges, nbToFindIfPossible) {
308
364
  const n = nbEdges;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "math-exercises",
3
3
  "type": "module",
4
- "version": "3.0.216",
4
+ "version": "3.0.217",
5
5
  "description": "Math exercises generator for middle school and high school",
6
6
  "main": "lib/index.js",
7
7
  "files": [