math-exercises 3.0.149 → 3.0.150

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 (48) hide show
  1. package/lib/exercises/math/scratch/index.d.ts +13 -0
  2. package/lib/exercises/math/scratch/index.d.ts.map +1 -1
  3. package/lib/exercises/math/scratch/index.js +14 -0
  4. package/lib/exercises/math/scratch/scratchCond1.d.ts +25 -0
  5. package/lib/exercises/math/scratch/scratchCond1.d.ts.map +1 -0
  6. package/lib/exercises/math/scratch/scratchCond1.js +290 -0
  7. package/lib/exercises/math/scratch/scratchFunction1.d.ts +9 -0
  8. package/lib/exercises/math/scratch/scratchFunction1.d.ts.map +1 -0
  9. package/lib/exercises/math/scratch/scratchFunction1.js +199 -0
  10. package/lib/exercises/math/scratch/scratchLoop1.d.ts +10 -0
  11. package/lib/exercises/math/scratch/scratchLoop1.d.ts.map +1 -0
  12. package/lib/exercises/math/scratch/scratchLoop1.js +207 -0
  13. package/lib/exercises/math/scratch/scratchLoopCond1.d.ts +12 -0
  14. package/lib/exercises/math/scratch/scratchLoopCond1.d.ts.map +1 -0
  15. package/lib/exercises/math/scratch/scratchLoopCond1.js +236 -0
  16. package/lib/exercises/math/scratch/scratchLoopCond2.d.ts +14 -0
  17. package/lib/exercises/math/scratch/scratchLoopCond2.d.ts.map +1 -0
  18. package/lib/exercises/math/scratch/scratchLoopCond2.js +219 -0
  19. package/lib/exercises/math/scratch/scratchOperations1.d.ts +8 -0
  20. package/lib/exercises/math/scratch/scratchOperations1.d.ts.map +1 -0
  21. package/lib/exercises/math/scratch/scratchOperations1.js +245 -0
  22. package/lib/exercises/math/scratch/scratchOperations2.d.ts +10 -0
  23. package/lib/exercises/math/scratch/scratchOperations2.d.ts.map +1 -0
  24. package/lib/exercises/math/scratch/scratchOperations2.js +324 -0
  25. package/lib/exercises/math/scratch/scratchPrintXY.d.ts +9 -0
  26. package/lib/exercises/math/scratch/scratchPrintXY.d.ts.map +1 -0
  27. package/lib/exercises/math/scratch/scratchPrintXY.js +194 -0
  28. package/lib/exercises/math/scratch/scratchStringLoop.d.ts +10 -0
  29. package/lib/exercises/math/scratch/scratchStringLoop.d.ts.map +1 -0
  30. package/lib/exercises/math/scratch/scratchStringLoop.js +192 -0
  31. package/lib/exercises/math/scratch/scratchStringLoopCond.d.ts +12 -0
  32. package/lib/exercises/math/scratch/scratchStringLoopCond.d.ts.map +1 -0
  33. package/lib/exercises/math/scratch/scratchStringLoopCond.js +270 -0
  34. package/lib/exercises/math/scratch/scratchStringLoopCond2.d.ts +12 -0
  35. package/lib/exercises/math/scratch/scratchStringLoopCond2.d.ts.map +1 -0
  36. package/lib/exercises/math/scratch/scratchStringLoopCond2.js +273 -0
  37. package/lib/exercises/math/scratch/scratchStringLoopCond3.d.ts +12 -0
  38. package/lib/exercises/math/scratch/scratchStringLoopCond3.d.ts.map +1 -0
  39. package/lib/exercises/math/scratch/scratchStringLoopCond3.js +275 -0
  40. package/lib/exercises/math/scratch/scratchSwapUsingTmp.d.ts +10 -0
  41. package/lib/exercises/math/scratch/scratchSwapUsingTmp.d.ts.map +1 -0
  42. package/lib/exercises/math/scratch/scratchSwapUsingTmp.js +199 -0
  43. package/lib/exercises/math/scratch/scratchVarWaterfall.d.ts +10 -0
  44. package/lib/exercises/math/scratch/scratchVarWaterfall.d.ts.map +1 -0
  45. package/lib/exercises/math/scratch/scratchVarWaterfall.js +371 -0
  46. package/lib/index.d.ts +86 -1
  47. package/lib/index.d.ts.map +1 -1
  48. package/package.json +1 -1
