diff --git a/src/asy_library b/src/asy_library index c3b4c2b..cb9bc44 160000 --- a/src/asy_library +++ b/src/asy_library @@ -1 +1 @@ -Subproject commit c3b4c2b04ba03cad4ab8ff8cf2ea6199072a0ea2 +Subproject commit cb9bc442aed514cde57e69a67b2e0b13b6f1e914 diff --git a/src/fibonacci-primarie/2024-seconda-fase/contest/contest.mdx b/src/fibonacci-primarie/2024-seconda-fase/contest/contest.mdx new file mode 100644 index 0000000..9da9699 --- /dev/null +++ b/src/fibonacci-primarie/2024-seconda-fase/contest/contest.mdx @@ -0,0 +1,18 @@ + + +## Sezione 1: procedimenti procedurali + +
+ + +
+ +## Sezione 2: programmazione + +
+ + + +
+ +
diff --git a/src/fibonacci-primarie/2024-seconda-fase/contest/p-1-salto-ostacoli/code-alt.asy b/src/fibonacci-primarie/2024-seconda-fase/contest/p-1-salto-ostacoli/code-alt.asy new file mode 100644 index 0000000..9a2b36d --- /dev/null +++ b/src/fibonacci-primarie/2024-seconda-fase/contest/p-1-salto-ostacoli/code-alt.asy @@ -0,0 +1,52 @@ +access "../../../../asy_library/structures/layout.asy" as layout; + +unravel layout; // per evitare di scrivere layout.cose tutto il tempo + +unitsize(1cm); + +TEXT_SIZE = 2; +ALIGN = (0, 0.5); +BLOCK_PADDING = .3; + +element P = + row(2, 0, (0.5,0.5), + block_sequence( + start_block(e("Strategia 1")), + for_block( + block_content(e("ripeti mentre"), cond_block(data_block(e("posizione")), e("minore di"), data_block(e("traguardo"))), e(":")), + else_block( + block_content(e("se"), cond_block(e("pietra marrone"))), + block_sequence( + instr_block(element("salta")), + instr_block(element("salta")) + ), + block_content(e("altrimenti: ")), + instr_block(element("avanza")) + ) + ) + ), + block_sequence( + start_block(e("Strategia 2")), + for_block( + block_content(e("ripeti mentre"), cond_block(data_block(e("posizione")), e("minore di"), data_block(e("traguardo"))), e(":")), + instr_block(e("salta")) + ) + ), + block_sequence( + start_block(e("Strategia 3")), + for_block( + block_content(e("ripeti mentre"), cond_block(data_block(e("posizione")), e("minore di"), data_block(e("traguardo"))), e(":")), + else_block( + block_content(e("se"), cond_block(e("pietra marrone"))), + instr_block(element("salta")), + block_content(e("altrimenti: ")), + block_sequence( + instr_block(element("avanza")), + instr_block(element("avanza")) + ) + ) + ) + ) + ); + +add(P.drawing()); diff --git a/src/fibonacci-primarie/2024-seconda-fase/contest/p-1-salto-ostacoli/code.asy b/src/fibonacci-primarie/2024-seconda-fase/contest/p-1-salto-ostacoli/code.asy new file mode 100644 index 0000000..fb871f5 --- /dev/null +++ b/src/fibonacci-primarie/2024-seconda-fase/contest/p-1-salto-ostacoli/code.asy @@ -0,0 +1,24 @@ +access "../../../../asy_library/structures/layout.asy" as layout; + +unravel layout; // per evitare di scrivere layout.cose tutto il tempo + +unitsize(1cm); + +TEXT_SIZE = 2; +ALIGN = (0, 0.5); +BLOCK_PADDING = .3; + +element P = + block_sequence( + for_block( + block_content(e("ripeti mentre"), cond_block(data_block(e("posizione")), e("minore di"), data_block(e("traguardo"))), e(":")), + else_block( + block_content(e("se"), cond_block(e("pietra marrone"))), + instr_block(element("salta")), + block_content(e("altrimenti: ")), + instr_block(element("avanza")) + ) + ) + ); + +add(P.drawing()); diff --git a/src/fibonacci-primarie/2024-seconda-fase/contest/p-1-salto-ostacoli/fig.asy b/src/fibonacci-primarie/2024-seconda-fase/contest/p-1-salto-ostacoli/fig.asy new file mode 100644 index 0000000..91e7ec6 --- /dev/null +++ b/src/fibonacci-primarie/2024-seconda-fase/contest/p-1-salto-ostacoli/fig.asy @@ -0,0 +1,18 @@ +unitsize(1cm); + +access "../../../../asy_library/pictures/carrot.asy" as carrot; +access "../../../../asy_library/pictures/flat_rock.asy" as flat_rock; +access "../../../../asy_library/pictures/rock.asy" as rock; +access "../../../../asy_library/pictures/bunny_polychrome.asy" as bunny_polychrome; +access "../../../../asy_library/pictures/flag.asy" as flag; + +int[] rocks = {1, 0, 1, 2, 1, 1, 0, 1, 1, 2, 0, 0, 1, 1, 0, 2, 0, 0}; +picture[] pics = {flat_rock.drawing(0.5, gray), flat_rock.drawing(0.5, brown), shift(0,1)*rock.drawing(0.3,gray)}; + +for (int i=0; i Bunny cade sulla *grande roccia* in posizione $10$. +> +> Inizialmente si trova su una roccia marrone, e quindi salta arrivando in posizione $3$. +> Anche lì la roccia è marrone quindi salta di nuovo fino in posizione 5, e ancora una volta fino in posizione 7. +> A questo punto la roccia è grigia, e quindi avanza alla posizione 8. +> Ma dato che la roccia lì è marrone, salta cadendo direttamente sulla *grande roccia* in posizione $10$. +> +> ![primarie](primarie1.asy) +> ![secondarie](secondarie1.asy) + +--- + +Sempre nello stesso percorso ad ostacoli, Bunny vuole provare un po' di strategie diverse: + +![fig](fig.asy) + +![code](code-alt.asy) + +Quali di queste strategie gli consentono di raggiungere o superare il traguardo? + + +- [ ] la strategia 1 +- [ ] la strategia 2 +- [ ] la strategia 3 +- [x] le strategie 1 e 2 +- [ ] le strategie 2 e 3 + +> Funzionano entrambe le strategie 1 e 2. +> +> Nella strategia 2 Bunny salta sempre, toccando tutte le posizioni dispari e quindi evitando tutte le grandi rocce, +> che si trovano invece in posizioni pari, fino ad arrivare al traguardo in posizione $17$. +> +> Nella strategia 1, Bunny fa i salti a coppie: questo lo porta attraverso le posizioni $5$, $9$ e $13$, che hanno tutte +> la roccia marrone, per poi arrivare sul traguardo in posizione $17$ senza aver mai fatto avanza. +> +> Nella strategia 3, invece, Bunny cade sulla roccia $16$. +> Inizia saltando sulle rocce marroni in posizione $3$ e $5$ per arrivare alla posizione $7$. +> Da lì avanza due volte alla posizione $9$. +> A quel punto salta ancora alla posizione $11$, per poi avanzare due volte fino alla posizione $13$. +> Quindi salta in posizione $15$, e da lì avanza andando a scontrarsi contro la grande roccia. +> +> ![primarie](primarie2.asy) +> ![secondarie](secondarie2.asy) diff --git a/src/fibonacci-primarie/2024-seconda-fase/contest/p-1-salto-ostacoli/secondarie1.asy b/src/fibonacci-primarie/2024-seconda-fase/contest/p-1-salto-ostacoli/secondarie1.asy new file mode 100644 index 0000000..60528f1 --- /dev/null +++ b/src/fibonacci-primarie/2024-seconda-fase/contest/p-1-salto-ostacoli/secondarie1.asy @@ -0,0 +1,3 @@ +access "../../../../asy_library/structures/histogram.asy" as histogram; +unitsize(1cm); +add(histogram.drawing(scale(1.5)*"secondarie", new Label[]{"corretta", "vuota", "scorretta"}, new real[]{833, 14, 400})); diff --git a/src/fibonacci-primarie/2024-seconda-fase/contest/p-1-salto-ostacoli/secondarie2.asy b/src/fibonacci-primarie/2024-seconda-fase/contest/p-1-salto-ostacoli/secondarie2.asy new file mode 100644 index 0000000..f83b9a6 --- /dev/null +++ b/src/fibonacci-primarie/2024-seconda-fase/contest/p-1-salto-ostacoli/secondarie2.asy @@ -0,0 +1,3 @@ +access "../../../../asy_library/structures/histogram.asy" as histogram; +unitsize(1cm); +add(histogram.drawing(scale(1.5)*"secondarie", new Label[]{"corretta", "vuota", "scorretta"}, new real[]{629, 7, 611})); diff --git a/src/fibonacci-primarie/2024-seconda-fase/contest/p-2-spiedino/code.asy b/src/fibonacci-primarie/2024-seconda-fase/contest/p-2-spiedino/code.asy new file mode 100644 index 0000000..ae5470f --- /dev/null +++ b/src/fibonacci-primarie/2024-seconda-fase/contest/p-2-spiedino/code.asy @@ -0,0 +1,29 @@ +access "../../../../asy_library/structures/layout.asy" as layout; + +unravel layout; // per evitare di scrivere layout.cose tutto il tempo + +unitsize(1cm); + +TEXT_SIZE = 2; +ALIGN = (0, 0.5); + +element P = row( + BLOCK_PADDING, + fill_space=0, + block_sequence( + instr_block(element("imposta"), choice_block(e("valore")), element("a"), data_block(e("1"))), + instr_block(element("imposta"), choice_block(e("i")), element("a"), data_block(e("1"))), + for_block( + block_content(e("ripeti"), data_block(e("24")), e("volte:")), + block_sequence( + if_block( + block_content(e("se"), cond_block(data_block(e("cibo in posizione"), data_block(e("i"))), e("è diverso da"), data_block(e("cibo in posizione"), data_block(data_block(e("i")), e("+"), data_block(e("1")))))), + instr_block(e("aumenta"), choice_block(e("valore")), element("di"), data_block(e("1"))) + ), + instr_block(e("aumenta"), choice_block(e("i")), element("di"), data_block(e("1"))) + ) + ) + ) +); + +add(P.drawing()); diff --git a/src/fibonacci-primarie/2024-seconda-fase/contest/p-2-spiedino/fig.asy b/src/fibonacci-primarie/2024-seconda-fase/contest/p-2-spiedino/fig.asy new file mode 100644 index 0000000..00912f1 --- /dev/null +++ b/src/fibonacci-primarie/2024-seconda-fase/contest/p-2-spiedino/fig.asy @@ -0,0 +1,41 @@ +access "../../../../asy_library/pictures/bunny_polychrome.asy" as bunny_polychrome; +access "../../../../asy_library/pictures/apple.asy" as apple; +access "../../../../asy_library/pictures/banana.asy" as banana; +access "../../../../asy_library/pictures/strawberry.asy" as strawberry; +access "../../../../asy_library/pictures/watermelon.asy" as watermelon; +access "../../../../asy_library/pictures/tomato.asy" as tomato; +access "../../../../asy_library/pictures/carrot.asy" as carrot; +access "../../../../asy_library/pictures/potato.asy" as potato; +access "../../../../asy_library/pictures/eggplant.asy" as eggplant; + +path rect(pair a, pair b) { + return a -- (a.x,b.y) -- b -- (b.x,a.y) -- cycle; +} + + +unitsize(1cm); + +picture[] pics = { + apple.drawing(1.5), rotate(30)*banana.drawing(0.9), strawberry.drawing(), watermelon.drawing(0.9), + tomato.drawing(0.7), rotate(40)*carrot.drawing(0.5), rotate(30)*potato.drawing(0.8), eggplant.drawing(0.9) +}; + +for (int i=0; i Ragionando sul programma di Allie, si può vedere che con un ciclo percorre tutti i valori $i$ da $1$ a $24$, +> esaminando per ciascuno se i cibi nelle posizioni $i$ e $i+1$ sono diversi. In altre parole, Allie sta +> esaminando tutte le coppie di cibi vicini, contando quante sono diverse. Questo in pratica conta quanti +> diverse zone di frutta uguale ci sono sullo spiedino, che sono 8: +> +> 1. le due patate; +> 2. la mela; +> 3. le due carote; +> 4. le cinque fette di anguria; +> 5. le due melanzane; +> 6. le quattro fragole; +> 7. le due banane; e infine +> 8. i sette pomodori. +> +> ![primarie](primarie1.asy) +> ![secondarie](secondarie1.asy) + +--- + +Carol sta pensando che gli piacerebbe cambiare un po' il suo spiedino, di modo che il suo valore aumenti di $5$. +Quanti frutti dovrà modificare al minimo per ottenere questo risultato? + +- [ ] 2 +- [x] 3 +- [ ] 4 +- [ ] 5 +- [ ] 6 + +> Possiamo creare $5$ zone di frutta in più cambiando solo tre frutti. +> Con un singolo frutto possiamo spezzare una zona che sia lunga almeno tre per farla diventare tre zone. +> Questa cosa possiamo farla due volte per aumentare il valore di $4$, per esempio sostituendo +> una fetta di anguria nel mezzo con una patata e una delle fragole nel mezzo con una mela. +> +> A questo punto dobbiamo ancora aumentare il valore di $1$. Questo possiamo farlo sostituendo un cibo +> alla fine della zona con un'altro diverso: per esempio sostituendo una banana con una carota. +> Questo sarebbe il risultato finale: +> +> ![soluzione](sol.asy) +> +> ![primarie](primarie2.asy) +> ![secondarie](secondarie2.asy) diff --git a/src/fibonacci-primarie/2024-seconda-fase/contest/p-2-spiedino/secondarie1.asy b/src/fibonacci-primarie/2024-seconda-fase/contest/p-2-spiedino/secondarie1.asy new file mode 100644 index 0000000..84d1c86 --- /dev/null +++ b/src/fibonacci-primarie/2024-seconda-fase/contest/p-2-spiedino/secondarie1.asy @@ -0,0 +1,3 @@ +access "../../../../asy_library/structures/histogram.asy" as histogram; +unitsize(1cm); +add(histogram.drawing(scale(1.5)*"secondarie", new Label[]{"corretta", "vuota", "scorretta"}, new real[]{539, 98, 610})); diff --git a/src/fibonacci-primarie/2024-seconda-fase/contest/p-2-spiedino/secondarie2.asy b/src/fibonacci-primarie/2024-seconda-fase/contest/p-2-spiedino/secondarie2.asy new file mode 100644 index 0000000..2e7b83b --- /dev/null +++ b/src/fibonacci-primarie/2024-seconda-fase/contest/p-2-spiedino/secondarie2.asy @@ -0,0 +1,3 @@ +access "../../../../asy_library/structures/histogram.asy" as histogram; +unitsize(1cm); +add(histogram.drawing(scale(1.5)*"secondarie", new Label[]{"corretta", "vuota", "scorretta"}, new real[]{321, 172, 754})); diff --git a/src/fibonacci-primarie/2024-seconda-fase/contest/p-2-spiedino/sol.asy b/src/fibonacci-primarie/2024-seconda-fase/contest/p-2-spiedino/sol.asy new file mode 100644 index 0000000..b7f3aef --- /dev/null +++ b/src/fibonacci-primarie/2024-seconda-fase/contest/p-2-spiedino/sol.asy @@ -0,0 +1,45 @@ +access "../../../../asy_library/pictures/bunny_polychrome.asy" as bunny_polychrome; +access "../../../../asy_library/pictures/apple.asy" as apple; +access "../../../../asy_library/pictures/banana.asy" as banana; +access "../../../../asy_library/pictures/strawberry.asy" as strawberry; +access "../../../../asy_library/pictures/watermelon.asy" as watermelon; +access "../../../../asy_library/pictures/tomato.asy" as tomato; +access "../../../../asy_library/pictures/carrot.asy" as carrot; +access "../../../../asy_library/pictures/potato.asy" as potato; +access "../../../../asy_library/pictures/eggplant.asy" as eggplant; + +path rect(pair a, pair b) { + return a -- (a.x,b.y) -- b -- (b.x,a.y) -- cycle; +} + + +unitsize(1cm); + +picture[] pics = { + apple.drawing(1.5), rotate(30)*banana.drawing(0.9), strawberry.drawing(), watermelon.drawing(0.9), + tomato.drawing(0.7), rotate(40)*carrot.drawing(0.5), rotate(30)*potato.drawing(0.8), eggplant.drawing(0.9) +}; + +for (int i=0; i + +> Un possibile programma corretto è il seguente: +> +> ![soluzione](code.png) +> +> Secondo questo programma, per ognuno degli $N$ cibi che Tip-Tap vuole mangiare, il protagonista +> controlla se il prossimo cibo è una verdura, e in caso affermativo la cuoce prima di mangiarla. +> A questo punto mangia il prossimo cibo (che sia verdura o frutta), che sarà di suo gradimento: +> verdura cotta o frutta cruda. +> +> ![primarie](primarie.asy) +> ![secondarie](secondarie.asy) diff --git a/src/fibonacci-primarie/2024-seconda-fase/contest/s-1-pranzo/s1.blocks.yaml b/src/fibonacci-primarie/2024-seconda-fase/contest/s-1-pranzo/s1.blocks.yaml new file mode 100644 index 0000000..8b42e1b --- /dev/null +++ b/src/fibonacci-primarie/2024-seconda-fase/contest/s-1-pranzo/s1.blocks.yaml @@ -0,0 +1,100 @@ +- type: start + message0: inizia qui + nextStatement: null + colour: 20 + tooltip: L'esecuzione inizia da qui + helpUrl: "" + maxInstances: 1 + js: "" + +- type: N + message0: N + output: Number + colour: 20 + tooltip: numero di cibi in fila + helpUrl: "" + js: state.N + +- type: prossimo cibo + message0: prossimo cibo + output: String + colour: 20 + tooltip: il prossimo cibo in fila + helpUrl: "" + js: | + state.pos < state.N ? state.queue[state.pos] : exit(false, "il cibo è finito") + +- type: è una verdura + message0: "%1 è una verdura" + args0: + - type: input_value + check: String + output: Boolean + colour: 20 + tooltip: se il cibo dato è una verdura + helpUrl: "" + js: | + (function(x) { + food = x.split(" ")[0]; + if (food in state.food_types) + return state.food_types[food] === "verdura"; + exit(false, "non conosco il cibo " + x); + })(%1) + +- type: cuoci + message0: cuoci %1 + args0: + - type: input_value + check: String + previousStatement: null + nextStatement: null + colour: 20 + tooltip: cuoci il cibo dato + helpUrl: "" + js: | + (function(x) { + if (state.pos >= state.N) + exit(false, "hai finito il cibo"); + if (state.queue[state.pos] !== x) + exit(false, "questo non è il prossimo cibo"); + if (state.queue[state.pos].split(" ").length > 1) + exit(false, "stai cuocendo un cibo già cotto"); + state.queue[state.pos] += " cotta"; + })(%1); + +- type: mangia + message0: mangia %1 + args0: + - type: input_value + check: String + previousStatement: null + nextStatement: null + colour: 20 + tooltip: mangia il cibo dato + helpUrl: "" + js: | + (function(x) { + if (state.pos >= state.N) + exit(false, "hai finito il cibo"); + if (state.queue[state.pos] !== x) + exit(false, "questo non è il prossimo cibo"); + food = state.queue[state.pos].split(" "); + if (!(food[0] in state.food_types)) + exit(false, "non conosco il cibo " + food[0]); + if (state.food_types[food[0]] == "verdura" && food.length == 1) + exit(false, "a Tip-Tap non piace la verdura cruda"); + if (state.food_types[food[0]] == "frutta" && food.length > 1) + exit(false, "a Tip-Tap non piace la frutta cotta"); + state.pos += 1; + })(%1); + +- type: termina + message0: termina + previousStatement: null + colour: 20 + tooltip: smetti di mangiare + helpUrl: "" + js: | + if (state.pos < state.N) + exit(false, "non hai finito il cibo"); + exit(true, "hai finito tutto il cibo, complimenti!"); \ No newline at end of file diff --git a/src/fibonacci-primarie/2024-seconda-fase/contest/s-1-pranzo/secondarie.asy b/src/fibonacci-primarie/2024-seconda-fase/contest/s-1-pranzo/secondarie.asy new file mode 100644 index 0000000..173b6e8 --- /dev/null +++ b/src/fibonacci-primarie/2024-seconda-fase/contest/s-1-pranzo/secondarie.asy @@ -0,0 +1,3 @@ +access "../../../../asy_library/structures/histogram.asy" as histogram; +unitsize(1cm); +add(histogram.drawing(scale(1.5)*"secondarie", new Label[]{"0", "5", "10", "15", "20"}, new real[]{241, 361, 9, 3, 633})); diff --git a/src/fibonacci-primarie/2024-seconda-fase/contest/s-1-pranzo/sol.png b/src/fibonacci-primarie/2024-seconda-fase/contest/s-1-pranzo/sol.png new file mode 100644 index 0000000..7437e69 Binary files /dev/null and b/src/fibonacci-primarie/2024-seconda-fase/contest/s-1-pranzo/sol.png differ diff --git a/src/fibonacci-primarie/2024-seconda-fase/contest/s-1-pranzo/testcases.py b/src/fibonacci-primarie/2024-seconda-fase/contest/s-1-pranzo/testcases.py new file mode 100644 index 0000000..8213e7e --- /dev/null +++ b/src/fibonacci-primarie/2024-seconda-fase/contest/s-1-pranzo/testcases.py @@ -0,0 +1,21 @@ +import random +import json +random.seed(0) +testcases = [] +verdure = { + "carota": "verdura", + "patata": "verdura", + "melanzana": "verdura", +} +frutti = { + "mela": "frutta", + "banana": "frutta", + "fragola": "frutta", +} +food_types = {**verdure, **frutti} +type = [food_types, verdure, frutti, food_types] +N = [5, 10, 20, 40] +for t,n in zip(type,N): + queue = random.choices(list(t), k=n) + testcases.append({"food_types": food_types, "queue": queue, "pos": 0, "N": n}) +print(json.dumps(list(testcases))) diff --git a/src/fibonacci-primarie/2024-seconda-fase/contest/s-1-pranzo/visualizer.jsx b/src/fibonacci-primarie/2024-seconda-fase/contest/s-1-pranzo/visualizer.jsx new file mode 100644 index 0000000..6df73dc --- /dev/null +++ b/src/fibonacci-primarie/2024-seconda-fase/contest/s-1-pranzo/visualizer.jsx @@ -0,0 +1,54 @@ +"use client"; + +import { range } from "lodash-es"; + +import { Canvas, Sprite, Variables } from "~/utils/visualizer"; + +import bunny from "./asy/bunny.asy?w=66"; +import stoveOn from "./asy/fornello-acceso.asy?w=120"; +import stoveBack from "./asy/fornello-retro.asy?w=120"; +import stoveOff from "./asy/fornello-spento.asy?w=120"; + +const foods = import.meta.glob("./asy/cibo-*.asy", { + eager: true, + import: "default", + query: { w: 120 }, +}); + +export default function Visualizer({ variables, state }) { + function position(x, cook) { + if (x === -1) return [1.4, 1.3]; + if (cook) return [2.2, 1.5]; + return [0.5 * x + 2.4, 1.3]; + } + + return ( + <> + + + + {range(Math.max(state.pos - 1, 0), state.N).map((i) => { + const pos = position(i - state.pos, state.queue[i].endsWith(" cotta")); + return ( + + ); + })} + + + + + ); +} diff --git a/src/fibonacci-primarie/2024-seconda-fase/contest/s-2-spesa/asy/adulto.asy b/src/fibonacci-primarie/2024-seconda-fase/contest/s-2-spesa/asy/adulto.asy new file mode 100644 index 0000000..4833c3a --- /dev/null +++ b/src/fibonacci-primarie/2024-seconda-fase/contest/s-2-spesa/asy/adulto.asy @@ -0,0 +1,5 @@ +unitsize(1cm); + +access "../../../../../asy_library/pictures/bunny_polychrome.asy" as bunny; + +add(bunny.drawing(0.85, bunny.bunny_col)); diff --git a/src/fibonacci-primarie/2024-seconda-fase/contest/s-2-spesa/asy/bambino.asy b/src/fibonacci-primarie/2024-seconda-fase/contest/s-2-spesa/asy/bambino.asy new file mode 100644 index 0000000..718605a --- /dev/null +++ b/src/fibonacci-primarie/2024-seconda-fase/contest/s-2-spesa/asy/bambino.asy @@ -0,0 +1,5 @@ +unitsize(1cm); + +access "../../../../../asy_library/pictures/bunny_polychrome.asy" as bunny; + +add(yscale(0.6)*bunny.drawing(0.85, bunny.allie_col)); diff --git a/src/fibonacci-primarie/2024-seconda-fase/contest/s-2-spesa/asy/bunny.asy b/src/fibonacci-primarie/2024-seconda-fase/contest/s-2-spesa/asy/bunny.asy new file mode 100644 index 0000000..6e2b799 --- /dev/null +++ b/src/fibonacci-primarie/2024-seconda-fase/contest/s-2-spesa/asy/bunny.asy @@ -0,0 +1,5 @@ +unitsize(1cm); + +access "../../../../../asy_library/pictures/bunny_polychrome.asy" as bunny; + +add(reflect((2, 1), (2, 0))*bunny.drawing(0.85, bunny.carol_col)); diff --git a/src/fibonacci-primarie/2024-seconda-fase/contest/s-2-spesa/asy/carrot.asy b/src/fibonacci-primarie/2024-seconda-fase/contest/s-2-spesa/asy/carrot.asy new file mode 100644 index 0000000..a7c7642 --- /dev/null +++ b/src/fibonacci-primarie/2024-seconda-fase/contest/s-2-spesa/asy/carrot.asy @@ -0,0 +1,5 @@ +unitsize(1cm); + +access "../../../../../asy_library/pictures/carrot.asy" as carrot; + +add(carrot.drawing(0.12)); diff --git a/src/fibonacci-primarie/2024-seconda-fase/contest/s-2-spesa/code.png b/src/fibonacci-primarie/2024-seconda-fase/contest/s-2-spesa/code.png new file mode 100644 index 0000000..22d45cd Binary files /dev/null and b/src/fibonacci-primarie/2024-seconda-fase/contest/s-2-spesa/code.png differ diff --git a/src/fibonacci-primarie/2024-seconda-fase/contest/s-2-spesa/initial-blocks.json b/src/fibonacci-primarie/2024-seconda-fase/contest/s-2-spesa/initial-blocks.json new file mode 100644 index 0000000..6d41c25 --- /dev/null +++ b/src/fibonacci-primarie/2024-seconda-fase/contest/s-2-spesa/initial-blocks.json @@ -0,0 +1,19 @@ +{ + "blocks": { + "languageVersion": 0, + "blocks": [ + { + "type": "start", + "id": "y=zq)Uya2A/{vyOtN[i6", + "x": 61, + "y": 81 + } + ] + }, + "variables": [ + { + "name": "salto", + "id": "aL]BB^jjqL!cyI]38IpA" + } + ] +} diff --git a/src/fibonacci-primarie/2024-seconda-fase/contest/s-2-spesa/primarie.asy b/src/fibonacci-primarie/2024-seconda-fase/contest/s-2-spesa/primarie.asy new file mode 100644 index 0000000..b257346 --- /dev/null +++ b/src/fibonacci-primarie/2024-seconda-fase/contest/s-2-spesa/primarie.asy @@ -0,0 +1,3 @@ +access "../../../../asy_library/structures/histogram.asy" as histogram; +unitsize(1cm); +add(histogram.drawing(scale(1.5)*"primarie", new Label[]{"0", "5", "10", "15", "20"}, new real[]{343, 138, 13, 0, 12})); diff --git a/src/fibonacci-primarie/2024-seconda-fase/contest/s-2-spesa/question.mdx b/src/fibonacci-primarie/2024-seconda-fase/contest/s-2-spesa/question.mdx new file mode 100644 index 0000000..8999965 --- /dev/null +++ b/src/fibonacci-primarie/2024-seconda-fase/contest/s-2-spesa/question.mdx @@ -0,0 +1,39 @@ +import initialBlocks from "./initial-blocks.json"; +import customBlocks from "./s2.blocks.yaml"; +import testcases from "./testcases.py"; +import Visualizer from "./visualizer.jsx"; + +Carol è stata incaricata di distribuire carote ai suoi $N$ amici di fattoria. +I conigli, sia adulti che bambini, si sono quindi messi in fila e Carol deve dare 2 carote ad ogni adulto e una carota ad ogni bambino. +Per soddisfare le richieste di tutti, Carol può comprare dei pacchi da $K$ carote al costo di 1 euro. +Hai a disposizione questi blocchi: + +- `N`: il numero di amici di Carol. +- `K`: il numero di carote in un pacco. +- `coniglio adulto`: vero se il prossimo coniglio in fila è adulto. +- `dai` $x$ `carote`: consegna $x$ carote al prossimo coniglio in fila. +- `compra pacco di carote`: acquista un pacco di $K$ carote, al prezzo di 1 euro. +- `carote rimaste`: quante carote sono rimaste al momento a Carol. +- `termina`: smetti di consegnare carote. + +Aiuta Carol a distribuire le carote a tutti come previsto, spendendo meno possibile! + + + +> Un possibile programma corretto è il seguente: +> +> ![soluzione](code.png) +> +> Secondo questo programma, per ognuno degli $N$ amici in fila, il protagonista innanzitutto +> controlla se il prossimo coniglio è adulto. In caso affermativo, prima di dargli le due carote +> che gli spettano verifica di averne abbastanza, e se non fosse così ne compra un nuovo pacco. +> +> Se invece il prossimo coniglio è un bambino, anche in quel caso prima di dargli la carota che +> gli spetta controlla di averne almeno una, comprando un nuovo pacco se non fosse così. +> +> ![primarie](primarie.asy) diff --git a/src/fibonacci-primarie/2024-seconda-fase/contest/s-2-spesa/s2.blocks.yaml b/src/fibonacci-primarie/2024-seconda-fase/contest/s-2-spesa/s2.blocks.yaml new file mode 100644 index 0000000..96c7c6e --- /dev/null +++ b/src/fibonacci-primarie/2024-seconda-fase/contest/s-2-spesa/s2.blocks.yaml @@ -0,0 +1,90 @@ +- type: start + message0: inizia qui + nextStatement: null + colour: 20 + tooltip: L'esecuzione inizia da qui + helpUrl: "" + maxInstances: 1 + js: "" + +- type: N + message0: N + output: Number + colour: 20 + tooltip: numero di conigli in fila + helpUrl: "" + js: state.N + +- type: K + message0: K + output: Number + colour: 20 + tooltip: numero di carote in ogni pacco + helpUrl: "" + js: state.K + +- type: coniglio adulto + message0: coniglio adulto + output: Boolean + colour: 20 + tooltip: se il prossimo coniglio in fila è adulto + helpUrl: "" + js: | + state.queue[state.pos] === 2 + +- type: carote rimaste + message0: carote rimaste + output: Number + colour: 20 + tooltip: quante carote sono rimaste al momento a Carol + helpUrl: "" + js: | + state.carrots + +- type: dai carote + message0: dai %1 carote + args0: + - type: input_value + check: Integer + min: "0" + previousStatement: null + nextStatement: null + colour: 20 + tooltip: consegna carote al prossimo coniglio in fila + helpUrl: "" + js: | + (function(i) { + if (state.pos >= state.N) + exit(false, "non ci sono più conigli in fila"); + if (i > state.carrots) + exit(false, "non hai " + i + " carote da dare"); + state.carrots -= i; + state.wealth[state.pos] += i; + state.pos++; + if (state.queue[state.pos-1] !== i) + exit(false, "hai dato " + i + " carote ma dovevi darne " + state.queue[state.pos-1]); + })(%1); + +- type: compra pacco di carote + message0: compra pacco di carote + previousStatement: null + nextStatement: null + colour: 20 + tooltip: acquista un pacco di carote per 1 euro + helpUrl: "" + js: | + state.carrots += state.K; + state.cost++; + +- type: termina + message0: termina + previousStatement: null + colour: 20 + tooltip: smetti di consegnare carote + helpUrl: "" + js: | + if (state.pos < state.N) + exit(false, "non hai finito la fila"); + if (state.cost > state.sol) + exit(false, "potevi spendere meno soldi"); + exit(true, "hai distribuito le carote bene, complimenti!"); diff --git a/src/fibonacci-primarie/2024-seconda-fase/contest/s-2-spesa/testcases.py b/src/fibonacci-primarie/2024-seconda-fase/contest/s-2-spesa/testcases.py new file mode 100644 index 0000000..a97bd50 --- /dev/null +++ b/src/fibonacci-primarie/2024-seconda-fase/contest/s-2-spesa/testcases.py @@ -0,0 +1,12 @@ +import random +import json +random.seed(0) +testcases = [] +type = [[1,2], [1], [2], [1,2]] +N = [6, 10, 20, 40] +K = [2, 3, 5, 7] +for t,n,k in zip(type,N,K): + queue = [2, 1, 2, 2, 2, 1] if n == 6 else random.choices(t, k=n) + sol = (sum(queue) + k-1) // k + testcases.append({"N": n, "K": k, "queue": queue, "wealth": [0 for _ in range(n)], "sol": sol, "pos": 0, "carrots": 0, "cost": 0}) +print(json.dumps(list(testcases))) diff --git a/src/fibonacci-primarie/2024-seconda-fase/contest/s-2-spesa/visualizer.jsx b/src/fibonacci-primarie/2024-seconda-fase/contest/s-2-spesa/visualizer.jsx new file mode 100644 index 0000000..cf8ace0 --- /dev/null +++ b/src/fibonacci-primarie/2024-seconda-fase/contest/s-2-spesa/visualizer.jsx @@ -0,0 +1,47 @@ +"use client"; + +import { range } from "lodash-es"; + +import { Canvas, Sprite, Variables } from "~/utils/visualizer"; + +import adulto from "./asy/adulto.asy?w=80"; +import bambino from "./asy/bambino.asy?w=70"; +import bunny from "./asy/bunny.asy?w=80"; +import carrot from "./asy/carrot.asy?w=35"; + +export default function Visualizer({ variables, state }) { + let nc = 0; + return ( + <> + + {range(state.N).flatMap((i) => ( + = state.pos ? 30 + (i - state.pos) * 9 : 17 + (i - state.pos) * 6} + y={4.8} + /> + ))} + {range(state.N).flatMap((i) => { + return range(state.wealth[i]).map((j) => ( + + )); + })} + + {range(state.carrots).map((i) => { + const x = 25 + i * 1.5; + const y = 0; + return ; + })} + + + + ); +} diff --git a/src/fibonacci-primarie/2024-seconda-fase/contest/s-3-corridoio/asy/bulb-off.asy b/src/fibonacci-primarie/2024-seconda-fase/contest/s-3-corridoio/asy/bulb-off.asy new file mode 100644 index 0000000..b62767d --- /dev/null +++ b/src/fibonacci-primarie/2024-seconda-fase/contest/s-3-corridoio/asy/bulb-off.asy @@ -0,0 +1,5 @@ +unitsize(1cm); + +access "../../../../../asy_library/pictures/lightbulb.asy" as lightbulb; + +add(rotate(180)*lightbulb.drawing(1, gray)); diff --git a/src/fibonacci-primarie/2024-seconda-fase/contest/s-3-corridoio/asy/bulb-on.asy b/src/fibonacci-primarie/2024-seconda-fase/contest/s-3-corridoio/asy/bulb-on.asy new file mode 100644 index 0000000..7ae9a40 --- /dev/null +++ b/src/fibonacci-primarie/2024-seconda-fase/contest/s-3-corridoio/asy/bulb-on.asy @@ -0,0 +1,5 @@ +unitsize(1cm); + +access "../../../../../asy_library/pictures/lightbulb.asy" as lightbulb; + +add(rotate(180)*lightbulb.drawing(1, yellow)); diff --git a/src/fibonacci-primarie/2024-seconda-fase/contest/s-3-corridoio/asy/bunny-left.asy b/src/fibonacci-primarie/2024-seconda-fase/contest/s-3-corridoio/asy/bunny-left.asy new file mode 100644 index 0000000..4833c3a --- /dev/null +++ b/src/fibonacci-primarie/2024-seconda-fase/contest/s-3-corridoio/asy/bunny-left.asy @@ -0,0 +1,5 @@ +unitsize(1cm); + +access "../../../../../asy_library/pictures/bunny_polychrome.asy" as bunny; + +add(bunny.drawing(0.85, bunny.bunny_col)); diff --git a/src/fibonacci-primarie/2024-seconda-fase/contest/s-3-corridoio/asy/bunny-right.asy b/src/fibonacci-primarie/2024-seconda-fase/contest/s-3-corridoio/asy/bunny-right.asy new file mode 100644 index 0000000..f8f6fe5 --- /dev/null +++ b/src/fibonacci-primarie/2024-seconda-fase/contest/s-3-corridoio/asy/bunny-right.asy @@ -0,0 +1,5 @@ +unitsize(1cm); + +access "../../../../../asy_library/pictures/bunny_polychrome.asy" as bunny; + +add(reflect((2, 1), (2, 0))*bunny.drawing(0.85, bunny.bunny_col)); diff --git a/src/fibonacci-primarie/2024-seconda-fase/contest/s-3-corridoio/asy/closed-door.asy b/src/fibonacci-primarie/2024-seconda-fase/contest/s-3-corridoio/asy/closed-door.asy new file mode 100644 index 0000000..718ebfb --- /dev/null +++ b/src/fibonacci-primarie/2024-seconda-fase/contest/s-3-corridoio/asy/closed-door.asy @@ -0,0 +1,5 @@ +unitsize(1cm); + +access "../../../../../asy_library/pictures/diagonal_door.asy" as diagonal_door; + +add(diagonal_door.drawing(1.2, 0.2, false)); diff --git a/src/fibonacci-primarie/2024-seconda-fase/contest/s-3-corridoio/asy/opened-door.asy b/src/fibonacci-primarie/2024-seconda-fase/contest/s-3-corridoio/asy/opened-door.asy new file mode 100644 index 0000000..a24ce42 --- /dev/null +++ b/src/fibonacci-primarie/2024-seconda-fase/contest/s-3-corridoio/asy/opened-door.asy @@ -0,0 +1,5 @@ +unitsize(1cm); + +access "../../../../../asy_library/pictures/diagonal_door.asy" as diagonal_door; + +add(diagonal_door.drawing(1.2, 0.6)); diff --git a/src/fibonacci-primarie/2024-seconda-fase/contest/s-3-corridoio/asy/switch-off-off.asy b/src/fibonacci-primarie/2024-seconda-fase/contest/s-3-corridoio/asy/switch-off-off.asy new file mode 100644 index 0000000..bbf4f66 --- /dev/null +++ b/src/fibonacci-primarie/2024-seconda-fase/contest/s-3-corridoio/asy/switch-off-off.asy @@ -0,0 +1,5 @@ +unitsize(1cm); + +access "../../../../../asy_library/pictures/switch.asy" as switch; + +add(reflect((0, 0), (1, 0))*switch.drawing(1, mediumgray, gray(0.35))); diff --git a/src/fibonacci-primarie/2024-seconda-fase/contest/s-3-corridoio/asy/switch-off-on.asy b/src/fibonacci-primarie/2024-seconda-fase/contest/s-3-corridoio/asy/switch-off-on.asy new file mode 100644 index 0000000..ecac4f5 --- /dev/null +++ b/src/fibonacci-primarie/2024-seconda-fase/contest/s-3-corridoio/asy/switch-off-on.asy @@ -0,0 +1,5 @@ +unitsize(1cm); + +access "../../../../../asy_library/pictures/switch.asy" as switch; + +add(switch.drawing(1, mediumgray, gray(0.35))); diff --git a/src/fibonacci-primarie/2024-seconda-fase/contest/s-3-corridoio/asy/switch-on-off.asy b/src/fibonacci-primarie/2024-seconda-fase/contest/s-3-corridoio/asy/switch-on-off.asy new file mode 100644 index 0000000..983427f --- /dev/null +++ b/src/fibonacci-primarie/2024-seconda-fase/contest/s-3-corridoio/asy/switch-on-off.asy @@ -0,0 +1,5 @@ +unitsize(1cm); + +access "../../../../../asy_library/pictures/switch.asy" as switch; + +add(reflect((0, 0), (1, 0))*switch.drawing(1)); diff --git a/src/fibonacci-primarie/2024-seconda-fase/contest/s-3-corridoio/asy/switch-on-on.asy b/src/fibonacci-primarie/2024-seconda-fase/contest/s-3-corridoio/asy/switch-on-on.asy new file mode 100644 index 0000000..e6c97ba --- /dev/null +++ b/src/fibonacci-primarie/2024-seconda-fase/contest/s-3-corridoio/asy/switch-on-on.asy @@ -0,0 +1,5 @@ +unitsize(1cm); + +access "../../../../../asy_library/pictures/switch.asy" as switch; + +add(switch.drawing(1)); diff --git a/src/fibonacci-primarie/2024-seconda-fase/contest/s-3-corridoio/code.png b/src/fibonacci-primarie/2024-seconda-fase/contest/s-3-corridoio/code.png new file mode 100644 index 0000000..394dec9 Binary files /dev/null and b/src/fibonacci-primarie/2024-seconda-fase/contest/s-3-corridoio/code.png differ diff --git a/src/fibonacci-primarie/2024-seconda-fase/contest/s-3-corridoio/initial-blocks.json b/src/fibonacci-primarie/2024-seconda-fase/contest/s-3-corridoio/initial-blocks.json new file mode 100644 index 0000000..64bd836 --- /dev/null +++ b/src/fibonacci-primarie/2024-seconda-fase/contest/s-3-corridoio/initial-blocks.json @@ -0,0 +1,14 @@ +{ + "blocks": { + "languageVersion": 0, + "blocks": [ + { + "type": "start", + "id": "y=zq)Uya2A/{vyOtN[i6", + "x": 61, + "y": 81 + } + ] + }, + "variables": [] +} diff --git a/src/fibonacci-primarie/2024-seconda-fase/contest/s-3-corridoio/primarie.asy b/src/fibonacci-primarie/2024-seconda-fase/contest/s-3-corridoio/primarie.asy new file mode 100644 index 0000000..6d2a9a6 --- /dev/null +++ b/src/fibonacci-primarie/2024-seconda-fase/contest/s-3-corridoio/primarie.asy @@ -0,0 +1,3 @@ +access "../../../../asy_library/structures/histogram.asy" as histogram; +unitsize(1cm); +add(histogram.drawing(scale(1.5)*"primarie", new Label[]{"0", "5", "10", "15", "20"}, new real[]{380, 117, 5, 2, 2})); diff --git a/src/fibonacci-primarie/2024-seconda-fase/contest/s-3-corridoio/question.mdx b/src/fibonacci-primarie/2024-seconda-fase/contest/s-3-corridoio/question.mdx new file mode 100644 index 0000000..e361461 --- /dev/null +++ b/src/fibonacci-primarie/2024-seconda-fase/contest/s-3-corridoio/question.mdx @@ -0,0 +1,53 @@ +import initialBlocks from "./initial-blocks.json"; +import customBlocks from "./s3.blocks.yaml"; +import testcases from "./testcases.py"; +import Visualizer from "./visualizer.jsx"; + +Bunny oggi è rimasto a studiare fino a tarda notte nella sua stanza, mentre i suoi amici hanno già iniziato a fare cena insieme intorno al fuoco in giardino. +Ora Bunny li vuole raggiungere, però c'è un problema: ha paura del buio, quindi non è disposto ad entrare in una stanza se prima non ne accende la luce. +D'altra parte, Bunny è anche molto attento all'ambiente e non vuole lasciare luci accese prima di uscire fuori... neanche quelle che i suoi amici hanno +dimenticato accese! + +La Fattoria Fibonacci è fatta da $N$ stanze disposte in fila, come un lungo corridoio, separate da porte e numerate $1$, $2$, $\ldots$, $N$. +L'esterno della fattoria viene rappresentato come la stanza numero zero. +In ogni stanza ci sono due interruttori, che servono per accendere le lampadine delle stanze a destra e a sinistra. +Il lampadario della prima stanza si può anche spegnere dall'esterno. +Quando un interruttore viene premuto, accende la lampadina se è spenta e la spegne se è accesa. +Hai a disposizione questi blocchi: + +- `N`: il numero di stanze. +- `stanza corrente`: il numero della stanza corrente, $0$ (esterno) oppure da $1$ a $N$ (stanze). +- `muovi a destra/sinistra`: spostati nella stanza a destra/sinistra della stanza corrente. +- `interruttore a destra/sinistra`: premi l'interruttore che comanda la stanza a destra/sinistra. +- `lampadina a destra/sinistra accesa`: vero se la lampadina nella stanza a destra/sinistra è accesa. +- `termina`: raggiungi i tuoi amici per la cena intorno al fuoco. + +Aiuta Bunny a spegnere le luci e raggiungere gli amici, senza trovarsi mai al buio! + + + +> Un possibile programma corretto è il seguente: +> +> ![soluzione](code.png) +> +> Come prima cosa, Bunny deve controllare che non siano rimaste luci accese sulla sua destra, e +> percorre quindi tutte le stanze andando a destra fino all'ultima stanza (numero $N$). +> Prima di andare a destra deve però controllare se la lampadina fosse spenta, +> accendendola quindi per evitare la sua paura del buio. +> +> Alla fine di questo primo ciclo, Bunny si troverà nell'ultima stanza della fattoria, e può +> cominciare a tornare indietro spegnendo le luci dietro di sè. Procede quindi con un altro ciclo +> in cui va a sinistra, come sempre controllando prima se la luce alla sua sinistra (dove vuole andare) +> è spenta, e in caso la accende. Dopo essersi spostato a sinistra, spegne la luce della stanza +> da cui è arrivato. +> +> Questo secondo ciclo termina quando Bunny è arrivato nella prima stanza della fattoria, avendo spento tutte +> le altre luci. Non dovrà quindi fare altro che uscire, spegnere la luce nella prima stanza e poi raggiungere i suoi amici! +> +> ![primarie](primarie.asy) +> ![secondarie](secondarie.asy) diff --git a/src/fibonacci-primarie/2024-seconda-fase/contest/s-3-corridoio/s3.blocks.yaml b/src/fibonacci-primarie/2024-seconda-fase/contest/s-3-corridoio/s3.blocks.yaml new file mode 100644 index 0000000..677a396 --- /dev/null +++ b/src/fibonacci-primarie/2024-seconda-fase/contest/s-3-corridoio/s3.blocks.yaml @@ -0,0 +1,112 @@ +- type: start + message0: inizia qui + nextStatement: null + colour: 20 + tooltip: L'esecuzione inizia da qui + helpUrl: "" + maxInstances: 1 + js: "" + +- type: N + message0: N + output: Number + colour: 20 + tooltip: numero di stanze + helpUrl: "" + js: state.N + +- type: stanza corrente + message0: stanza corrente + output: Number + colour: 20 + tooltip: il numero della stanza corrente, 0 (esterno) oppure da 1 a N (stanze) + helpUrl: "" + js: state.pos + +- type: muovi + message0: muovi a %1 + args0: + - type: field_dropdown + options: + - [destra, "1"] + - [sinistra, "-1"] + previousStatement: null + nextStatement: null + colour: 20 + tooltip: spostati nella stanza a destra/sinistra della stanza corrente + helpUrl: "" + js: | + (function(i) { + state.dir = i; + if (state.pos+i > state.N) + exit(false, "non c'è una stanza a destra"); + if (state.pos+i < 0) + exit(false, "non c'è una stanza a sinistra"); + door = state.pos + Math.min(0, i); + state.door[door] = true; + pause(); + state.pos += i; + pause(); + state.door[door] = false; + if (state.light[state.pos-1] === 0) + exit(false, "la stanza in cui sei arrivato è buia"); + })(parseInt(%1)); + +- type: interruttore + message0: interruttore a %1 + args0: + - type: field_dropdown + options: + - [destra, "1"] + - [sinistra, "-1"] + previousStatement: null + nextStatement: null + colour: 20 + tooltip: premi l'interruttore che comanda la stanza a destra/sinistra + helpUrl: "" + js: | + (function(i) { + state.dir = i; + if (state.pos+i > state.N) + exit(false, "non c'è una stanza a destra"); + if (state.pos+i < 1) + exit(false, "non c'è una stanza a sinistra"); + state.switch[2*state.pos-1+Math.max(i,0)] ^= 1; + state.light[state.pos+i-1] ^= 1; + })(parseInt(%1)); + +- type: lampadina accesa + message0: lampadina a %1 accesa + args0: + - type: field_dropdown + options: + - [destra, "1"] + - [sinistra, "-1"] + output: Boolean + colour: 20 + tooltip: vero se la lampadina nella stanza a destra/sinistra è accesa + helpUrl: "" + js: | + (function(i) { + state.dir = i; + if (state.pos+i > state.N) + exit(false, "non c'è una stanza a destra"); + if (state.pos+i < 1) + exit(false, "non c'è una stanza a sinistra"); + return state.light[state.pos+i-1] === 1; + })(parseInt(%1)) + +- type: termina + message0: termina + previousStatement: null + colour: 20 + tooltip: raggiungi i tuoi amici per la cena intorno al fuoco + helpUrl: "" + js: | + if (state.pos !== 0) + exit(false, "non sei arrivato all'esterno"); + for (i=0; i + + {range(state.N).map((i) => ( + +
+ {i + 1} +
+
+ ))} + {range(state.N).map((i) => ( + + ))} + {range(state.N * 2).map((i) => ( + 0 && state.light[Math.floor((i - 1) / 2)] + ? state.switch[i] + ? switchOnOn + : switchOnOff + : state.switch[i] + ? switchOffOn + : switchOffOff + } + alt="" + x={width * (0.5 * i + 0.75) - 1.5} + y={10} + /> + ))} + {range(state.N).map((i) => ( + + {state.door[i] ? ( + + ) : ( + + )} + + ))} + +
+ + + ); +} diff --git a/src/fibonacci-primarie/2024-seconda-fase/header.md b/src/fibonacci-primarie/2024-seconda-fase/header.md new file mode 100644 index 0000000..0e0174b --- /dev/null +++ b/src/fibonacci-primarie/2024-seconda-fase/header.md @@ -0,0 +1,33 @@ +# Giochi di Fibonacci 2024/2025 + +## Fase II - Scuole primarie + +Questa prova contiene _5 problemi_ da risolvere in _120 minuti_, ed è divisa in due parti: +- due problemi di interpretazione di **procedimenti procedurali** come programmi a blocchi, e +- tre problemi di **programmazione** tramite blocchi. + +In entrambe le parti i problemi sono ordinati per difficoltà crescente. +**Attento che la difficoltà è soggettiva!** Se stai passando tanto tempo cercando di risolvere un problema, prova a passare ad altri problemi e altre categorie! + +## Punteggio + +### Procedimenti procedurali + +Questi problemi comprendono _due domande_, valutate separatamente. +La prima domanda è **sempre più semplice**, e può aiutare a rispondere alla seconda domanda. +Le domande sono tutte a **scelta multipla** con 5 opzioni, di cui **solo una** è corretta. Il punteggio che puoi ottenere è: + +- 5 punti per una risposta _corretta_; +- 1 punto per una risposta _non data_; +- 0 punti per una risposta _sbagliata_. + +### Programmazione a blocchi + +Questi problemi richiedono di scrivere un **singolo** programma a blocchi, che viene valutato **contemporaneamente** su quattro diversi livelli. +Quindi attenzione che non puoi scrivere programmi diversi per i diversi livelli, ma uno solo! +Per ciascun problema e per ciascun livello, Il punteggio che puoi ottenere è: + +- 5 punti se il programma produce la risposta _corretta_; +- 0 punti se il programma produce una risposta _sbagliata_. + +Quindi ogni domanda a blocchi può valere fino a 20 punti in totale. diff --git a/src/fibonacci-primarie/2024-seconda-fase/page.jsx b/src/fibonacci-primarie/2024-seconda-fase/page.jsx new file mode 100644 index 0000000..f3eefd8 --- /dev/null +++ b/src/fibonacci-primarie/2024-seconda-fase/page.jsx @@ -0,0 +1,18 @@ +import { NoAuth } from "@olinfo/quizms/student"; + +import Statement from "./contest/contest.mdx"; +import Header from "./header.md"; + +export const metadata = { + title: "Giochi di Fibonacci 2024/2025 - Fase II - Scuole primarie", + description: "Seconda fase dei Giochi di Fibonacci 2024/2025 per le scuole primarie", +}; + +export default function App() { + return ( + +
+ + + ); +} diff --git a/src/fibonacci-primarie/page.jsx b/src/fibonacci-primarie/page.jsx index 3fffd47..e58483b 100644 --- a/src/fibonacci-primarie/page.jsx +++ b/src/fibonacci-primarie/page.jsx @@ -11,6 +11,7 @@ export const metadata = { }; const editions = [ + "2024 - Seconda fase", "2024 - Prima fase", "2023 - Seconda fase", "2023 - Seconda fase - Demo", diff --git a/src/fibonacci-secondarie/2024-seconda-fase/contest/contest.mdx b/src/fibonacci-secondarie/2024-seconda-fase/contest/contest.mdx new file mode 100644 index 0000000..5546f2f --- /dev/null +++ b/src/fibonacci-secondarie/2024-seconda-fase/contest/contest.mdx @@ -0,0 +1,18 @@ + + +## Sezione 1: procedimenti procedurali + +
+ + +
+ +## Sezione 2: programmazione + +
+ + + +
+ +
diff --git a/src/fibonacci-secondarie/2024-seconda-fase/contest/p-1-salto-ostacoli b/src/fibonacci-secondarie/2024-seconda-fase/contest/p-1-salto-ostacoli new file mode 120000 index 0000000..450f3e0 --- /dev/null +++ b/src/fibonacci-secondarie/2024-seconda-fase/contest/p-1-salto-ostacoli @@ -0,0 +1 @@ +../../../fibonacci-primarie/2024-seconda-fase/contest/p-1-salto-ostacoli \ No newline at end of file diff --git a/src/fibonacci-secondarie/2024-seconda-fase/contest/p-2-spiedino b/src/fibonacci-secondarie/2024-seconda-fase/contest/p-2-spiedino new file mode 120000 index 0000000..733ad7b --- /dev/null +++ b/src/fibonacci-secondarie/2024-seconda-fase/contest/p-2-spiedino @@ -0,0 +1 @@ +../../../fibonacci-primarie/2024-seconda-fase/contest/p-2-spiedino \ No newline at end of file diff --git a/src/fibonacci-secondarie/2024-seconda-fase/contest/s-1-pranzo b/src/fibonacci-secondarie/2024-seconda-fase/contest/s-1-pranzo new file mode 120000 index 0000000..ead255c --- /dev/null +++ b/src/fibonacci-secondarie/2024-seconda-fase/contest/s-1-pranzo @@ -0,0 +1 @@ +../../../fibonacci-primarie/2024-seconda-fase/contest/s-1-pranzo \ No newline at end of file diff --git a/src/fibonacci-secondarie/2024-seconda-fase/contest/s-3-corridoio b/src/fibonacci-secondarie/2024-seconda-fase/contest/s-3-corridoio new file mode 120000 index 0000000..b3ce03d --- /dev/null +++ b/src/fibonacci-secondarie/2024-seconda-fase/contest/s-3-corridoio @@ -0,0 +1 @@ +../../../fibonacci-primarie/2024-seconda-fase/contest/s-3-corridoio \ No newline at end of file diff --git a/src/fibonacci-secondarie/2024-seconda-fase/contest/s-4-percorso-incrementale/asy/bunny.asy b/src/fibonacci-secondarie/2024-seconda-fase/contest/s-4-percorso-incrementale/asy/bunny.asy new file mode 100644 index 0000000..20d015a --- /dev/null +++ b/src/fibonacci-secondarie/2024-seconda-fase/contest/s-4-percorso-incrementale/asy/bunny.asy @@ -0,0 +1,7 @@ +unitsize(1cm); + +access "../../../../../asy_library/pictures/bunny_polychrome.asy" as bunny; +access "../../../../../asy_library/pictures/paint_bucket.asy" as paint_bucket; + +add(reflect((2, 1), (2, 0))*bunny.drawing(1, bunny.allie_col)); +add(shift(5,-2)*paint_bucket.drawing(0.3)); diff --git a/src/fibonacci-secondarie/2024-seconda-fase/contest/s-4-percorso-incrementale/code.png b/src/fibonacci-secondarie/2024-seconda-fase/contest/s-4-percorso-incrementale/code.png new file mode 100644 index 0000000..c926d08 Binary files /dev/null and b/src/fibonacci-secondarie/2024-seconda-fase/contest/s-4-percorso-incrementale/code.png differ diff --git a/src/fibonacci-secondarie/2024-seconda-fase/contest/s-4-percorso-incrementale/initial-blocks.json b/src/fibonacci-secondarie/2024-seconda-fase/contest/s-4-percorso-incrementale/initial-blocks.json new file mode 100644 index 0000000..64bd836 --- /dev/null +++ b/src/fibonacci-secondarie/2024-seconda-fase/contest/s-4-percorso-incrementale/initial-blocks.json @@ -0,0 +1,14 @@ +{ + "blocks": { + "languageVersion": 0, + "blocks": [ + { + "type": "start", + "id": "y=zq)Uya2A/{vyOtN[i6", + "x": 61, + "y": 81 + } + ] + }, + "variables": [] +} diff --git a/src/fibonacci-secondarie/2024-seconda-fase/contest/s-4-percorso-incrementale/partial.png b/src/fibonacci-secondarie/2024-seconda-fase/contest/s-4-percorso-incrementale/partial.png new file mode 100644 index 0000000..9683be4 Binary files /dev/null and b/src/fibonacci-secondarie/2024-seconda-fase/contest/s-4-percorso-incrementale/partial.png differ diff --git a/src/fibonacci-secondarie/2024-seconda-fase/contest/s-4-percorso-incrementale/question.mdx b/src/fibonacci-secondarie/2024-seconda-fase/contest/s-4-percorso-incrementale/question.mdx new file mode 100644 index 0000000..381a0c3 --- /dev/null +++ b/src/fibonacci-secondarie/2024-seconda-fase/contest/s-4-percorso-incrementale/question.mdx @@ -0,0 +1,60 @@ +import initialBlocks from "./initial-blocks.json"; +import customBlocks from "./s4.blocks.yaml"; +import testcases from "./testcases.py"; +import Visualizer from "./visualizer.jsx"; + +Allie è stata incaricata da Carol di dipingere il muro della fattoria, formato da $N$ pareti quadrate numerate da $1$ a $N$. +Alcune pareti sono già colorate, mentre altre sono bianche. +Carol ha dato ad Allie un foglio con $M$ istruzioni di due tipi: +- **AVANZA**: passa alla parete successiva. +- **SALTA**: spostati in avanti (di almeno una casella) fino a che non trovi una parete bianca. + +Il modo di seguire queste istruzioni è però piuttosto complicato! Infatti, Allie deve seguire ripetutamente questi passi, per ogni $i$ da $1$ fino ad $M$: +1. Partire (o ripartire) dalla prima parete. +1. Seguire le prime $i$ istruzioni sul foglio. +1. Dipingere la parete su cui si ferma. + +Aiuta Allie a dipingere il muro della fattoria facendo in modo che il risultato finale sia quello desiderato da Carol! Hai a disposizione questi blocchi: + +- `N`: il numero di pareti. +- `M`: il numero di istruzioni. +- `l'istruzione attuale è salta/avanza`: vero se la prossima istruzione da eseguire è salta/avanza. +- `la parete corrente è bianca/colorata`: vero se la parete davanti a Allie è bianca/colorata. +- `colora la parete`: Allie colora la parete davanti a sé. +- `avanza`: Allie passa alla parete successiva. +- `prossima istruzione`: Allie passa all'istruzione successiva. +- `torna all'inizio`: Allie torna davanti alla prima parete, e ricomincia a leggere le istruzioni dalla prima. +- `termina`: Allie avvisa Carol che ha terminato il lavoro. + +**ATTENZIONE**: Allie non deve per forza eseguire tutto il complicato procedimento assegnatole da Carol: le basta fare in modo che il risultato finale sia lo stesso. +In particolare, per completare l'ultimo livello, Allie non deve mai tornare indietro (quindi non può usare l'azione `torna all'inizio`) ma deve comunque fare in modo che il muro sia dipinto come vuole Carol. + + + +> Un possibile programma che segue esattamente le istruzioni di Allie è il seguente: +> +> ![soluzione](partial.png) +> +> Per ogni $i$ da $1$ ad $M$, come prima cosa Carol esegue le prime $i$ istruzioni. +> Questo viene fatto con un ciclo che per $i$ volte esegue la prossima istruzione: +> avanza sempre di uno, e poi se l'istruzione è salta avanza ulteriormente finché +> Carol si trova su di una parete colorata. Terminato il ciclo, Carol colora la parete +> a cui è arrivata e poi riparte dall'inizio. +> +> Il procedimento indicato da Allie, tuttavia, non è molto efficiente! Carol può ottenere +> lo stesso risultato precedente senza mai tornare indietro, con questo programma: +> +> ![soluzione](code.png) +> +> L'idea in questo programma è dopo aver seguito le prime $i$ istruzioni e colorato l'ultima +> casella, se ripeto di nuovo le prime $i$ istruzioni, arrivo esattamente nello stesso punto +> in cui già mi trovo! L'unica differenza è se l'ultima istruzione era **SALTA**, perché in quel +> caso devo saltare anche la casella che ho appena colorato. Dopo aver fatto quello, posso +> semplicemente passare alla prossima istruzione senza ripartire dall'inizio. +> +> ![secondarie](secondarie.asy) diff --git a/src/fibonacci-secondarie/2024-seconda-fase/contest/s-4-percorso-incrementale/s4.blocks.yaml b/src/fibonacci-secondarie/2024-seconda-fase/contest/s-4-percorso-incrementale/s4.blocks.yaml new file mode 100644 index 0000000..c8a04a4 --- /dev/null +++ b/src/fibonacci-secondarie/2024-seconda-fase/contest/s-4-percorso-incrementale/s4.blocks.yaml @@ -0,0 +1,129 @@ +- type: start + message0: inizia qui + nextStatement: null + colour: 20 + tooltip: L'esecuzione inizia da qui + helpUrl: "" + maxInstances: 1 + js: | + function controlla_posizione() { + if(state.pos >= state.N) { + exit(false, "sei andato oltre l'ultima parete"); + } + } + function controlla_indice() { + if (state.i >= state.M) { + exit(false, "sei andato oltre l'ultima istruzione"); + } + } + function colore() { + controlla_posizione(); + return state.cols[state.pos]; + } + function colora() { + controlla_posizione(); + state.cols[state.pos] = "B"; + if (state.cols[state.pos] !== state.solution[state.pos]) + exit(false, "non dovevi colorare questa parete"); + } + function prossima_posizione() { + controlla_posizione(); + state.pos += 1; + } + function istruzione() { + controlla_indice(); + return state.instr[state.i]; + } + function prossima_istruzione() { + controlla_indice(); + state.i += 1; + } + +- type: N + message0: N + output: Number + colour: 20 + tooltip: il numero di pareti + helpUrl: "" + js: state.N + +- type: M + message0: M + output: Number + colour: 20 + tooltip: il numero di istruzioni + helpUrl: "" + js: state.M + +- type: istruzione corrente + message0: l'istruzione attuale è %1 + args0: + - type: field_dropdown + options: + - [avanza, "A"] + - [salta, "S"] + output: Boolean + colour: 20 + tooltip: CAMBIAMI + helpUrl: "" + js: istruzione() == "%1" + +- type: colore parete + message0: la parete corrente è %1 + args0: + - type: field_dropdown + options: + - [bianca, "W"] + - [colorata, "B"] + output: Boolean + colour: 20 + tooltip: controlla il colore della parete davanti ad Allie + js: colore() == "%1" + +- type: colora + message0: colora la parete + colour: 20 + previousStatement: null + nextStatement: null + tooltip: colora la parete davanti ad Allie + js: colora(); + +- type: avanza + message0: avanza + colour: 20 + previousStatement: null + nextStatement: null + tooltip: passa alla parete successiva + js: prossima_posizione(); + +- type: prossima istruzione + message0: prossima istruzione + colour: 20 + previousStatement: null + nextStatement: null + tooltip: passa all'istruzione successiva + js: prossima_istruzione(); + +- type: torna all'inizio + message0: torna all'inizio + colour: 20 + previousStatement: null + nextStatement: null + tooltip: torna alla prima parete e alla prima istruzione + js: | + if(state.must_optimize) { + exit(false, "non puoi tornare all'inizio in questo livello"); + } + state.pos = 0; + state.i = 0; + +- type: termina + message0: termina + previousStatement: null + colour: 20 + tooltip: termina il procedimento + js: | + for (i = 0; i < state.N; i++) + if (state.cols[i] !== state.solution[i]) + exit(false, "non hai colorato la parete " + (i+1) + " come voleva Carol"); + exit(true, "hai colorato bene le pareti, complimenti!"); diff --git a/src/fibonacci-secondarie/2024-seconda-fase/contest/s-4-percorso-incrementale/secondarie.asy b/src/fibonacci-secondarie/2024-seconda-fase/contest/s-4-percorso-incrementale/secondarie.asy new file mode 100644 index 0000000..c6cee37 --- /dev/null +++ b/src/fibonacci-secondarie/2024-seconda-fase/contest/s-4-percorso-incrementale/secondarie.asy @@ -0,0 +1,3 @@ +access "../../../../asy_library/structures/histogram.asy" as histogram; +unitsize(1cm); +add(histogram.drawing(scale(1.5)*"secondarie", new Label[]{"0", "5", "10", "15", "20"}, new real[]{678, 539, 4, 15, 11})); diff --git a/src/fibonacci-secondarie/2024-seconda-fase/contest/s-4-percorso-incrementale/testcases.py b/src/fibonacci-secondarie/2024-seconda-fase/contest/s-4-percorso-incrementale/testcases.py new file mode 100644 index 0000000..110d6bb --- /dev/null +++ b/src/fibonacci-secondarie/2024-seconda-fase/contest/s-4-percorso-incrementale/testcases.py @@ -0,0 +1,44 @@ +import random +import json +testcases = [ + dict(seed=1, N=6, M=2, instr=["S", "A"], cols=["W", "B", "W", "B", "W", "W"], all_white=False, must_optimize=False), + dict(seed=2, N=10, M=6, all_white=True, must_optimize=False), + dict(seed=3, N=30, M=10, all_white=False, must_optimize=False), + dict(seed=5, N=40, M=18, all_white=False, must_optimize=True), +] + +def solve(N, M, instr, cols): + res = cols[:] + for i in range(1, M+1): + pos = 0 + for j in range(i): + pos += 1 + if instr[j] == "S": + while(res[pos] == "B"): + pos += 1 + res[pos] = "B" + return res + +def gen_testcase(seed, N, M, all_white, must_optimize, cols=None, instr=None): + random.seed(seed) + if cols == None: + possible_cols = ["W"] if all_white else ["W", "B"] + cols = random.choices(possible_cols, k=N) + else: + assert(len(cols)==N) + if instr == None: + instr = random.choices(["A", "S"], k=M) + else: + assert(len(instr) == M) + return dict( + N=N, + M=M, + cols=cols, + instr=instr, + must_optimize=must_optimize, + solution=solve(N, M, instr, cols), + pos=0, + i=0, + ) + +print(json.dumps([gen_testcase(**testcase) for testcase in testcases])) diff --git a/src/fibonacci-secondarie/2024-seconda-fase/contest/s-4-percorso-incrementale/visualizer.jsx b/src/fibonacci-secondarie/2024-seconda-fase/contest/s-4-percorso-incrementale/visualizer.jsx new file mode 100644 index 0000000..de4a922 --- /dev/null +++ b/src/fibonacci-secondarie/2024-seconda-fase/contest/s-4-percorso-incrementale/visualizer.jsx @@ -0,0 +1,95 @@ +"use client"; + +import { range } from "lodash-es"; +import { Canvas, Rectangle, Sprite, Variables } from "~/utils/visualizer"; +import bunny from "./asy/bunny.asy?w=66"; + +class Random { + constructor(seed) { + this._seed = seed % 2147483647; + if (this._seed <= 0) this._seed += 2147483646; + } + next() { + this._seed = (this._seed * 16807) % 2147483647; + return this._seed; + } +} + +export default function Visualizer({ variables, state }) { + const cell_side = 20; + const cell_padding = 1; + const scale = 10; + const font_height = 4; + + const random = new Random(state.N); + const colors = ["orange", "lightgreen", "blue", "aquamarine", "yellow", "red"]; + const cell_color = range(state.N).map(() => colors[random.next() % colors.length]); + return ( + <> + + {range(state.N).map((i) => ( + + + {i + 1} + + + ))} + + + {range(state.M).map((i) => ( + +
+                {`${(state.M > 9) && (i + 1 < 10) ? " " : ""}${i + 1}. ${{ S: "SALTA", A: "AVANZA" }[state.instr[i]]}`}
+              
+
+ ))} +
+
+ + + ); +} diff --git a/src/fibonacci-secondarie/2024-seconda-fase/header.md b/src/fibonacci-secondarie/2024-seconda-fase/header.md new file mode 100644 index 0000000..0670e21 --- /dev/null +++ b/src/fibonacci-secondarie/2024-seconda-fase/header.md @@ -0,0 +1,33 @@ +# Giochi di Fibonacci 2024/2025 + +## Fase II - Scuole secondarie + +Questa prova contiene _5 problemi_ da risolvere in _120 minuti_, ed è divisa in due parti: +- due problemi di interpretazione di **procedimenti procedurali** come programmi a blocchi, e +- tre problemi di **programmazione** tramite blocchi. + +In entrambe le parti i problemi sono ordinati per difficoltà crescente. +**Attento che la difficoltà è soggettiva!** Se stai passando tanto tempo cercando di risolvere un problema, prova a passare ad altri problemi e altre categorie! + +## Punteggio + +### Procedimenti procedurali + +Questi problemi comprendono _due domande_, valutate separatamente. +La prima domanda è **sempre più semplice**, e può aiutare a rispondere alla seconda domanda. +Le domande sono tutte a **scelta multipla** con 5 opzioni, di cui **solo una** è corretta. Il punteggio che puoi ottenere è: + +- 5 punti per una risposta _corretta_; +- 1 punto per una risposta _non data_; +- 0 punti per una risposta _sbagliata_. + +### Programmazione a blocchi + +Questi problemi richiedono di scrivere un **singolo** programma a blocchi, che viene valutato **contemporaneamente** su quattro diversi livelli. +Quindi attenzione che non puoi scrivere programmi diversi per i diversi livelli, ma uno solo! +Per ciascun problema e per ciascun livello, Il punteggio che puoi ottenere è: + +- 5 punti se il programma produce la risposta _corretta_; +- 0 punti se il programma produce una risposta _sbagliata_. + +Quindi ogni domanda a blocchi può valere fino a 20 punti in totale. diff --git a/src/fibonacci-secondarie/2024-seconda-fase/page.jsx b/src/fibonacci-secondarie/2024-seconda-fase/page.jsx new file mode 100644 index 0000000..1d1668e --- /dev/null +++ b/src/fibonacci-secondarie/2024-seconda-fase/page.jsx @@ -0,0 +1,18 @@ +import { NoAuth } from "@olinfo/quizms/student"; + +import Statement from "./contest/contest.mdx"; +import Header from "./header.md"; + +export const metadata = { + title: "Giochi di Fibonacci 2024/2025 - Fase II - Scuole secondarie", + description: "Seconda fase dei Giochi di Fibonacci 2024/2025 per le scuole secondarie", +}; + +export default function App() { + return ( + +
+ + + ); +} diff --git a/src/fibonacci-secondarie/page.jsx b/src/fibonacci-secondarie/page.jsx index acc7f1b..c15cb9e 100644 --- a/src/fibonacci-secondarie/page.jsx +++ b/src/fibonacci-secondarie/page.jsx @@ -11,6 +11,7 @@ export const metadata = { }; const editions = [ + "2024 - Seconda fase", "2024 - Prima fase", "2023 - Terza fase", "2023 - Seconda fase",