Také si povíme o vhodných funkcionálních datových strukturách, jak programovat s grafy a naučíme se, jak programovat imperativní algoritmy používající pole.
Dál nás bude zajímat vícevláknové programování a způsoby synchronizace vláken.
Kromě technik se naučíme profilovat a ladit programy v Haskellu, používat výjimky, řekneme si o používaných optimalizacích a vysvětlíme si, jak se propojují programy v Haskellu s jinými jazyky a technologiemi.
Všechny domácí úkoly by měly být spustitelné na hugsu i na ghci, pokud nebude u úkolu řečeno jinak, byť můžete používat vcelku libovolná rozšíření oproti Haskellu 98, která jsou v obou interpreterech.
Zadání domácích úkolů se může lehce změnit oproti tomu, které jsem zadával na hodině (když udělám nějakou chybu). Platná verze je vždy ta uvedená zde.
Datum cvičení | ID | Body | Popis | |||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
03. března 2009 | Úkoly můžete odevzdávat do 24. března 2009, 10:40. | |||||||||||||||||||||||||||||||||||||||
wc | 2 | Napište skript, který přečte standardní vstup a na výstup vypíše jednu řádku (podobně jako wc bez parametrů
až na nemezerové znaky):počet_řádek počet_slov počet_nemezerových_znaků Je vhodné použít main = interact w , kde w::String->String .
| ||||||||||||||||||||||||||||||||||||||
cat-n | 2 | Napište skript, který se chová jako cat -n , tj. čte standardní vstup a každý řádek očísluje stylem
printf("%6d\t%s, číslo_řádku, text_řádku) .
| ||||||||||||||||||||||||||||||||||||||
Pro další tři úlohy ji zadefinujte binární strom, který má hodnoty typu a v každém vrcholu,
tj. BinTree a = ... .
| ||||||||||||||||||||||||||||||||||||||||
l2t | 2 | Napište funkci, která dostane setřídění seznam a vytvoří z něj perfektní binární vyhledávací strom. Perfektní znamená, že v každém vrcholu je velikost podstromu levého syna rovna velikosti podstromu pravého syna až na plus minus 1. | ||||||||||||||||||||||||||||||||||||||
perf | 1 | Vytvořte funkci, které zadáte mocninu dvojky n=2k a ona vytvoří úplný binární strom s k hladinami. V každém vrcholu je číslo 1. Optimalizujte na časovou složitost. | ||||||||||||||||||||||||||||||||||||||
onepass | 2 | Napište funkci, které dáte binární strom s Int y a ona vytvoří strom stejného tvaru, taktéž s Int y,
který má v každém vrcholu uložený celočíselný průměr všech
hodnot vrcholů původního stromu. Pozor,
původní strom můžete projít jenom jednou a ten nový nemůžete
procházet vůbec (jenom ho vytvořit)!
| ||||||||||||||||||||||||||||||||||||||
10. března 2009 | Úkoly můžete odevzdávat do 31. března 2009, 10:40. | |||||||||||||||||||||||||||||||||||||||
show | 1 | Máte dáno data Tree a = Empty | Tree a [Tree a] . Napište ručně instanci Show (Tree a) , aby fungovala v
lineárním čase.
| ||||||||||||||||||||||||||||||||||||||
n235 | 1.5 | Napište funkci, která vrací nekonečný seznam rostoucích čísel, která nemají jiné prvočíselné dělitele než 2, 3, 5, tj. čísel tvaru 2i * 3j * 5k. Složitost získání prvních K prvků musí být O(K). | ||||||||||||||||||||||||||||||||||||||
lcs | 1.5 | Napište funkci, která pro dva dané seznamy najde délku jejich nejdelšího společného ne nutně souvislého podseznamu. Časová složitost by měla být nejvíc O(součin délek těchto seznamů). | ||||||||||||||||||||||||||||||||||||||
sumall | 1.5 | Napište funkci sumall , která dostane libovolný nezáporný počet Int ů a vrátí jejich součet.
| ||||||||||||||||||||||||||||||||||||||
printf | 1.5 | Napište funkci printf , která bude umět vypisovat dané argumenty podle formátovacího řetězce. Podporujte alespoň %c
%d a %s . Funkce nemusí fungovat přesně tak, jako její
céčková varianta, ale
printf "Ahoj %d %s%c" (5::Int) "člověků" '!' by mělo fungovat.
| ||||||||||||||||||||||||||||||||||||||
mulall | 1.5 | Navrhněte funkci mulAll , které jako první parametr nějak zadáte počet a ona pak vynásobí tolik parametrů typu Integer .
Takže typ mulAll "dva" musí být Integer->Integer->Integer .
Tu "dvojku" nemůžete zadat číslem ani stringem, ale nějak jinak
(klidně to může být unárně).
| ||||||||||||||||||||||||||||||||||||||
17. března 2009 | Úkoly můžete odevzdávat do 07. dubna 2009, 10:40. | |||||||||||||||||||||||||||||||||||||||
pyth | 1.5 | Napište funkci pyth::[(Int,Int,Int)] , která bude vracet všechny pythagorejské trojice, tj. trojice kladných
přirozených čísel, že
a2+b2=c2.
Tato funkce by měla vracet všechny takové trojice a přitom
každou právě jednou ((3,4,5) a (4,3,5) jsou stejné trojice).
| ||||||||||||||||||||||||||||||||||||||
ls | 2 | Napište příkaz ls , který dostane na příkazové řádce několik adresářů, každý z nich rekurzivně projde
a vypíše.
| ||||||||||||||||||||||||||||||||||||||
diff | 3 | Napište příkaz diff , který dostane na příkazové řádce dva soubory (pokud jeden chybí, tak je to standardní
vstup) a najde diff, tj. nejmenší počet řádek, které je třeba
odstranit či přidat, aby se z prvního souboru stal druhý.
Na výstup (jako diff -u ) vypište nezměněné
řádky s mezerou na začátku, odstraněné s - na začátku
a přidané s + na začátku.
| ||||||||||||||||||||||||||||||||||||||
24. března 2009 | Úkoly můžete odevzdávat do 14. dubna 2009, 10:40. | |||||||||||||||||||||||||||||||||||||||
bala | 1-2 | Napište funkci balanced::[Int]->Int , která dostane seznam nul a jedniček a vrátí délku nejdelší souvislé podposloupnosti, ve
které je stejně nul a jedniček. Body dostanete podle časové
složitosti, O(N2) za bod, O(N) za dva a půl.
| ||||||||||||||||||||||||||||||||||||||
usek | 1-2.5 | Napište funkci usek::[Int]->Int , která dostane posloupnost a vrátí délku její nejdelší souvislé podposloupnosti, která má
nezáporný součet svých členů. Body dostanete podle časové
složitosti, O(N2) za bod, O(N) za dva a půl bodu.
| ||||||||||||||||||||||||||||||||||||||
demo | 3 | Napište funkce demorse::String->String , která dekóduje vstup v morseovce. Tečka je tečka, čárka je pomlčka, oddělovač znaků
je svislítko a oddělovač slov jsou dvě svislítka. Ostatní znaky
ignorujte. Plný počet bodů jenom za složitost lineární s
velikostí vstupu plus s velikostí abecedy.
| ||||||||||||||||||||||||||||||||||||||
mstop | 3 | Rozšiřte monádu z Eval3.hs tak, aby podporovala funkci stop :: Vypocet () . Této funkci předáte
string. Tato funkce přeruší výpočet v monádě a vrátí (uvnitř
té monády samozřejmě) onen string a zbytek výpočtu. Uživatel
může zbytek výpočtu kdykoliv spustit.
| ||||||||||||||||||||||||||||||||||||||
31. března 2009 | Úkoly můžete odevzdávat do 21. dubna 2009, 10:40. | |||||||||||||||||||||||||||||||||||||||
feq | 3 | Napište program, který dostane na příkazové řádce (viz getArgs ) jméno adresáře a on roztřídí soubory v tomto
adresáři (ne v podadresářích; viz getDirectoryContent
a doesDirectoryExist ) do skupin podle obsahu, tj. v jedné
skupině jsou právě soubory stejného obsahu. Zkuste vymyslet
nějaký chytřejší způsob než porovnávat soubory každý s každým.
| ||||||||||||||||||||||||||||||||||||||
find | 2 | Napište program, který dostane na příkazové řádce řetězec a případně adresář (pokud adresář chybí, použije se aktuální adresář), najde rekurzivně všechny soubory a podadresáře obsahující daný řetězec a vypíše je, jeden na řádku. | ||||||||||||||||||||||||||||||||||||||
coll | 2.5 | Vytvořte funkci collision::(Integer->Integer)->(Integer,Integer) , která
dostane funkci f, o které ví, že nekonečná posloupnost $f(0),
f(f(0)), f(f(f(0))),...$ neobsahuje nulu a skládá se pouze z
konečného počtu různých čísel (čili je od nějaké doby
periodická). Najděte $co nejrychleji a s pomocí co nejméně
paměti dvě různé hodnoty x,y, aby f(x)=f(y)$.
| ||||||||||||||||||||||||||||||||||||||
tiso | 2.5 | Stromy jsou definované jako BinTree a = N | V (BinTree a) a (BinTree a) . Napište funkci,
která dostane dva stromy, a zjistí, jestli jsou stejné až na
pořadí synů. Tedy V N 1 (V N 2 N) je až na pořadí synů
shodný s V (V N 2 N) 1 N . Plný počet bodů jenom za řešení
rychlejší než Ο(N2), kde N je počet vrcholů většího ze
stromů.
| ||||||||||||||||||||||||||||||||||||||
07. dubna 2009 | Úkoly můžete odevzdávat do 28. dubna 2009, 10:40. | |||||||||||||||||||||||||||||||||||||||
  | Mějme binární stromy BinTree a = N | V (BinTree a) a (BinTree a) .
| |||||||||||||||||||||||||||||||||||||||
bfst | 2.5 | Napište funkci bfst :: BinTree a -> BinTree Int , která dostane binární strom a vrátí binární strom stejného tvaru,
který má vrcholy očíslované po vrstvách zleva doprava, tj.
vrcholy jsou očíslované v pořadí, v jakém byste je navštívili
při prohledávání do šířky. Plný počet bodů za lineární řešení.
| ||||||||||||||||||||||||||||||||||||||
recon | 2.5 | Napište funkci recon :: [a] -> [a] -> BinTree a , která dostane vrcholy stromu v prefixovém uspořádání, vrcholy toho
samého stromu v infixovém uspořádání a vrátí původní strom.
Předpokládejte, že všechny vrcholy stromu mají jedinečné
hodnoty. Plný počet bodů za lineární řešení.
| ||||||||||||||||||||||||||||||||||||||
cut | 2 | Napište program, který dostane na příkazové řádce dva parametry, první je seznam sloupců te formátu "3-6,1,2,7-10" a druhý nepovinný parametr je jediný znak, oddělovač. Program čte standardní vstup, každý řádek rozseká na sloupce podle oddělovače a vypíše pouze zadané sloupce, které na výstupu opět oddělí oddělovačem. | ||||||||||||||||||||||||||||||||||||||
calc | 3 | Napište jednoduchou kalkulačku pro čísla s libovolnou přesností. Čtěte standardní vstup, každá řádka je jeden výraz, spočtěte ho
a výsledek vypište. Výraz je klasický aritmetický výraz s
operacemi + - * / % (mínus jenom binární), závorkami, čísly
a speciální proměnnou "last", ve které je uložen výsledek
předchozího výrazu (a nula, pokud jde o první výraz nebo se
minulý výraz nepovedlo naparsovat nebo vyhodnotit). Na
parsování výrazu si napište parser typu toho z přednášky
(výsledky parseru ukládejte do Maybe monády). Vše počítejte v
Integer ech. Složitost by měla být lineární s velikostí
vstupu.
| ||||||||||||||||||||||||||||||||||||||
14. dubna 2009 | Úkoly můžete odevzdávat do 05. května 2009, 10:40. | |||||||||||||||||||||||||||||||||||||||
blud | 3 | Na vstupu dostanete bludiště: dostanete čísla N,M a dále M řádek, každá obsahuje N nemezerových znaků. Velké X je
zeď, tečka je volno, M je matfyzák, který je v bludišti právě
jeden, a m je matfyzačka, která je v bludišti také právě
jedna. Najděte a zobrazte nejkratší cestu mezi matfyzačkou a
matfyzákem. Vypište bludiště ve stejném formátu, jenom
zavináčem označte políčka, která leží na nejkratší cestě. Chci
Ο(MN) nebo Ο(MN log(MN)).
| ||||||||||||||||||||||||||||||||||||||
primes | 3 | Napište funkci primes :: [Integer] , která vrací všechna prvočísla. Tato funkce musí fungovat velmi rychle, se
složitostí Ο(N log log N) pro získání všech prvočísel do
N, což je přesně složitost Eratosthenova síta. Na rozdíl od
síta ale musíte vracet potenciálně nekonečně prvočísel.
| ||||||||||||||||||||||||||||||||||||||
21. dubna 2009 | Úkoly můžete odevzdávat do 12. května 2009, 10:40. | |||||||||||||||||||||||||||||||||||||||
plen | 2 | Napište funkci plen :: [Int] -> Integer , která dostane permutaci a vrátí kolikrát nejméněkrát (nula neplatí :–) je
třeba tuto permutaci složit samu se sebou, aby vznikla
identická permutace.
| ||||||||||||||||||||||||||||||||||||||
stree | 3 | Na vstupu dostanete graf, zadaný jako seznam sousedů. První řádka vstupu obsahuje číslo N a i-tá řádka z dalších N řádek obsahuje každá sousedy i-tého vrcholu. V lineárním čase najděte a vypište libovolnou kostru tohoto grafu. | ||||||||||||||||||||||||||||||||||||||
fft | 3 | Naprogramujte v Haskellu funkci fft::Int->[Float]->[Complex Float] . Tato funkce použitá jako
fft n seznam_2n_floatů provede FFT, tj. rychlou Fourierovu
transformaci na daných hodnotách. Složitost algoritmu musí být
Ο(N log N).
| ||||||||||||||||||||||||||||||||||||||
28. dubna 2009 | Úkoly můžete odevzdávat do 19. května 2009, 10:40. | |||||||||||||||||||||||||||||||||||||||
quad | 2 | Na vstupu je černobílý obrázek v rozlišení 2n x 2n zadaný následujícím kódováním:
|
Jméno | Odevzdané úkoly | Body |
---|