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.
- package/lib/exercises/math/scratch/index.d.ts +13 -0
- package/lib/exercises/math/scratch/index.d.ts.map +1 -1
- package/lib/exercises/math/scratch/index.js +14 -0
- package/lib/exercises/math/scratch/scratchCond1.d.ts +25 -0
- package/lib/exercises/math/scratch/scratchCond1.d.ts.map +1 -0
- package/lib/exercises/math/scratch/scratchCond1.js +290 -0
- package/lib/exercises/math/scratch/scratchFunction1.d.ts +9 -0
- package/lib/exercises/math/scratch/scratchFunction1.d.ts.map +1 -0
- package/lib/exercises/math/scratch/scratchFunction1.js +199 -0
- package/lib/exercises/math/scratch/scratchLoop1.d.ts +10 -0
- package/lib/exercises/math/scratch/scratchLoop1.d.ts.map +1 -0
- package/lib/exercises/math/scratch/scratchLoop1.js +207 -0
- package/lib/exercises/math/scratch/scratchLoopCond1.d.ts +12 -0
- package/lib/exercises/math/scratch/scratchLoopCond1.d.ts.map +1 -0
- package/lib/exercises/math/scratch/scratchLoopCond1.js +236 -0
- package/lib/exercises/math/scratch/scratchLoopCond2.d.ts +14 -0
- package/lib/exercises/math/scratch/scratchLoopCond2.d.ts.map +1 -0
- package/lib/exercises/math/scratch/scratchLoopCond2.js +219 -0
- package/lib/exercises/math/scratch/scratchOperations1.d.ts +8 -0
- package/lib/exercises/math/scratch/scratchOperations1.d.ts.map +1 -0
- package/lib/exercises/math/scratch/scratchOperations1.js +245 -0
- package/lib/exercises/math/scratch/scratchOperations2.d.ts +10 -0
- package/lib/exercises/math/scratch/scratchOperations2.d.ts.map +1 -0
- package/lib/exercises/math/scratch/scratchOperations2.js +324 -0
- package/lib/exercises/math/scratch/scratchPrintXY.d.ts +9 -0
- package/lib/exercises/math/scratch/scratchPrintXY.d.ts.map +1 -0
- package/lib/exercises/math/scratch/scratchPrintXY.js +194 -0
- package/lib/exercises/math/scratch/scratchStringLoop.d.ts +10 -0
- package/lib/exercises/math/scratch/scratchStringLoop.d.ts.map +1 -0
- package/lib/exercises/math/scratch/scratchStringLoop.js +192 -0
- package/lib/exercises/math/scratch/scratchStringLoopCond.d.ts +12 -0
- package/lib/exercises/math/scratch/scratchStringLoopCond.d.ts.map +1 -0
- package/lib/exercises/math/scratch/scratchStringLoopCond.js +270 -0
- package/lib/exercises/math/scratch/scratchStringLoopCond2.d.ts +12 -0
- package/lib/exercises/math/scratch/scratchStringLoopCond2.d.ts.map +1 -0
- package/lib/exercises/math/scratch/scratchStringLoopCond2.js +273 -0
- package/lib/exercises/math/scratch/scratchStringLoopCond3.d.ts +12 -0
- package/lib/exercises/math/scratch/scratchStringLoopCond3.d.ts.map +1 -0
- package/lib/exercises/math/scratch/scratchStringLoopCond3.js +275 -0
- package/lib/exercises/math/scratch/scratchSwapUsingTmp.d.ts +10 -0
- package/lib/exercises/math/scratch/scratchSwapUsingTmp.d.ts.map +1 -0
- package/lib/exercises/math/scratch/scratchSwapUsingTmp.js +199 -0
- package/lib/exercises/math/scratch/scratchVarWaterfall.d.ts +10 -0
- package/lib/exercises/math/scratch/scratchVarWaterfall.d.ts.map +1 -0
- package/lib/exercises/math/scratch/scratchVarWaterfall.js +371 -0
- package/lib/index.d.ts +86 -1
- package/lib/index.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1,2 +1,15 @@
|
|
|
1
1
|
export * from "./scratchLoopStepsCount.js";
|
|
2
|
+
export * from "./scratchLoopCond1.js";
|
|
3
|
+
export * from "./scratchSwapUsingTmp.js";
|
|
4
|
+
export * from "./scratchLoopCond2.js";
|
|
5
|
+
export * from "./scratchPrintXY.js";
|
|
6
|
+
export * from "./scratchOperations1.js";
|
|
7
|
+
export * from "./scratchOperations2.js";
|
|
8
|
+
export * from "./scratchLoop1.js";
|
|
9
|
+
export * from "./scratchVarWaterfall.js";
|
|
10
|
+
export * from "./scratchStringLoop.js";
|
|
11
|
+
export * from "./scratchStringLoopCond.js";
|
|
12
|
+
export * from "./scratchStringLoopCond2.js";
|
|
13
|
+
export * from "./scratchStringLoopCond3.js";
|
|
14
|
+
export * from "./scratchCond1.js";
|
|
2
15
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/exercises/math/scratch/index.ts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/exercises/math/scratch/index.ts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAC;AAC3C,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC;AACxC,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,mBAAmB,CAAC"}
|
|
@@ -1 +1,15 @@
|
|
|
1
1
|
export * from "./scratchLoopStepsCount.js";
|
|
2
|
+
export * from "./scratchLoopCond1.js";
|
|
3
|
+
export * from "./scratchSwapUsingTmp.js";
|
|
4
|
+
export * from "./scratchLoopCond2.js";
|
|
5
|
+
export * from "./scratchPrintXY.js";
|
|
6
|
+
export * from "./scratchOperations1.js";
|
|
7
|
+
export * from "./scratchOperations2.js";
|
|
8
|
+
export * from "./scratchLoop1.js";
|
|
9
|
+
export * from "./scratchVarWaterfall.js";
|
|
10
|
+
export * from "./scratchStringLoop.js";
|
|
11
|
+
export * from "./scratchStringLoopCond.js";
|
|
12
|
+
export * from "./scratchStringLoopCond2.js";
|
|
13
|
+
export * from "./scratchStringLoopCond3.js";
|
|
14
|
+
export * from "./scratchCond1.js";
|
|
15
|
+
// export * from "./scratchFunction1.js";
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Exercise } from "../../../exercises/exercise.js";
|
|
2
|
+
type Condition1 = {
|
|
3
|
+
isNOT: boolean;
|
|
4
|
+
isGreaterCond1: boolean;
|
|
5
|
+
thresholdCond1: number;
|
|
6
|
+
};
|
|
7
|
+
type Condition2 = {
|
|
8
|
+
isAND: boolean;
|
|
9
|
+
conditions: Condition1[];
|
|
10
|
+
};
|
|
11
|
+
type Condition = Condition1 | Condition2;
|
|
12
|
+
type Identifiers = {
|
|
13
|
+
xStart: number;
|
|
14
|
+
factorStart: number;
|
|
15
|
+
condition: Condition;
|
|
16
|
+
offsetCondTrue: number;
|
|
17
|
+
};
|
|
18
|
+
type Options = {
|
|
19
|
+
isAllowAND: boolean;
|
|
20
|
+
isAllowOR: boolean;
|
|
21
|
+
isAllowNOT: boolean;
|
|
22
|
+
};
|
|
23
|
+
export declare const scratchCond1: Exercise<Identifiers, Options>;
|
|
24
|
+
export {};
|
|
25
|
+
//# sourceMappingURL=scratchCond1.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scratchCond1.d.ts","sourceRoot":"","sources":["../../../../src/exercises/math/scratch/scratchCond1.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAkBT,MAAM,6BAA6B,CAAC;AAQrC,KAAK,UAAU,GAAG;IAChB,KAAK,EAAE,OAAO,CAAC;IACf,cAAc,EAAE,OAAO,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,KAAK,UAAU,GAAG;IAChB,KAAK,EAAE,OAAO,CAAC;IACf,UAAU,EAAE,UAAU,EAAE,CAAC;CAC1B,CAAC;AAEF,KAAK,SAAS,GAAG,UAAU,GAAG,UAAU,CAAC;AA4FzC,KAAK,WAAW,GAAG;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,SAAS,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAoNF,KAAK,OAAO,GAAG;IACb,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;CACrB,CAAC;AAgCF,eAAO,MAAM,YAAY,EAAE,QAAQ,CAAC,WAAW,EAAE,OAAO,CAmBvD,CAAC"}
|
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
import { addValidProp, shuffleProps, tryToAddWrongProp, propWhile, GeneratorOptionTarget, GeneratorOptionType, } from "../../../exercises/exercise.js";
|
|
2
|
+
import { getDistinctQuestions } from "../../../exercises/utils/getDistinctQuestions.js";
|
|
3
|
+
import { numberVEA } from "../../../exercises/vea/numberVEA.js";
|
|
4
|
+
import { randint } from "../../../math/utils/random/randint.js";
|
|
5
|
+
import { coinFlip } from "../../../utils/alea/coinFlip.js";
|
|
6
|
+
import { random } from "../../../utils/alea/random.js";
|
|
7
|
+
import { handleVEAError } from "../../../utils/errors/handleVEAError.js";
|
|
8
|
+
const getFlatArrCondition = (condition) => {
|
|
9
|
+
if ("conditions" in condition) {
|
|
10
|
+
const conditions = condition.conditions;
|
|
11
|
+
return [
|
|
12
|
+
...conditions.flatMap((conditionChild) => [
|
|
13
|
+
...getFlatArrCondition(conditionChild),
|
|
14
|
+
]),
|
|
15
|
+
condition,
|
|
16
|
+
];
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
if (condition.isNOT) {
|
|
20
|
+
return [Object.assign({}, condition, { isNOT: false }), condition];
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
return [condition];
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
const getFunctionForCondition = (condition) => {
|
|
28
|
+
if ("conditions" in condition) {
|
|
29
|
+
const conditions = condition.conditions;
|
|
30
|
+
if (condition.isAND) {
|
|
31
|
+
return (x) => conditions.reduce((acc, conditionChild) => acc && getFunctionForCondition(conditionChild)(x), true);
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
return (x) => conditions.reduce((acc, conditionChild) => acc || getFunctionForCondition(conditionChild)(x), false);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
const { isNOT, isGreaterCond1, thresholdCond1 } = condition;
|
|
39
|
+
if (isNOT) {
|
|
40
|
+
const conditionRaw = Object.assign({}, condition, { isNOT: !isNOT });
|
|
41
|
+
return (x) => !getFunctionForCondition(conditionRaw)(x);
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
return (x) => {
|
|
45
|
+
return isGreaterCond1 ? x > thresholdCond1 : x < thresholdCond1;
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
const getStrScratchForCondition = (condition) => {
|
|
51
|
+
if ("conditions" in condition) {
|
|
52
|
+
const conditions = condition.conditions;
|
|
53
|
+
return `< ${getStrScratchForCondition(conditions[0])} ${condition.isAND ? " et " : " ou "} ${getStrScratchForCondition(conditions[1])} >`;
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
const { isNOT, isGreaterCond1, thresholdCond1 } = condition;
|
|
57
|
+
if (isNOT) {
|
|
58
|
+
const conditionRaw = Object.assign({}, condition, { isNOT: !isNOT });
|
|
59
|
+
return `< non ${getStrScratchForCondition(conditionRaw)}>`;
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
return `<(x) ${isGreaterCond1 ? ">" : "\\<"} (${thresholdCond1})>`;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
const getTexForCondition = (condition) => {
|
|
67
|
+
if ("conditions" in condition) {
|
|
68
|
+
const conditions = condition.conditions;
|
|
69
|
+
return `(${getTexForCondition(conditions[0])} ${condition.isAND ? "\\ et\\ " : "\\ ou\\ "} ${getTexForCondition(conditions[1])})`;
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
const { isNOT, isGreaterCond1, thresholdCond1 } = condition;
|
|
73
|
+
if (isNOT) {
|
|
74
|
+
return `non( x ${isGreaterCond1 ? ">" : "<"} ${thresholdCond1})`;
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
return `x ${isGreaterCond1 ? ">" : "<"} ${thresholdCond1}`;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
const getInstruction = (identifiers) => {
|
|
82
|
+
const { xStart, factorStart, condition, offsetCondTrue } = identifiers;
|
|
83
|
+
return `On considère le programme Scratch ci-dessous :
|
|
84
|
+
|
|
85
|
+
<svg id="scratch">
|
|
86
|
+
quand @greenFlag est cliqué
|
|
87
|
+
mettre [x v] à ([${xStart}] * [${factorStart}])
|
|
88
|
+
si ${getStrScratchForCondition(condition)} alors
|
|
89
|
+
ajouter (${offsetCondTrue}) à [x v]
|
|
90
|
+
</svg>
|
|
91
|
+
|
|
92
|
+
Quelle est la valeur de $x$ à la fin de l'exécution du programme ?`;
|
|
93
|
+
};
|
|
94
|
+
const getFunctionForScratchProgram = (identifiers) => {
|
|
95
|
+
const { xStart, factorStart, condition, offsetCondTrue } = identifiers;
|
|
96
|
+
return (_) => {
|
|
97
|
+
const outDict = {};
|
|
98
|
+
//init
|
|
99
|
+
let x = xStart * factorStart;
|
|
100
|
+
outDict[0] = {
|
|
101
|
+
x,
|
|
102
|
+
};
|
|
103
|
+
//cond
|
|
104
|
+
{
|
|
105
|
+
if (getFunctionForCondition(condition)(x)) {
|
|
106
|
+
x = x + offsetCondTrue;
|
|
107
|
+
}
|
|
108
|
+
//store step dict
|
|
109
|
+
outDict[1] = {
|
|
110
|
+
x,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
//convenience: store last step in -1
|
|
114
|
+
outDict[-1] = outDict[Math.max(...Object.keys(outDict).map((k) => +k))];
|
|
115
|
+
return outDict;
|
|
116
|
+
};
|
|
117
|
+
};
|
|
118
|
+
const getAnswerNode = (identifiers) => {
|
|
119
|
+
return getFunctionForScratchProgram(identifiers)(identifiers)[-1].x.toTree();
|
|
120
|
+
};
|
|
121
|
+
const getAnswer = (identifiers) => {
|
|
122
|
+
return getAnswerNode(identifiers).toTex();
|
|
123
|
+
};
|
|
124
|
+
const getHint = () => {
|
|
125
|
+
return `Cherche si la condition est vérifiée
|
|
126
|
+
pour déterminer si l'instruction dans le bloc "si ... alors" va être exécutée.
|
|
127
|
+
S'il y a un "et", il faut que toutes les conditions soient vérifiées.
|
|
128
|
+
S'il y a un "ou", il faut qu'au moins une condition soit vérifiée.
|
|
129
|
+
S'il y a un "non", il faut que la condition qu'il cible ne soit pas vérifiée.`;
|
|
130
|
+
};
|
|
131
|
+
const getCorrection = (identifiers) => {
|
|
132
|
+
const { condition } = identifiers;
|
|
133
|
+
const dictSteps = getFunctionForScratchProgram(identifiers)(identifiers);
|
|
134
|
+
const x = dictSteps[0].x;
|
|
135
|
+
return `Initialement, $x$ vaut $${dictSteps[0].x}$.
|
|
136
|
+
|
|
137
|
+
${getFlatArrCondition(condition).map((conditionMember) => {
|
|
138
|
+
const isConditionVerified = getFunctionForCondition(conditionMember)(x);
|
|
139
|
+
return `La condition $${getTexForCondition(conditionMember)}$ ${isConditionVerified ? "est vérifiée" : "n'est pas vérifiée"}.`;
|
|
140
|
+
}).join(`
|
|
141
|
+
|
|
142
|
+
`)}
|
|
143
|
+
|
|
144
|
+
À la fin de l'exécution du programme, $x$ vaut donc $${dictSteps[-1].x}$.
|
|
145
|
+
`;
|
|
146
|
+
};
|
|
147
|
+
const getPropositions = (n, { answer, ...identifiers }) => {
|
|
148
|
+
const { xStart, factorStart, offsetCondTrue } = identifiers;
|
|
149
|
+
const propositions = [];
|
|
150
|
+
addValidProp(propositions, answer);
|
|
151
|
+
//wrong cond
|
|
152
|
+
{
|
|
153
|
+
tryToAddWrongProp(propositions, (xStart * factorStart).frenchify());
|
|
154
|
+
tryToAddWrongProp(propositions, (xStart * factorStart + offsetCondTrue).frenchify());
|
|
155
|
+
}
|
|
156
|
+
//add instead of mult
|
|
157
|
+
{
|
|
158
|
+
tryToAddWrongProp(propositions, (xStart + factorStart).frenchify());
|
|
159
|
+
}
|
|
160
|
+
//problème de tables
|
|
161
|
+
{
|
|
162
|
+
const offset = randint(-10, 11);
|
|
163
|
+
tryToAddWrongProp(propositions, (xStart * factorStart + offset).frenchify());
|
|
164
|
+
}
|
|
165
|
+
propWhile(propositions, n, () => {
|
|
166
|
+
tryToAddWrongProp(propositions, randint(-20, 21).frenchify());
|
|
167
|
+
});
|
|
168
|
+
return shuffleProps(propositions, n);
|
|
169
|
+
};
|
|
170
|
+
const getKeys = () => {
|
|
171
|
+
return [];
|
|
172
|
+
};
|
|
173
|
+
const isAnswerValid = (ans, { answer }) => {
|
|
174
|
+
try {
|
|
175
|
+
return numberVEA(ans, answer);
|
|
176
|
+
}
|
|
177
|
+
catch (err) {
|
|
178
|
+
return handleVEAError(err);
|
|
179
|
+
}
|
|
180
|
+
};
|
|
181
|
+
const getScratchCond1Question = (optsIn) => {
|
|
182
|
+
const opts = (optsIn ?? optsDefault);
|
|
183
|
+
function createRandomCond1(isAllowNOT) {
|
|
184
|
+
const isNOT = isAllowNOT && coinFlip();
|
|
185
|
+
const isGreaterCond1 = coinFlip();
|
|
186
|
+
const thresholdCond1 = randint(-50, 51);
|
|
187
|
+
const condition1 = {
|
|
188
|
+
isNOT,
|
|
189
|
+
isGreaterCond1,
|
|
190
|
+
thresholdCond1,
|
|
191
|
+
};
|
|
192
|
+
return condition1;
|
|
193
|
+
}
|
|
194
|
+
const isAllowCond2 = opts.isAllowAND || opts.isAllowOR;
|
|
195
|
+
const isCond2 = isAllowCond2 && coinFlip();
|
|
196
|
+
const cond2Type = random([
|
|
197
|
+
...(opts.isAllowAND ? ["and"] : []),
|
|
198
|
+
...(opts.isAllowAND ? ["or"] : []),
|
|
199
|
+
]);
|
|
200
|
+
let condition;
|
|
201
|
+
if (isCond2) {
|
|
202
|
+
let arrIsAllowNOT;
|
|
203
|
+
if (opts.isAllowNOT) {
|
|
204
|
+
arrIsAllowNOT = random([
|
|
205
|
+
[true, false],
|
|
206
|
+
[false, true],
|
|
207
|
+
[false, false],
|
|
208
|
+
]);
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
arrIsAllowNOT = [false, false];
|
|
212
|
+
}
|
|
213
|
+
condition = {
|
|
214
|
+
isAND: cond2Type === "and",
|
|
215
|
+
conditions: arrIsAllowNOT.map((isAllowNOT) => createRandomCond1(isAllowNOT)),
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
else {
|
|
219
|
+
condition = createRandomCond1(opts.isAllowNOT);
|
|
220
|
+
}
|
|
221
|
+
const xStart = randint(-10, 11);
|
|
222
|
+
const factorStart = randint(-10, 11);
|
|
223
|
+
const offsetCondTrue = randint(-20, 21);
|
|
224
|
+
const identifiers = {
|
|
225
|
+
xStart,
|
|
226
|
+
factorStart,
|
|
227
|
+
condition,
|
|
228
|
+
offsetCondTrue,
|
|
229
|
+
};
|
|
230
|
+
return getQuestionFromIdentifiers(identifiers, opts);
|
|
231
|
+
};
|
|
232
|
+
const getQuestionFromIdentifiers = (identifiers, opts) => {
|
|
233
|
+
return {
|
|
234
|
+
answer: getAnswer(identifiers),
|
|
235
|
+
instruction: getInstruction(identifiers),
|
|
236
|
+
keys: getKeys(identifiers),
|
|
237
|
+
answerFormat: "tex",
|
|
238
|
+
identifiers,
|
|
239
|
+
hint: getHint(identifiers),
|
|
240
|
+
correction: getCorrection(identifiers),
|
|
241
|
+
options: opts,
|
|
242
|
+
};
|
|
243
|
+
};
|
|
244
|
+
const optsDefault = {
|
|
245
|
+
isAllowAND: true,
|
|
246
|
+
isAllowOR: true,
|
|
247
|
+
isAllowNOT: true,
|
|
248
|
+
};
|
|
249
|
+
const options = [
|
|
250
|
+
{
|
|
251
|
+
id: "isAllowAND",
|
|
252
|
+
label: `autoriser "et"`,
|
|
253
|
+
target: GeneratorOptionTarget.instruction,
|
|
254
|
+
type: GeneratorOptionType.checkbox,
|
|
255
|
+
defaultValue: optsDefault.isAllowAND,
|
|
256
|
+
},
|
|
257
|
+
{
|
|
258
|
+
id: "isAllowOR",
|
|
259
|
+
label: `autoriser "ou"`,
|
|
260
|
+
target: GeneratorOptionTarget.instruction,
|
|
261
|
+
type: GeneratorOptionType.checkbox,
|
|
262
|
+
defaultValue: optsDefault.isAllowOR,
|
|
263
|
+
},
|
|
264
|
+
{
|
|
265
|
+
id: "isAllowNOT",
|
|
266
|
+
label: `autoriser "non"`,
|
|
267
|
+
target: GeneratorOptionTarget.instruction,
|
|
268
|
+
type: GeneratorOptionType.checkbox,
|
|
269
|
+
defaultValue: optsDefault.isAllowNOT,
|
|
270
|
+
},
|
|
271
|
+
];
|
|
272
|
+
export const scratchCond1 = {
|
|
273
|
+
id: "scratchCond1",
|
|
274
|
+
connector: "=",
|
|
275
|
+
label: "Utiliser une condition en Scratch",
|
|
276
|
+
isSingleStep: true,
|
|
277
|
+
generator: (nb, opts) => getDistinctQuestions(() => getScratchCond1Question(opts), nb),
|
|
278
|
+
options,
|
|
279
|
+
qcmTimer: 60,
|
|
280
|
+
freeTimer: 60,
|
|
281
|
+
getPropositions,
|
|
282
|
+
isAnswerValid,
|
|
283
|
+
subject: "Mathématiques",
|
|
284
|
+
getInstruction,
|
|
285
|
+
getHint,
|
|
286
|
+
getCorrection,
|
|
287
|
+
getAnswer,
|
|
288
|
+
getQuestionFromIdentifiers,
|
|
289
|
+
hasHintAndCorrection: true,
|
|
290
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Exercise } from "../../../exercises/exercise.js";
|
|
2
|
+
type Identifiers = {
|
|
3
|
+
xStart: number;
|
|
4
|
+
params: number[][];
|
|
5
|
+
arrIsUseFunc: boolean[];
|
|
6
|
+
};
|
|
7
|
+
export declare const scratchFunction1: Exercise<Identifiers>;
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=scratchFunction1.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scratchFunction1.d.ts","sourceRoot":"","sources":["../../../../src/exercises/math/scratch/scratchFunction1.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAeT,MAAM,6BAA6B,CAAC;AAQrC,KAAK,WAAW,GAAG;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC;IACnB,YAAY,EAAE,OAAO,EAAE,CAAC;CACzB,CAAC;AAiNF,eAAO,MAAM,gBAAgB,EAAE,QAAQ,CAAC,WAAW,CAkBlD,CAAC"}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import { addValidProp, shuffleProps, tryToAddWrongProp, propWhile, } from "../../../exercises/exercise.js";
|
|
2
|
+
import { getDistinctQuestions } from "../../../exercises/utils/getDistinctQuestions.js";
|
|
3
|
+
import { numberVEA } from "../../../exercises/vea/numberVEA.js";
|
|
4
|
+
import { randint } from "../../../math/utils/random/randint.js";
|
|
5
|
+
import { probaFlip } from "../../../utils/alea/probaFlip.js";
|
|
6
|
+
import { randomMany } from "../../../utils/alea/random.js";
|
|
7
|
+
import { handleVEAError } from "../../../utils/errors/handleVEAError.js";
|
|
8
|
+
const getInstruction = (identifiers) => {
|
|
9
|
+
const { xStart, params, arrIsUseFunc } = identifiers;
|
|
10
|
+
return `On considère le programme Scratch ci-dessous :
|
|
11
|
+
|
|
12
|
+
<svg id="scratch">
|
|
13
|
+
définir mystère (a) (b)
|
|
14
|
+
si <(x) \\< (a)> alors
|
|
15
|
+
mettre [x v] à (a)
|
|
16
|
+
fin
|
|
17
|
+
si <(x) > (b)> alors
|
|
18
|
+
mettre [x v] à (b)
|
|
19
|
+
fin
|
|
20
|
+
quand @greenFlag est cliqué
|
|
21
|
+
mettre [x v] à [${xStart}]
|
|
22
|
+
${arrIsUseFunc.map((isUseFunc, i) => {
|
|
23
|
+
if (isUseFunc) {
|
|
24
|
+
return `mystère [${params[i][0]}] [${params[i][1]}]`;
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
return `ajouter [${params[i][0]}] à [x v]`;
|
|
28
|
+
}
|
|
29
|
+
}).join(`
|
|
30
|
+
`)}
|
|
31
|
+
</svg>
|
|
32
|
+
|
|
33
|
+
Quelle est la valeur de $x$ à la fin de l'exécution du programme ?`;
|
|
34
|
+
};
|
|
35
|
+
const getFunctionForScratchProgram = (identifiers) => {
|
|
36
|
+
const { xStart, params, arrIsUseFunc } = identifiers;
|
|
37
|
+
return (_) => {
|
|
38
|
+
const outDict = {};
|
|
39
|
+
//init
|
|
40
|
+
let x = xStart;
|
|
41
|
+
outDict[0] = {
|
|
42
|
+
x,
|
|
43
|
+
};
|
|
44
|
+
//cond
|
|
45
|
+
arrIsUseFunc.forEach((isUseFunc, i) => {
|
|
46
|
+
if (isUseFunc) {
|
|
47
|
+
const [a, b] = params[i];
|
|
48
|
+
if (x < a) {
|
|
49
|
+
x = a;
|
|
50
|
+
}
|
|
51
|
+
if (x > b) {
|
|
52
|
+
x = b;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
x = x + params[i][0];
|
|
57
|
+
}
|
|
58
|
+
//store step dict
|
|
59
|
+
outDict[i + 1] = {
|
|
60
|
+
x,
|
|
61
|
+
};
|
|
62
|
+
});
|
|
63
|
+
//convenience: store last step in -1
|
|
64
|
+
outDict[-1] = outDict[Math.max(...Object.keys(outDict).map((k) => +k))];
|
|
65
|
+
return outDict;
|
|
66
|
+
};
|
|
67
|
+
};
|
|
68
|
+
const getAnswerNode = (identifiers) => {
|
|
69
|
+
return getFunctionForScratchProgram(identifiers)(identifiers)[-1].x.toTree();
|
|
70
|
+
};
|
|
71
|
+
const getAnswer = (identifiers) => {
|
|
72
|
+
return getAnswerNode(identifiers).toTex();
|
|
73
|
+
};
|
|
74
|
+
const getHint = () => {
|
|
75
|
+
return `Une fois que tu as compris ce que fait le bloc mystère, tu peux l'appliquer avec les paramètres fournis.
|
|
76
|
+
La valeur de la variable $x$ va évoluer tout au long du programme.`;
|
|
77
|
+
};
|
|
78
|
+
const getCorrection = (identifiers) => {
|
|
79
|
+
const { params, arrIsUseFunc } = identifiers;
|
|
80
|
+
const dictSteps = getFunctionForScratchProgram(identifiers)(identifiers);
|
|
81
|
+
return `Initialement, $x$ vaut $${dictSteps[0].x}$.
|
|
82
|
+
|
|
83
|
+
${arrIsUseFunc.map((isUseFunc, i) => {
|
|
84
|
+
const strInstruction = (() => {
|
|
85
|
+
if (isUseFunc) {
|
|
86
|
+
return `mystère($${params[i][0]}$, $${params[i][1]}$)`;
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
return `mettre $x$ à $${params[i][0]}$`;
|
|
90
|
+
}
|
|
91
|
+
})();
|
|
92
|
+
return `Suite à l'instruction
|
|
93
|
+
|
|
94
|
+
${strInstruction}
|
|
95
|
+
|
|
96
|
+
$x$ vaut $${dictSteps[i + 1].x}$.
|
|
97
|
+
`;
|
|
98
|
+
}).join(`
|
|
99
|
+
|
|
100
|
+
`)}
|
|
101
|
+
|
|
102
|
+
À la fin de l'exécution du programme, $x$ vaut donc $${dictSteps[-1].x}$.
|
|
103
|
+
`;
|
|
104
|
+
};
|
|
105
|
+
const getPropositions = (n, { answer, ...identifiers }) => {
|
|
106
|
+
const { xStart, arrIsUseFunc, params } = identifiers;
|
|
107
|
+
const propositions = [];
|
|
108
|
+
addValidProp(propositions, answer);
|
|
109
|
+
//wrong cond
|
|
110
|
+
{
|
|
111
|
+
const arrIsUseFuncWrong = arrIsUseFunc.reduce((acc, _) => {
|
|
112
|
+
return acc.flatMap((arr) => [
|
|
113
|
+
[...arr, true],
|
|
114
|
+
[...arr, false],
|
|
115
|
+
]);
|
|
116
|
+
}, [[]]);
|
|
117
|
+
arrIsUseFuncWrong.forEach((arrIsUseFunc) => {
|
|
118
|
+
const identifiersWrong = Object.assign({}, identifiers, { arrIsUseFunc });
|
|
119
|
+
const texWrong = getAnswer(identifiersWrong);
|
|
120
|
+
tryToAddWrongProp(propositions, texWrong);
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
//xStart
|
|
124
|
+
{
|
|
125
|
+
tryToAddWrongProp(propositions, xStart.frenchify());
|
|
126
|
+
}
|
|
127
|
+
//student does not want to think: a * b
|
|
128
|
+
{
|
|
129
|
+
const isLastInstructionUseFunc = arrIsUseFunc[arrIsUseFunc.length - 1];
|
|
130
|
+
if (isLastInstructionUseFunc) {
|
|
131
|
+
const [a, b] = params[params.length - 1];
|
|
132
|
+
tryToAddWrongProp(propositions, (a * b).frenchify());
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
propWhile(propositions, n, () => {
|
|
136
|
+
tryToAddWrongProp(propositions, randint(-20, 21).frenchify());
|
|
137
|
+
});
|
|
138
|
+
return shuffleProps(propositions, n);
|
|
139
|
+
};
|
|
140
|
+
const getKeys = () => {
|
|
141
|
+
return [];
|
|
142
|
+
};
|
|
143
|
+
const isAnswerValid = (ans, { answer }) => {
|
|
144
|
+
try {
|
|
145
|
+
return numberVEA(ans, answer);
|
|
146
|
+
}
|
|
147
|
+
catch (err) {
|
|
148
|
+
return handleVEAError(err);
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
const getScratchFunction1Question = () => {
|
|
152
|
+
const arrIsUseFunc = randomMany([0, 1, 2, 3], 3).map((i) => i % 2 === 0);
|
|
153
|
+
const params = arrIsUseFunc.map((isUseFunc) => isUseFunc
|
|
154
|
+
? (() => {
|
|
155
|
+
let a = randint(-22, 23);
|
|
156
|
+
let b = randint(-22, 23);
|
|
157
|
+
if (probaFlip(0.8)) {
|
|
158
|
+
[a, b] = [a, b].toSorted((a, b) => a - b);
|
|
159
|
+
}
|
|
160
|
+
return [a, b];
|
|
161
|
+
})()
|
|
162
|
+
: [randint(-10, 11)]);
|
|
163
|
+
const xStart = randint(-10, 11);
|
|
164
|
+
const identifiers = {
|
|
165
|
+
xStart,
|
|
166
|
+
arrIsUseFunc,
|
|
167
|
+
params,
|
|
168
|
+
};
|
|
169
|
+
return getQuestionFromIdentifiers(identifiers);
|
|
170
|
+
};
|
|
171
|
+
const getQuestionFromIdentifiers = (identifiers) => {
|
|
172
|
+
return {
|
|
173
|
+
answer: getAnswer(identifiers),
|
|
174
|
+
instruction: getInstruction(identifiers),
|
|
175
|
+
keys: getKeys(identifiers),
|
|
176
|
+
answerFormat: "tex",
|
|
177
|
+
identifiers,
|
|
178
|
+
hint: getHint(identifiers),
|
|
179
|
+
correction: getCorrection(identifiers),
|
|
180
|
+
};
|
|
181
|
+
};
|
|
182
|
+
export const scratchFunction1 = {
|
|
183
|
+
id: "scratchFunction1",
|
|
184
|
+
connector: "=",
|
|
185
|
+
label: "Utiliser un bloc personnalisé en Scratch",
|
|
186
|
+
isSingleStep: true,
|
|
187
|
+
generator: (nb, opts) => getDistinctQuestions(() => getScratchFunction1Question(opts), nb),
|
|
188
|
+
qcmTimer: 60,
|
|
189
|
+
freeTimer: 60,
|
|
190
|
+
getPropositions,
|
|
191
|
+
isAnswerValid,
|
|
192
|
+
subject: "Mathématiques",
|
|
193
|
+
getInstruction,
|
|
194
|
+
getHint,
|
|
195
|
+
getCorrection,
|
|
196
|
+
getAnswer,
|
|
197
|
+
getQuestionFromIdentifiers,
|
|
198
|
+
hasHintAndCorrection: true,
|
|
199
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Exercise } from "../../../exercises/exercise.js";
|
|
2
|
+
type Identifiers = {
|
|
3
|
+
xStart: number;
|
|
4
|
+
repeatCount: number;
|
|
5
|
+
offset1: number;
|
|
6
|
+
isFoolish: boolean;
|
|
7
|
+
};
|
|
8
|
+
export declare const scratchLoop1: Exercise<Identifiers>;
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=scratchLoop1.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scratchLoop1.d.ts","sourceRoot":"","sources":["../../../../src/exercises/math/scratch/scratchLoop1.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAeT,MAAM,6BAA6B,CAAC;AAOrC,KAAK,WAAW,GAAG;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;CACpB,CAAC;AAmNF,eAAO,MAAM,YAAY,EAAE,QAAQ,CAAC,WAAW,CAkB9C,CAAC"}
|