úlohy na DP a prefixáky
This commit is contained in:
parent
1237d32514
commit
fe7d72429a
1 changed files with 51 additions and 38 deletions
89
tasks.json
89
tasks.json
|
@ -122,7 +122,7 @@
|
||||||
"title": "Životně důležitá úloha",
|
"title": "Životně důležitá úloha",
|
||||||
"position": [
|
"position": [
|
||||||
-90.7659363746643,
|
-90.7659363746643,
|
||||||
879.8850021362305
|
880.786247253418
|
||||||
],
|
],
|
||||||
"taskReference": "26-Z2-4",
|
"taskReference": "26-Z2-4",
|
||||||
"points": 12
|
"points": 12
|
||||||
|
@ -825,11 +825,12 @@
|
||||||
"kucharka-zakladni-dynamicke-programovani"
|
"kucharka-zakladni-dynamicke-programovani"
|
||||||
],
|
],
|
||||||
"position": [
|
"position": [
|
||||||
153.05905151367188,
|
-273.39971923828125,
|
||||||
506.2679748535156
|
1197.8036499023438
|
||||||
],
|
],
|
||||||
"title": "Čtyřková",
|
"title": "Čtyřková",
|
||||||
"points": 12
|
"points": 12,
|
||||||
|
"hidden": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "open-data",
|
"type": "open-data",
|
||||||
|
@ -1144,7 +1145,7 @@
|
||||||
"taskReference": "30-1-4",
|
"taskReference": "30-1-4",
|
||||||
"requires": [],
|
"requires": [],
|
||||||
"position": [
|
"position": [
|
||||||
2425.829833984375,
|
2427.345458984375,
|
||||||
1017.5477600097656
|
1017.5477600097656
|
||||||
],
|
],
|
||||||
"title": "Cesta v bunkru",
|
"title": "Cesta v bunkru",
|
||||||
|
@ -1169,10 +1170,12 @@
|
||||||
"type": "open-data",
|
"type": "open-data",
|
||||||
"id": "30-3-1",
|
"id": "30-3-1",
|
||||||
"taskReference": "30-3-1",
|
"taskReference": "30-3-1",
|
||||||
"requires": [],
|
"requires": [
|
||||||
|
"30-Z4-1"
|
||||||
|
],
|
||||||
"position": [
|
"position": [
|
||||||
2260.394287109375,
|
-513.2063903808594,
|
||||||
885.5089416503906
|
1192.0383605957031
|
||||||
],
|
],
|
||||||
"title": "Vlnění",
|
"title": "Vlnění",
|
||||||
"hidden": true,
|
"hidden": true,
|
||||||
|
@ -1182,13 +1185,15 @@
|
||||||
"type": "open-data",
|
"type": "open-data",
|
||||||
"id": "30-4-5",
|
"id": "30-4-5",
|
||||||
"taskReference": "30-4-5",
|
"taskReference": "30-4-5",
|
||||||
"requires": [],
|
"requires": [
|
||||||
|
"kucharka-zakladni-dynamicke-programovani"
|
||||||
|
],
|
||||||
"position": [
|
"position": [
|
||||||
2434.596923828125,
|
-376.9443664550781,
|
||||||
816.7156677246094
|
1235.2302551269531
|
||||||
],
|
],
|
||||||
"title": "Frňákovník",
|
"title": "Frňákovník",
|
||||||
"hidden": true,
|
"hidden": false,
|
||||||
"points": 10
|
"points": 10
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -1310,12 +1315,14 @@
|
||||||
"taskReference": "30-Z2-4",
|
"taskReference": "30-Z2-4",
|
||||||
"title": "Příliš bílý displej",
|
"title": "Příliš bílý displej",
|
||||||
"comment": " Práce s 2d polem",
|
"comment": " Práce s 2d polem",
|
||||||
"requires": [],
|
"requires": [
|
||||||
"position": [
|
"kucharka-zakladni-prefixove-soucty-2d"
|
||||||
-1553.5021209716797,
|
|
||||||
-1031.9203643798828
|
|
||||||
],
|
],
|
||||||
"hidden": true,
|
"position": [
|
||||||
|
-710.1918792724609,
|
||||||
|
1333.6874084472656
|
||||||
|
],
|
||||||
|
"hidden": false,
|
||||||
"points": 12
|
"points": 12
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -1381,12 +1388,14 @@
|
||||||
"taskReference": "30-Z4-1",
|
"taskReference": "30-Z4-1",
|
||||||
"title": "Statistika sprintů",
|
"title": "Statistika sprintů",
|
||||||
"comment": " Prefixové součty",
|
"comment": " Prefixové součty",
|
||||||
"requires": [],
|
"requires": [
|
||||||
"position": [
|
"kucharka-zakladni-prefixove-soucty"
|
||||||
-1586.7162628173828,
|
|
||||||
-1087.0154418945312
|
|
||||||
],
|
],
|
||||||
"hidden": true,
|
"position": [
|
||||||
|
-623.6291046142578,
|
||||||
|
1118.8409271240234
|
||||||
|
],
|
||||||
|
"hidden": false,
|
||||||
"points": 8
|
"points": 8
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -1435,13 +1444,15 @@
|
||||||
"type": "open-data",
|
"type": "open-data",
|
||||||
"id": "31-1-1",
|
"id": "31-1-1",
|
||||||
"taskReference": "31-1-1",
|
"taskReference": "31-1-1",
|
||||||
"requires": [],
|
"requires": [
|
||||||
|
"28-Z4-4"
|
||||||
|
],
|
||||||
"position": [
|
"position": [
|
||||||
2454.366792678833,
|
-280.69116020202637,
|
||||||
946.1978244781494
|
1289.7996921539307
|
||||||
],
|
],
|
||||||
"title": "Karkulčin byznys",
|
"title": "Karkulčin byznys",
|
||||||
"hidden": true,
|
"hidden": false,
|
||||||
"points": 12
|
"points": 12
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -2138,12 +2149,14 @@
|
||||||
"id": "kucharka-zakladni-dynamicke-programovani",
|
"id": "kucharka-zakladni-dynamicke-programovani",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"comment": "...",
|
"comment": "...",
|
||||||
"requires": [],
|
"requires": [
|
||||||
|
"kucharka-zakladni-prefixove-soucty"
|
||||||
|
],
|
||||||
"title": "Dynamické programování",
|
"title": "Dynamické programování",
|
||||||
"htmlContent": "<h3>Předpočítané mezivýsledky</h3><p>Motivací k této kapitole je následující motto: „Proč počítat něco vícekrát, když nám to stačí spočítat jednou a zapamatovat si to?“.</p><p>Velmi často se totiž setkáváme s tím, že něco počítáme stále dokola. Jako příklad si můžeme připomenout naši rekurzivní implementaci počítání Fibonacciho čísel zmíněnou výše.</p><p>Když se podíváme na výpočet čísla fib(5), vidíme, že pro něj voláme fib(4) a fib(3), fib(4) volá fib(3) a fib(2), fib(3) volá fib(2) a fib(1) a tak dále. Všimli jste si, kolikrát se nám tyhle výpočty opakují? Některá Fibonacciho čísla spočteme totiž zbytečně mnohokrát.</p><figure class=\"image\"><img src=\"https://ksp.mff.cuni.cz/kucharky/zakladni-algoritmy/zakladni_algoritmy-5.png\" alt=\"Strom výpočtu Fibonacciho čísla\"></figure><p>Kdybychom si je namísto opakovaného počítání někde pamatovali, mohli bychom pak odpověď na dotaz na již vypočtené číslo vytáhnout jako králíka z klobouku v konstantním čase. Zavedením jednoho globálního pole, ve kterém si tyto hodnoty pro jednotlivá n budeme pamatovat, nám sníží časovou složitost z O(2n) na pěkných O(n). Takovému postupu se obecně říká <i>dynamické programování</i>.</p><h4>Dynamické programování</h4><figure class=\"image\"><img src=\"https://ksp.mff.cuni.cz/img/hippo_dynamit.png\" alt=\"Dynamitské programování\"></figure><p>Nejprve uveďme na pravou váhu výraz „dynamické“ v názvu. Nevystihuje tak úplně podstatu této techniky a jeho historické pozadí je celkem složité, avšak dnes je tento název již tak zažitý, že se už pravděpodobně nezmění.</p><p>Slovo „dynamické“ částečně odkazuje na to, že se dynamicky (za běhu programu) postupně staví řešení jednodušších problémů, která jsou následně použita pro řešení složitějších. Jeho hlavní podstatou je tedy ukládání a opětovné použití již jednou vypočtených údajů.</p><p>Hodí se na úlohy, které se dají dělit na podúlohy, které jsou si podobné a mohou se opakovat. Výsledky takovýchto podúloh si poté ukládáme a při dotazu na stejnou podúlohu vrátíme jen uložený výsledek a výpočet již neprovádíme.</p><p>Pro další prohloubení znalostí můžete na našem webu nahlédnout do další kuchařky, tentokrát nesoucí (překvapivě) název <a href=\"https://ksp.mff.cuni.cz/viz/kucharky/dynamicke-programovani\">Dynamické programování</a>.</p>",
|
"htmlContent": "<h3>Předpočítané mezivýsledky</h3><p>Motivací k této kapitole je následující motto: „Proč počítat něco vícekrát, když nám to stačí spočítat jednou a zapamatovat si to?“.</p><p>Velmi často se totiž setkáváme s tím, že něco počítáme stále dokola. Jako příklad si můžeme připomenout naši rekurzivní implementaci počítání Fibonacciho čísel zmíněnou výše.</p><p>Když se podíváme na výpočet čísla fib(5), vidíme, že pro něj voláme fib(4) a fib(3), fib(4) volá fib(3) a fib(2), fib(3) volá fib(2) a fib(1) a tak dále. Všimli jste si, kolikrát se nám tyhle výpočty opakují? Některá Fibonacciho čísla spočteme totiž zbytečně mnohokrát.</p><figure class=\"image\"><img src=\"https://ksp.mff.cuni.cz/kucharky/zakladni-algoritmy/zakladni_algoritmy-5.png\" alt=\"Strom výpočtu Fibonacciho čísla\"></figure><p>Kdybychom si je namísto opakovaného počítání někde pamatovali, mohli bychom pak odpověď na dotaz na již vypočtené číslo vytáhnout jako králíka z klobouku v konstantním čase. Zavedením jednoho globálního pole, ve kterém si tyto hodnoty pro jednotlivá n budeme pamatovat, nám sníží časovou složitost z O(2n) na pěkných O(n). Takovému postupu se obecně říká <i>dynamické programování</i>.</p><h4>Dynamické programování</h4><figure class=\"image\"><img src=\"https://ksp.mff.cuni.cz/img/hippo_dynamit.png\" alt=\"Dynamitské programování\"></figure><p>Nejprve uveďme na pravou váhu výraz „dynamické“ v názvu. Nevystihuje tak úplně podstatu této techniky a jeho historické pozadí je celkem složité, avšak dnes je tento název již tak zažitý, že se už pravděpodobně nezmění.</p><p>Slovo „dynamické“ částečně odkazuje na to, že se dynamicky (za běhu programu) postupně staví řešení jednodušších problémů, která jsou následně použita pro řešení složitějších. Jeho hlavní podstatou je tedy ukládání a opětovné použití již jednou vypočtených údajů.</p><p>Hodí se na úlohy, které se dají dělit na podúlohy, které jsou si podobné a mohou se opakovat. Výsledky takovýchto podúloh si poté ukládáme a při dotazu na stejnou podúlohu vrátíme jen uložený výsledek a výpočet již neprovádíme.</p><p>Pro další prohloubení znalostí můžete na našem webu nahlédnout do další kuchařky, tentokrát nesoucí (překvapivě) název <a href=\"https://ksp.mff.cuni.cz/viz/kucharky/dynamicke-programovani\">Dynamické programování</a>.</p>",
|
||||||
"position": [
|
"position": [
|
||||||
105.5970230102539,
|
-332.6829147338867,
|
||||||
425.50379943847656
|
1135.6282806396484
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -2212,8 +2225,8 @@
|
||||||
"title": "Pole",
|
"title": "Pole",
|
||||||
"htmlContent": "<p>První datovou strukturou, kterou si představíme a která se na výše nastíněnou situaci náramně hodí, je <i>pole</i>. To představuje spoustu přihrádek (proměnných) naskládaných v paměti za sebou, ke kterým typicky přistupujeme přes jeden společný název pole a jejich pořadové číslo neboli index (jako NazevPole[0], NazevPole[1], …). (Pozor, ve světě počítačů se velmi často indexuje od nuly, tedy první prvek má v tomto případě index 0.)</p><p>Ve většině základních jazyků je pole jen <i>statické</i>, tedy v okamžiku jeho vytváření musíme počítači říct, jak ho chceme velké. Některé vyšší jazyky ale nabízejí i pole, které se dynamicky zvětšuje, takovou konstrukci si ukážeme ve druhé části kuchařky.</p><p>Abychom nebyli omezeni jen jedním rozměrem, můžeme si klidně vyrobit pole dvourozměrné (případně obecně n-rozměrné). Dvourozměrné pole je vlastně tabulka hodnot, nazýváme ji také někdy <i>matice</i>, a může se nám hodit například při reprezentaci různých map (plán bludiště) nebo, jak uvidíme níže, pro reprezentaci dalších datových struktur.</p><p>U pole již má smysl přemýšlet, jak dlouho bude která operace trvat. Díky tomu, že jsou jednotlivé prvky v poli naskládané pevně za sebou, je snadné spočítat umístění konkrétní přihrádky. Proto když se počítače zeptáme na obsah přihrády pole[42], vrátí nám hodnotu ihned.</p><figure class=\"image\"><img src=\"https://ksp.mff.cuni.cz/img/hippo_array.png\" alt=\"Pole\"></figure><p>Tomu budeme říkat <i>operace v konstantním čase</i> a budeme značit, že trvá čas O(1). Efektivitu programu totiž nepočítáme v sekundách (protože každý z nás má asi jinak rychlý počítač), ale v počtu základních operací, které musí program řádově vykonat. Více o časové složitosti si můžete přečíst v <a href=\"https://ksp.mff.cuni.cz/viz/kucharky/slozitost\">kuchařce o složitosti</a>, nejdříve však doporučujeme dočíst tuto kuchařku.</p><p>Přidání nového prvku na konec pole také zvládneme v konstantním čase. Problém je přidání nového prvku někam doprostřed (což se nám typicky stane, pokud budeme chtít udržovat hodnoty v poli seřazené a zároveň do něj vkládat nové). V takovém případě se totiž všechny prvky za vkládaným musí posunout o jednu pozici dál, aby se vkládaný prvek vešel na své místo. Taková operace tedy může pro pole délky N (čili pole obsahující N prvků) trvat řádově až N kroků, což zapisujeme jako O(N) a říkáme, že je to vzhledem k N <i>lineární časová složitost</i>.</p><p>To je značná nevýhoda oproti struktuře, kterou si ukážeme za chvíli. Určitě ale pole nezavrhujme. Je to základní datová struktura, která nalezne použití ve spoustě programů, a jak si ve druhé části kuchařky ukážeme, můžeme ho použít třeba k rychlému hledání hodnoty metodou <i>binárního vyhledávání</i>. Nyní ale již slibovaná další datová struktura.</p>",
|
"htmlContent": "<p>První datovou strukturou, kterou si představíme a která se na výše nastíněnou situaci náramně hodí, je <i>pole</i>. To představuje spoustu přihrádek (proměnných) naskládaných v paměti za sebou, ke kterým typicky přistupujeme přes jeden společný název pole a jejich pořadové číslo neboli index (jako NazevPole[0], NazevPole[1], …). (Pozor, ve světě počítačů se velmi často indexuje od nuly, tedy první prvek má v tomto případě index 0.)</p><p>Ve většině základních jazyků je pole jen <i>statické</i>, tedy v okamžiku jeho vytváření musíme počítači říct, jak ho chceme velké. Některé vyšší jazyky ale nabízejí i pole, které se dynamicky zvětšuje, takovou konstrukci si ukážeme ve druhé části kuchařky.</p><p>Abychom nebyli omezeni jen jedním rozměrem, můžeme si klidně vyrobit pole dvourozměrné (případně obecně n-rozměrné). Dvourozměrné pole je vlastně tabulka hodnot, nazýváme ji také někdy <i>matice</i>, a může se nám hodit například při reprezentaci různých map (plán bludiště) nebo, jak uvidíme níže, pro reprezentaci dalších datových struktur.</p><p>U pole již má smysl přemýšlet, jak dlouho bude která operace trvat. Díky tomu, že jsou jednotlivé prvky v poli naskládané pevně za sebou, je snadné spočítat umístění konkrétní přihrádky. Proto když se počítače zeptáme na obsah přihrády pole[42], vrátí nám hodnotu ihned.</p><figure class=\"image\"><img src=\"https://ksp.mff.cuni.cz/img/hippo_array.png\" alt=\"Pole\"></figure><p>Tomu budeme říkat <i>operace v konstantním čase</i> a budeme značit, že trvá čas O(1). Efektivitu programu totiž nepočítáme v sekundách (protože každý z nás má asi jinak rychlý počítač), ale v počtu základních operací, které musí program řádově vykonat. Více o časové složitosti si můžete přečíst v <a href=\"https://ksp.mff.cuni.cz/viz/kucharky/slozitost\">kuchařce o složitosti</a>, nejdříve však doporučujeme dočíst tuto kuchařku.</p><p>Přidání nového prvku na konec pole také zvládneme v konstantním čase. Problém je přidání nového prvku někam doprostřed (což se nám typicky stane, pokud budeme chtít udržovat hodnoty v poli seřazené a zároveň do něj vkládat nové). V takovém případě se totiž všechny prvky za vkládaným musí posunout o jednu pozici dál, aby se vkládaný prvek vešel na své místo. Taková operace tedy může pro pole délky N (čili pole obsahující N prvků) trvat řádově až N kroků, což zapisujeme jako O(N) a říkáme, že je to vzhledem k N <i>lineární časová složitost</i>.</p><p>To je značná nevýhoda oproti struktuře, kterou si ukážeme za chvíli. Určitě ale pole nezavrhujme. Je to základní datová struktura, která nalezne použití ve spoustě programů, a jak si ve druhé části kuchařky ukážeme, můžeme ho použít třeba k rychlému hledání hodnoty metodou <i>binárního vyhledávání</i>. Nyní ale již slibovaná další datová struktura.</p>",
|
||||||
"position": [
|
"position": [
|
||||||
-386.3838195800781,
|
-396.99383544921875,
|
||||||
714.8706398010254
|
655.7576637268066
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -2235,13 +2248,13 @@
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"comment": "https://ksp.mff.cuni.cz/kucharky/zakladni-algoritmy/",
|
"comment": "https://ksp.mff.cuni.cz/kucharky/zakladni-algoritmy/",
|
||||||
"requires": [
|
"requires": [
|
||||||
"kucharka-zakladni-prefixove-soucty"
|
"30-Z4-1"
|
||||||
],
|
],
|
||||||
"title": "Dvourozměrné prefixové součty",
|
"title": "Dvourozměrné prefixové součty",
|
||||||
"htmlContent": "<h4>Dvourozměrné prefixové součty</h4><p>Prefixové součty se dají zobecnit i do více rozměrů, ale princip je vždy stejný. Například dvourozměrné prefixové součty u matice fungují tak, že si předpočítáme součty podmatic začínajících levým vrchním políčkem a končící na indexu [x,y].</p><p>Z toho je vidět, že prefixový součet zpravidla obsadí stejně velký prostor jako původní data, v tomto případě tedy budeme mít matici hodnot prefixových součtů končících na zadaných souřadnicích. Jak ale získat součet nějaké podmatice, která se nachází někde „uprostřed“ naší matice?</p><p>Použijeme stejný princip jako u jednorozměrného případu: Přičteme větší část, kterou chceme započítat, a odečteme od ní části, které započítat nechceme. Pro případ podmatice začínající vlevo nahoře na pozici [x,y] a končící napravo dole na [X,Y] to ilustruje následující obrázek:</p><figure class=\"image\"><img src=\"https://ksp.mff.cuni.cz/kucharky/zakladni-algoritmy/zakladni_algoritmy-6.png\" alt=\"Dvourozměrné prefixové součty\"></figure><p>Nejdříve přičteme celý prefixový součet končící na pozici [X,Y]. Tím jsme ale započítali i části A, B a C z obrázku, které započítat nechceme. Tak odečteme prefixové součty končící na indexech [X,y] a [x,Y]. Ale pozor, teď jsme odečetli jednou A+B a jednou A+C, tedy část A (prefixový součet končící na pozici [x,y]) jsme odečetli dvakrát, musíme ji proto ještě jednou přičíst.</p><p>Celý vzorec tedy vypadá takto:</p><p>soucet = P[X,Y] - P[X,y] - P[x,Y] + P[x,y];</p><p>Tento princip přičítání a odečítání se dá zobecnit i pro libovolné vyšší rozměry, ale chce to již trošku představivosti, co se má přičíst a kolikrát. Říká se tomu také <i>princip inkluze a exkluze</i> a najde použití nejen u vícerozměrných prefixových součtů.</p>",
|
"htmlContent": "<h4>Dvourozměrné prefixové součty</h4><p>Prefixové součty se dají zobecnit i do více rozměrů, ale princip je vždy stejný. Například dvourozměrné prefixové součty u matice fungují tak, že si předpočítáme součty podmatic začínajících levým vrchním políčkem a končící na indexu [x,y].</p><p>Z toho je vidět, že prefixový součet zpravidla obsadí stejně velký prostor jako původní data, v tomto případě tedy budeme mít matici hodnot prefixových součtů končících na zadaných souřadnicích. Jak ale získat součet nějaké podmatice, která se nachází někde „uprostřed“ naší matice?</p><p>Použijeme stejný princip jako u jednorozměrného případu: Přičteme větší část, kterou chceme započítat, a odečteme od ní části, které započítat nechceme. Pro případ podmatice začínající vlevo nahoře na pozici [x,y] a končící napravo dole na [X,Y] to ilustruje následující obrázek:</p><figure class=\"image\"><img src=\"https://ksp.mff.cuni.cz/kucharky/zakladni-algoritmy/zakladni_algoritmy-6.png\" alt=\"Dvourozměrné prefixové součty\"></figure><p>Nejdříve přičteme celý prefixový součet končící na pozici [X,Y]. Tím jsme ale započítali i části A, B a C z obrázku, které započítat nechceme. Tak odečteme prefixové součty končící na indexech [X,y] a [x,Y]. Ale pozor, teď jsme odečetli jednou A+B a jednou A+C, tedy část A (prefixový součet končící na pozici [x,y]) jsme odečetli dvakrát, musíme ji proto ještě jednou přičíst.</p><p>Celý vzorec tedy vypadá takto:</p><p>soucet = P[X,Y] - P[X,y] - P[x,Y] + P[x,y];</p><p>Tento princip přičítání a odečítání se dá zobecnit i pro libovolné vyšší rozměry, ale chce to již trošku představivosti, co se má přičíst a kolikrát. Říká se tomu také <i>princip inkluze a exkluze</i> a najde použití nejen u vícerozměrných prefixových součtů.</p>",
|
||||||
"position": [
|
"position": [
|
||||||
-714.1817283630371,
|
-710.7839622497559,
|
||||||
1252.7593383789062
|
1225.3379516601562
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -2415,15 +2428,15 @@
|
||||||
{
|
{
|
||||||
"id": "placeholder-kurz-programovani",
|
"id": "placeholder-kurz-programovani",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"comment": "...",
|
"comment": "",
|
||||||
"requires": [
|
"requires": [
|
||||||
"programovani"
|
"programovani"
|
||||||
],
|
],
|
||||||
"title": "Placeholder pro základní kurz programování",
|
"title": "Základní kurz programování",
|
||||||
"htmlContent": "<p>Tady by měl začítat kurz programování. Chceme ze stávajícího kurzu vybrat úlohy a dát je sem. Postupně by asi také bylo fajn to celé rozvinou do větších detailů.</p>",
|
"htmlContent": "<p>Tady by měl začítat kurz programování. Chceme ze stávajícího kurzu vybrat úlohy a dát je sem. Postupně by asi také bylo fajn to celé rozvinou do větších detailů.</p><p> </p><p>Zatím je základní kurz na https://ksp.mff.cuni.cz/kurzy/zkp/1-uvod/</p>",
|
||||||
"position": [
|
"position": [
|
||||||
271.81773376464844,
|
271.81773376464844,
|
||||||
322.83670806884766
|
324.0678482055664
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
Reference in a new issue