@@ -0,0 +1,194 @@
1
+ import { addValidProp, tryToAddWrongProp, } from "../../../exercises/exercise.js";
2
+ import { getDistinctQuestions } from "../../../exercises/utils/getDistinctQuestions.js";
3
+ import { randint } from "../../../math/utils/random/randint.js";
4
+ import { shuffle } from "../../../utils/alea/shuffle.js";
5
+ const getInstruction = (identifiers) => {
6
+ const { xStart, yStart, rand } = identifiers;
7
+ return `On considère le programme Scratch ci-dessous :
8
+
9
+ <svg id="scratch">
10
+ quand @greenFlag est cliqué
11
+ mettre [x v] à [${xStart}]
12
+ mettre [y v] à [${yStart}]
13
+ ${(() => {
14
+ switch (rand) {
15
+ //"x+y"
16
+ case 0:
17
+ return `dire [x + y]`;
18
+ case 1:
19
+ return `dire (regrouper [x] et (regrouper [+] et [y]))`;
20
+ //`${x}+${y}`
21
+ case 2:
22
+ return `dire (regrouper (x) et (regrouper [+] et (y)))`;
23
+ //`${x+y}`
24
+ case 3:
25
+ return `dire ((x) + (y))`;
26
+ //`x+${y}`
27
+ case 4:
28
+ return `dire (regrouper [x] et (regrouper [+] et (y)))`;
29
+ //`${x}+y`
30
+ case 5:
31
+ return `dire (regrouper (x) et (regrouper [+] et [y]))`;
32
+ }
33
+ })()}
34
+ </svg>
35
+
36
+ Que va dire le lutin quand on va exécuter le programme ?`;
37
+ };
38
+ const getFunctionForScratchProgram = (identifiers) => {
39
+ const { xStart, yStart, rand } = identifiers;
40
+ return (_) => {
41
+ const outDict = {};
42
+ //init
43
+ const x = xStart;
44
+ const y = yStart;
45
+ //convenience: store last step in -1
46
+ outDict[-1] = (() => {
47
+ switch (rand) {
48
+ case 0:
49
+ case 1:
50
+ return "x+y";
51
+ case 2:
52
+ return `${x}+${y}`;
53
+ case 3:
54
+ return `${x + y}`;
55
+ case 4:
56
+ return `x+${y}`;
57
+ case 5:
58
+ return `${x}+y`;
59
+ default:
60
+ throw new Error("unsupported rand: " + rand);
61
+ }
62
+ })();
63
+ return outDict;
64
+ };
65
+ };
66
+ const getAnswer = (identifiers) => {
67
+ const dictSteps = getFunctionForScratchProgram(identifiers)(identifiers);
68
+ return dictSteps[-1];
69
+ };
70
+ const getHint = () => {
71
+ return `Pour chaque variable, est-ce qu'on te demande d'afficher son nom, ou bien sa valeur ?`;
72
+ };
73
+ const getCorrection = (identifiers) => {
74
+ const { xStart, yStart, rand } = identifiers;
75
+ return `Initialement, $x$ vaut $${xStart}$ et $y$ vaut $${yStart}$.
76
+
77
+ ${(() => {
78
+ switch (rand) {
79
+ case 0:
80
+ return `Dans l'instruction dire ..., ce qui est en blanc, c'est la chaîne de caractères "x+y".
81
+
82
+ Le lutin va donc dire: "x+y" (Tout simplement !).`;
83
+ case 1:
84
+ return `Dans l'instruction dire ..., ce qui est en blanc, ce sont les chaînes de caractères "x", "+" et "y".
85
+
86
+ On les regroupe.
87
+
88
+ Le lutin va donc dire: "x+y".`;
89
+ case 2:
90
+ return `Dans l'instruction dire ..., ce qui est en blanc, c'est uniquement la chaîne de caractères "+".
91
+
92
+ On va donc construire des chaînes de caractères avec les valeurs des variables $x$ et $y$.
93
+
94
+ Ensuite, on regroupe tout.
95
+
96
+ Le lutin va donc dire : "$${xStart}$+$${yStart}$".`;
97
+ case 3:
98
+ return `Dans l'instruction dire ..., il n'y a rien en blanc.
99
+
100
+ On va donc calculer la somme $${xStart}$ + $${yStart}$ et la transformer en chaîne de caractères.
101
+
102
+ Le lutin va donc dire : "$${xStart + yStart}$".`;
103
+ case 4:
104
+ return `Dans l'instruction dire ..., ce qui est en blanc, ce sont les chaînes de caractères "x" et "+".
105
+
106
+ On va donc construire une chaîne de caractères avec la valeur de la variable $y$.
107
+
108
+ Ensuite, on regroupe tout.
109
+
110
+ Le lutin va donc dire : "x+$${yStart}$".`;
111
+ case 5:
112
+ return `Dans l'instruction dire ..., ce qui est en blanc, ce sont les chaînes de caractères "+" et "y".
113
+
114
+ On va donc construire une chaîne de caractères avec la valeur de la variable $x$.
115
+
116
+ Ensuite, on regroupe tout.
117
+
118
+ Le lutin va donc dire : "$${xStart}$+y".`;
119
+ default:
120
+ throw new Error("unsupported rand: " + rand);
121
+ }
122
+ })()}
123
+
124
+ `;
125
+ };
126
+ const getPropositions = (n, { answer, ...identifiers }) => {
127
+ const propositions = [];
128
+ addValidProp(propositions, answer);
129
+ //mandatory
130
+ [3].forEach((rand) => {
131
+ const identifiersWrong = Object.assign({}, identifiers, {
132
+ rand,
133
+ });
134
+ const texWrong = getAnswer(identifiersWrong);
135
+ tryToAddWrongProp(propositions, texWrong);
136
+ });
137
+ //filler
138
+ [...Array(6).keys()].forEach((rand) => {
139
+ if (propositions.length < n) {
140
+ const identifiersWrong = Object.assign({}, identifiers, {
141
+ rand,
142
+ });
143
+ const texWrong = getAnswer(identifiersWrong);
144
+ tryToAddWrongProp(propositions, texWrong);
145
+ }
146
+ });
147
+ return shuffle(propositions);
148
+ };
149
+ const getKeys = () => {
150
+ return ["x", "y"];
151
+ };
152
+ const isAnswerValid = (ans, { answer }) => {
153
+ return ans === answer;
154
+ };
155
+ const getScratchPrintXYQuestion = () => {
156
+ const xStart = randint(-10, 10);
157
+ const yStart = randint(-10, 10);
158
+ const rand = randint(0, 6);
159
+ const identifiers = {
160
+ xStart,
161
+ yStart,
162
+ rand,
163
+ };
164
+ return getQuestionFromIdentifiers(identifiers);
165
+ };
166
+ const getQuestionFromIdentifiers = (identifiers) => {
167
+ return {
168
+ answer: getAnswer(identifiers),
169
+ instruction: getInstruction(identifiers),
170
+ keys: getKeys(identifiers),
171
+ answerFormat: "tex",
172
+ identifiers,
173
+ hint: getHint(identifiers),
174
+ correction: getCorrection(identifiers),
175
+ };
176
+ };
177
+ export const scratchPrintXY = {
178
+ id: "scratchPrintXY",
179
+ connector: "=",
180
+ label: "Afficher des chaînes de caractères et/ou des valeurs de variables en Scratch",
181
+ isSingleStep: true,
182
+ generator: (nb, opts) => getDistinctQuestions(() => getScratchPrintXYQuestion(opts), nb),
183
+ qcmTimer: 60,
184
+ freeTimer: 60,
185
+ getPropositions,
186
+ isAnswerValid,
187
+ subject: "Mathématiques",
188
+ getInstruction,
189
+ getHint,
190
+ getCorrection,
191
+ getAnswer,
192
+ getQuestionFromIdentifiers,
193
+ hasHintAndCorrection: true,
194
+ };
@@ -0,0 +1,10 @@
1
+ import { Exercise } from "../../../exercises/exercise.js";
2
+ type Identifiers = {
3
+ strStart: string;
4
+ repeatCount: number;
5
+ strAppend1: string;
6
+ rand: number;
7
+ };
8
+ export declare const scratchStringLoop: Exercise<Identifiers>;
9
+ export {};
10
+ //# sourceMappingURL=scratchStringLoop.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scratchStringLoop.d.ts","sourceRoot":"","sources":["../../../../src/exercises/math/scratch/scratchStringLoop.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAcT,MAAM,6BAA6B,CAAC;AAMrC,KAAK,WAAW,GAAG;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AA8MF,eAAO,MAAM,iBAAiB,EAAE,QAAQ,CAAC,WAAW,CAkBnD,CAAC"}
@@ -0,0 +1,192 @@
1
+ import { addValidProp, shuffleProps, tryToAddWrongProp, } from "../../../exercises/exercise.js";
2
+ import { getDistinctQuestions } from "../../../exercises/utils/getDistinctQuestions.js";
3
+ import { randint } from "../../../math/utils/random/randint.js";
4
+ import { coinFlip } from "../../../utils/alea/coinFlip.js";
5
+ import { random } from "../../../utils/alea/random.js";
6
+ const getInstruction = (identifiers) => {
7
+ const { strStart, repeatCount, strAppend1, rand } = identifiers;
8
+ return `On considère le programme Scratch ci-dessous :
9
+
10
+ <svg id="scratch">
11
+ quand @greenFlag est cliqué
12
+ mettre [x v] à [${strStart}]
13
+ répéter (${repeatCount}) fois
14
+ ${(() => {
15
+ switch (rand) {
16
+ case 0:
17
+ return ` mettre [x v] à (regrouper (x) et [${strAppend1}])`;
18
+ case 1:
19
+ return ` mettre [x v] à (regrouper [${strAppend1}] et (x))`;
20
+ case 2:
21
+ return ` mettre [x v] à (regrouper (x) et (x))`;
22
+ case 3:
23
+ return ` mettre [x v] à (regrouper [${strAppend1}] et [${strAppend1}])`;
24
+ }
25
+ })()}
26
+ </svg>
27
+
28
+ Quelle est la valeur de $x$ à la fin de l'exécution du programme ?`;
29
+ };
30
+ const getFunctionForScratchProgram = (identifiers) => {
31
+ const { strStart, repeatCount, strAppend1, rand } = identifiers;
32
+ return (_) => {
33
+ const outDict = {};
34
+ //init
35
+ let x;
36
+ x = strStart;
37
+ outDict[0] = {
38
+ x,
39
+ };
40
+ //loop
41
+ let counter = 0;
42
+ while (counter < repeatCount) {
43
+ counter++;
44
+ //inside of loop
45
+ {
46
+ x = (() => {
47
+ switch (rand) {
48
+ case 0:
49
+ return x + strAppend1;
50
+ case 1:
51
+ return strAppend1 + x;
52
+ case 2:
53
+ return x + x;
54
+ case 3:
55
+ return strAppend1 + strAppend1;
56
+ default:
57
+ throw new Error("unsupported rand: " + rand);
58
+ }
59
+ })();
60
+ }
61
+ //store step dict
62
+ outDict[counter] = {
63
+ x,
64
+ };
65
+ }
66
+ //convenience: store last step in -1
67
+ outDict[-1] = outDict[Math.max(...Object.keys(outDict).map((k) => +k))];
68
+ return outDict;
69
+ };
70
+ };
71
+ const getAnswer = (identifiers) => {
72
+ return getFunctionForScratchProgram(identifiers)(identifiers)[-1].x;
73
+ };
74
+ const getHint = () => {
75
+ return `La valeur de la variable $x$ change au cours de l'exécution du programme.
76
+ À chaque itération,
77
+ détermine comment la variable évolue.`;
78
+ };
79
+ const getCorrection = (identifiers) => {
80
+ const { strAppend1, rand } = identifiers;
81
+ const dictSteps = getFunctionForScratchProgram(identifiers)(identifiers);
82
+ return `Initialement, $x$ vaut $${dictSteps[0].x}$.
83
+
84
+ ${Object.keys(dictSteps)
85
+ .map((k) => +k)
86
+ .filter((k) => k > 0)
87
+ .map((k) => {
88
+ return `Itération n°$${k}$ :
89
+
90
+ Au début, $x$ vaut $${dictSteps[k - 1].x}$.
91
+
92
+ On va affecter à $x$ la chaîne de caractères composée par le regroupement de ${(() => {
93
+ switch (rand) {
94
+ case 0:
95
+ return `$${dictSteps[k - 1].x}$ et de $${strAppend1}$`;
96
+ case 1:
97
+ return `$${strAppend1}$ et de $${dictSteps[k - 1].x}$`;
98
+ case 2:
99
+ return `$${dictSteps[k - 1].x}$ et de $${dictSteps[k - 1].x}$`;
100
+ case 3:
101
+ return `$${strAppend1}$ et de $${strAppend1}$`;
102
+ default:
103
+ throw new Error("unsupported rand: " + rand);
104
+ }
105
+ })()}.
106
+
107
+ $x$ vaut maintenant $${dictSteps[k].x}$.`;
108
+ }).join(`
109
+
110
+ `)}
111
+
112
+ À la fin de l'exécution du programme, $x$ vaut donc $${dictSteps[-1].x}$.`;
113
+ };
114
+ const getPropositions = (n, { answer, ...identifiers }) => {
115
+ const { strStart, repeatCount, rand } = identifiers;
116
+ const propositions = [];
117
+ addValidProp(propositions, answer);
118
+ [...Array(4).keys()].forEach((rand) => {
119
+ const identifiersWrong = Object.assign({}, identifiers, {
120
+ rand,
121
+ });
122
+ const texWrong = getAnswer(identifiersWrong);
123
+ tryToAddWrongProp(propositions, texWrong);
124
+ });
125
+ //strStart
126
+ tryToAddWrongProp(propositions, strStart);
127
+ //terror for rand===3
128
+ if (rand === 2) {
129
+ if (coinFlip()) {
130
+ const texWrong = strStart.repeat(2 ** repeatCount - 1);
131
+ tryToAddWrongProp(propositions, texWrong);
132
+ }
133
+ if (strStart.length === 1) {
134
+ if (coinFlip()) {
135
+ const texWrong = strStart.repeat(2 ** repeatCount + 1);
136
+ tryToAddWrongProp(propositions, texWrong);
137
+ }
138
+ }
139
+ }
140
+ return shuffleProps(propositions, n);
141
+ };
142
+ const getKeys = () => {
143
+ return ["A", "B", "C", "D"];
144
+ };
145
+ const isAnswerValid = (ans, { answer }) => {
146
+ return ans === answer;
147
+ };
148
+ const getScratchStringLoopQuestion = () => {
149
+ const rand = randint(0, 4);
150
+ function createRandomStr(length) {
151
+ return [...Array(length).keys()].reduce((acc, _) => acc + random(["A", "B", "C", "D"]), "");
152
+ }
153
+ const repeatCount = randint(1, 4);
154
+ const strStart = createRandomStr(rand === 2 && repeatCount === 3 ? 1 : randint(1, 3));
155
+ const strAppend1 = createRandomStr(randint(1, 3));
156
+ const identifiers = {
157
+ strStart,
158
+ repeatCount,
159
+ strAppend1,
160
+ rand,
161
+ };
162
+ return getQuestionFromIdentifiers(identifiers);
163
+ };
164
+ const getQuestionFromIdentifiers = (identifiers) => {
165
+ return {
166
+ answer: getAnswer(identifiers),
167
+ instruction: getInstruction(identifiers),
168
+ keys: getKeys(identifiers),
169
+ answerFormat: "tex",
170
+ identifiers,
171
+ hint: getHint(identifiers),
172
+ correction: getCorrection(identifiers),
173
+ };
174
+ };
175
+ export const scratchStringLoop = {
176
+ id: "scratchStringLoop",
177
+ connector: "=",
178
+ label: "Utiliser une boucle avec une chaîne de caractères en Scratch",
179
+ isSingleStep: true,
180
+ generator: (nb, opts) => getDistinctQuestions(() => getScratchStringLoopQuestion(opts), nb),
181
+ qcmTimer: 60,
182
+ freeTimer: 60,
183
+ getPropositions,
184
+ isAnswerValid,
185
+ subject: "Mathématiques",
186
+ getInstruction,
187
+ getHint,
188
+ getCorrection,
189
+ getAnswer,
190
+ getQuestionFromIdentifiers,
191
+ hasHintAndCorrection: true,
192
+ };
@@ -0,0 +1,12 @@
1
+ import { Exercise } from "../../../exercises/exercise.js";
2
+ type Identifiers = {
3
+ strStart: string;
4
+ repeatCount: number;
5
+ isGreaterCond1: boolean;
6
+ thresholdCond1: number;
7
+ arrStrAppend: string[];
8
+ arrRand: number[];
9
+ };
10
+ export declare const scratchStringLoopCond: Exercise<Identifiers>;
11
+ export {};
12
+ //# sourceMappingURL=scratchStringLoopCond.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scratchStringLoopCond.d.ts","sourceRoot":"","sources":["../../../../src/exercises/math/scratch/scratchStringLoopCond.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAcT,MAAM,6BAA6B,CAAC;AAqBrC,KAAK,WAAW,GAAG;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,OAAO,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB,CAAC;AA4SF,eAAO,MAAM,qBAAqB,EAAE,QAAQ,CAAC,WAAW,CAmBvD,CAAC"}
@@ -0,0 +1,270 @@
1
+ import { addValidProp, shuffleProps, tryToAddWrongProp, } from "../../../exercises/exercise.js";
2
+ import { getDistinctQuestions } from "../../../exercises/utils/getDistinctQuestions.js";
3
+ import { randint } from "../../../math/utils/random/randint.js";
4
+ import { coinFlip } from "../../../utils/alea/coinFlip.js";
5
+ import { probaFlip } from "../../../utils/alea/probaFlip.js";
6
+ import { random, randomMany } from "../../../utils/alea/random.js";
7
+ import { getCartesiansProducts } from "../../../utils/arrays/cartesianProducts.js";
8
+ const getStrScratchForRand = (rand, strAppend) => {
9
+ switch (rand) {
10
+ case 0:
11
+ return ` mettre [x v] à (regrouper (x) et [${strAppend}])`;
12
+ case 1:
13
+ return ` mettre [x v] à (regrouper [${strAppend}] et (x))`;
14
+ case 2:
15
+ return ` mettre [x v] à (regrouper (x) et (x))`;
16
+ case 3:
17
+ return ` mettre [x v] à (regrouper [${strAppend}] et [${strAppend}])`;
18
+ }
19
+ };
20
+ const getInstruction = (identifiers) => {
21
+ const { strStart, repeatCount, isGreaterCond1, thresholdCond1, arrStrAppend, arrRand, } = identifiers;
22
+ return `On considère le programme Scratch ci-dessous :
23
+
24
+ <svg id="scratch">
25
+ quand @greenFlag est cliqué
26
+ mettre [x v] à [${strStart}]
27
+ répéter (${repeatCount}) fois
28
+ si <(longueur de (x)) ${isGreaterCond1 ? ">" : "\\<"} (${thresholdCond1})> alors
29
+ ${arrRand.map((rand, i) => `${getStrScratchForRand(rand, arrStrAppend[i])}
30
+ `).join(`sinon
31
+ `)}
32
+ </svg>
33
+
34
+ Quelle est la valeur de $x$ à la fin de l'exécution du programme ?`;
35
+ };
36
+ const getFunctionForScratchProgram = (identifiers) => {
37
+ const { strStart, repeatCount, isGreaterCond1, thresholdCond1, arrStrAppend, arrRand, } = identifiers;
38
+ return (_) => {
39
+ const outDict = {};
40
+ //init
41
+ let x;
42
+ x = strStart;
43
+ outDict[0] = {
44
+ x,
45
+ };
46
+ function strForXAndRandAndStrAppend(x, rand, strAppend) {
47
+ switch (rand) {
48
+ case 0:
49
+ return x + strAppend;
50
+ case 1:
51
+ return strAppend + x;
52
+ case 2:
53
+ return x + x;
54
+ case 3:
55
+ return strAppend + strAppend;
56
+ default:
57
+ throw new Error("unsupported rand: " + rand);
58
+ }
59
+ }
60
+ //loop
61
+ let counter = 0;
62
+ while (counter < repeatCount) {
63
+ counter++;
64
+ //inside of loop
65
+ {
66
+ if (isGreaterCond1 ? x.length > thresholdCond1 : x.length < thresholdCond1) {
67
+ x = strForXAndRandAndStrAppend(x, arrRand[0], arrStrAppend[0]);
68
+ }
69
+ else {
70
+ x = strForXAndRandAndStrAppend(x, arrRand[1], arrStrAppend[1]);
71
+ }
72
+ }
73
+ //store step dict
74
+ outDict[counter] = {
75
+ x,
76
+ };
77
+ }
78
+ //convenience: store last step in -1
79
+ outDict[-1] = outDict[Math.max(...Object.keys(outDict).map((k) => +k))];
80
+ return outDict;
81
+ };
82
+ };
83
+ const getAnswer = (identifiers) => {
84
+ return getFunctionForScratchProgram(identifiers)(identifiers)[-1].x;
85
+ };
86
+ const getHint = () => {
87
+ return `La valeur de la variable $x$ change au cours de l'exécution du programme.
88
+ À chaque itération,
89
+ détermine comment la variable évolue.
90
+ La longueur d'une chaîne de caractères est le nombre de caractères qu'elle contient (exemple : "AAC" est de longueur $3$).`;
91
+ };
92
+ const getCorrection = (identifiers) => {
93
+ const { isGreaterCond1, thresholdCond1, arrRand, arrStrAppend } = identifiers;
94
+ const dictSteps = getFunctionForScratchProgram(identifiers)(identifiers);
95
+ return `Initialement, $x$ vaut $${dictSteps[0].x}$.
96
+
97
+ ${Object.keys(dictSteps)
98
+ .map((k) => +k)
99
+ .filter((k) => k > 0)
100
+ .map((k) => {
101
+ const x = dictSteps[k - 1].x;
102
+ const isConditionVerified = isGreaterCond1
103
+ ? x.length > thresholdCond1
104
+ : x.length < thresholdCond1;
105
+ const indexCondition = isConditionVerified ? 0 : 1;
106
+ const rand = arrRand[indexCondition];
107
+ const strAppend1 = arrStrAppend[indexCondition];
108
+ return `Itération n°$${k}$ :
109
+
110
+ Au début, $x$ vaut $${x}$.
111
+
112
+ La longueur de $x$ est $${x.length}$.
113
+
114
+ La condition ${isConditionVerified ? "est vérifiée" : "n'est pas vérifiée"}.
115
+
116
+ On va affecter à $x$ la chaîne de caractères composée par le regroupement de ${(() => {
117
+ switch (rand) {
118
+ case 0:
119
+ return `$${dictSteps[k - 1].x}$ et de $${strAppend1}$`;
120
+ case 1:
121
+ return `$${strAppend1}$ et de $${dictSteps[k - 1].x}$`;
122
+ case 2:
123
+ return `$${dictSteps[k - 1].x}$ et de $${dictSteps[k - 1].x}$`;
124
+ case 3:
125
+ return `$${strAppend1}$ et de $${strAppend1}$`;
126
+ default:
127
+ throw new Error("unsupported rand: " + rand);
128
+ }
129
+ })()}.
130
+
131
+ $x$ vaut maintenant $${dictSteps[k].x}$.`;
132
+ }).join(`
133
+
134
+ `)}
135
+
136
+ À la fin de l'exécution du programme, $x$ vaut donc $${dictSteps[-1].x}$.`;
137
+ };
138
+ const getPropositions = (n, { answer, ...identifiers }) => {
139
+ const { strStart, repeatCount, arrRand, arrStrAppend } = identifiers;
140
+ const propositions = [];
141
+ addValidProp(propositions, answer);
142
+ //toggle on all checks
143
+ {
144
+ const identifiersWrong = Object.assign({}, identifiers, {
145
+ arrRand: arrRand.toReversed(),
146
+ arrStrAppend: arrStrAppend.toReversed(),
147
+ });
148
+ const texWrong = getAnswer(identifiersWrong);
149
+ tryToAddWrongProp(propositions, texWrong);
150
+ }
151
+ //ABB instead of BBA
152
+ if (arrRand.includes(0) || arrRand.includes(1)) {
153
+ const identifiersWrong = Object.assign({}, identifiers, {
154
+ arrRand: arrRand.map((rand) => (rand === 0 ? 1 : rand === 1 ? 0 : rand)),
155
+ arrStrAppend: arrStrAppend.toReversed(),
156
+ });
157
+ const texWrong = getAnswer(identifiersWrong);
158
+ tryToAddWrongProp(propositions, texWrong);
159
+ }
160
+ //wrong repeatCount
161
+ {
162
+ const identifiersWrong = Object.assign({}, identifiers, {
163
+ repeatCount: repeatCount - 1,
164
+ });
165
+ const texWrong = getAnswer(identifiersWrong);
166
+ tryToAddWrongProp(propositions, texWrong);
167
+ }
168
+ //strStart
169
+ tryToAddWrongProp(propositions, strStart);
170
+ //filler
171
+ [...Array(repeatCount + 4).keys()].forEach((repeatCountW) => {
172
+ let strWrong = strStart;
173
+ [...Array(repeatCountW).keys()].forEach(() => {
174
+ const strAppend = random(arrStrAppend);
175
+ if (coinFlip()) {
176
+ strWrong = strWrong + strAppend;
177
+ }
178
+ else {
179
+ strWrong = strAppend + strWrong;
180
+ }
181
+ });
182
+ if (propositions.length < n) {
183
+ tryToAddWrongProp(propositions, strWrong);
184
+ }
185
+ });
186
+ ["A", "B", "C", "D"].forEach((strWrong) => {
187
+ if (propositions.length < n) {
188
+ tryToAddWrongProp(propositions, strWrong);
189
+ }
190
+ });
191
+ return shuffleProps(propositions, n);
192
+ };
193
+ const getKeys = () => {
194
+ return ["A", "B", "C", "D"];
195
+ };
196
+ const isAnswerValid = (ans, { answer }) => {
197
+ return ans === answer;
198
+ };
199
+ const getScratchStringLoopCondQuestion = () => {
200
+ const arrRand = randomMany([0, 1, 2, 3], 2);
201
+ function createRandomStr(length) {
202
+ return [...Array(length).keys()].reduce((acc, _) => acc + random(["A", "B", "C", "D"]), "");
203
+ }
204
+ function createAllPossibleStrings(minLength, maxLength) {
205
+ return [...Array(maxLength - minLength).keys()]
206
+ .map((i) => i + minLength)
207
+ .reduce((acc, length) => {
208
+ const arrSrc = [...Array(length).keys()].map(() => [
209
+ "A",
210
+ "B",
211
+ "C",
212
+ "D",
213
+ ]);
214
+ const arrCartesianProduct = getCartesiansProducts(arrSrc);
215
+ const arrStr = arrCartesianProduct.map((arr) => arr.join(""));
216
+ acc.push(...arrStr);
217
+ return acc;
218
+ }, []);
219
+ }
220
+ const repeatCount = arrRand.includes(2) ? randint(2, 4) : randint(2, 5);
221
+ const strStart = createRandomStr(arrRand.includes(2) && repeatCount === 3 ? 1 : randint(1, 3));
222
+ let arrStrAppend;
223
+ if (probaFlip(0.41)) {
224
+ const strAppendSame = random(createAllPossibleStrings(1, 3).filter((str) => str !== strStart));
225
+ arrStrAppend = [0, 1].map(() => strAppendSame);
226
+ }
227
+ else {
228
+ arrStrAppend = [0, 1].map(() => createRandomStr(randint(1, 3)));
229
+ }
230
+ const isGreaterCond1 = coinFlip();
231
+ const thresholdCond1 = randint(3, 6);
232
+ const identifiers = {
233
+ strStart,
234
+ repeatCount,
235
+ arrStrAppend,
236
+ arrRand,
237
+ isGreaterCond1,
238
+ thresholdCond1,
239
+ };
240
+ return getQuestionFromIdentifiers(identifiers);
241
+ };
242
+ const getQuestionFromIdentifiers = (identifiers) => {
243
+ return {
244
+ answer: getAnswer(identifiers),
245
+ instruction: getInstruction(identifiers),
246
+ keys: getKeys(identifiers),
247
+ answerFormat: "tex",
248
+ identifiers,
249
+ hint: getHint(identifiers),
250
+ correction: getCorrection(identifiers),
251
+ };
252
+ };
253
+ export const scratchStringLoopCond = {
254
+ id: "scratchStringLoopCond",
255
+ connector: "=",
256
+ label: "Utiliser une condition dans une boucle avec une chaîne de caractères en Scratch",
257
+ isSingleStep: true,
258
+ generator: (nb, opts) => getDistinctQuestions(() => getScratchStringLoopCondQuestion(opts), nb),
259
+ qcmTimer: 60,
260
+ freeTimer: 60,
261
+ getPropositions,
262
+ isAnswerValid,
263
+ subject: "Mathématiques",
264
+ getInstruction,
265
+ getHint,
266
+ getCorrection,
267
+ getAnswer,
268
+ getQuestionFromIdentifiers,
269
+ hasHintAndCorrection: true,
270
+ };