Cvičenia z programovania 2 - utorok 8:10 akvárium X

!!! POZOR !!! od 13.6. do 16.6. sa nebudú dať odovzdávať projekty !!! POZOR !!!

Ak si chcete precvičiť backtrack, podmienky v úlohe na backtrack som trochu zvoľnil. V úlohe na sorty som pridal príklad, ako som to myslel.
Ak vám chýbajú body za rozcvičky alebo domáce úlohy, alebo nemáte zapísaný projekt, ktorý ste už nahlásili, pls ozvite sa mi čím skôr, ideálne emailom.


cviko4ls.pas - výsledný kód z druhého cvičenia na spájané zoznamy a na procedurálny typ
Binárne stromy - totožné príklady z cvičenia v 2 verziách: Smerníky+záznamy, Objekty

Projekty

Základné pravidlá
Pokyny
Námety

Body za projekt Vám pridelím na základe osobného stretnutia (miestnosť I-11), na ktorom mi predvediete svoj projekt a vysvetlíte kód (ako ste to robili, ako to funguje). Body za projekt už pred skúškou musíte mať pridelené! Takže sa treba dohodnúť vopred. Odporúčam ozvať sa mi aspoň týždeň pred termínom skúšky, že chcete odovzdať projekt. Napíšte dátum a čas, kedy by Vám to vyhovovalo. Ak je to možné, doneste si vlastný notebook. Ak máte už niečo naprogramované a myslíte si, že by to bol dobrý projekt, nemusíte sa samozrejeme najprv prihlasovať. Skúste rovno poslať projekt a dohodnúť sa na odovzdaní. Prinajhoršom vám zamietnem tému, ale skôr navrhnem modifikácie.

Žiadni dvaja z mojich študentov bez ohľadu na skupinu nemôžu mať rovnaký projekt, databázy môžu byť tematicky podobné, ale musia byť aspoň niečím odlišné. Aj z jedného príkladu sa dajú vymyslieť dve rozne témy. Druháci musia mať novú tému, alebo starú patrične rozšíriť.

Body sa dajú získať za kvalitný návrh a vnútornú implementáciu, používateľnosť a vzhľad, užitočnosť, dokumentáciu..., za nutné minimum budú 1-3 body.

Rozcvičky

menokrúžok 12.2.19.2.26.2.5.3.12.3.19.3.26.3. 2.4.
veľká noc
9.4.16.4.23.4.30.4.7.5.14.5. suma
8 najlepších
spolu
(max 40)
projektbody
za projekt
Achbergerová, Katarína 2iai 0.5 3.5 4 4 5 1 4 4.5 4 4.5 3 33.5 33.5 FMFI Kino4.5
Beneš, Vladimír 2iai 2.5 2.5 2.5
Bobák, Martin 1iai3 4.5 5 3 4.5 1 5 4.5 5 5 5 4.5 38.5 240
Cimprich, Lukáš 1iai3 4.5 5 5 2 4 2 4 4 30.5 30.5 Evidencia webstránok4
Dobiáš, Dávid 1iai3 4 4.5 3.5 3 4 5 3 4 5 3.5 4 4 4.5 35 540 Evidencia pacientov
Grund, Adam 1iai3 5 1.5 2.5 5 2 3.5 4.5 2.5 3 4 30 3.533.5
Hudec, Matej 1iai3 5 5 4.5 4 3.5 4.5 4.5 3.5 4 5 5 37.5 340 Archív hercov9.5
Chlup, Jakub 1iai3 4.5 4.5 4 4.5 4 3 4.5 5 2.5 5 36 440 Autobusová stanica10
Íro, Branislav 1iai3 4 4 1 3 2.5 2 3.5 4 4.5 2.5 28 331 Sklad erotických pomôcok8
Jamrišková, Martina 1iai3 3 4 4 4.5 3 5 3.5 5 2.5 4.5 33.5 740 Pizzéria9
Jančovič, Matúš 1iai3 3 4 2.5 3.5 2 3 3 3.5 4.5 2.5 5 4 30.5 9.540
Kalužák, Matúš 1iai3 5 5 5 5 4.5 5 5 4.5 4.5 39 240 Hardware shop6
Karlubík, Juraj 1iai3 2 4.5 3 3.5 3.5 3 5 3.5 3.5 3.5 5 2.5 32 335
Kloss, Martin 1iai5 3 4.5 3.5 2.5 2.5 2 3.5 5 4 5 4.5 33 235 Letisko9.5
Kotry Lukáš 1iai5 3 3 3
Kováč, Pavol 1iai3 5 5 5 5 3 4.5 4.5 5 4 5 4.5 39 540 Zmenáreň4
Krajčovicová, Veronika 1iai5 3 0.5 1 4 1.5 3 1.5 2.5 4.5 1.5 3.5 4 4.5 29 29 Lekáreň
Križan, Ferdinand 1iai5 2.5 3 2.5 4 4 3.5 2.5 4.5 4.5 2 4 4 31.5 839.5 Motorové vozidlá7
Mauritz, Henrich 2iai 4.5 2.5 4 1 4.5 2 4.5 2.5 5 4.5 32 739 Školský bufet5
Mečiar, Martin 1iai5 4 3.5 4.5 3.5 4.5 4.5 24.5 24.5
Mesároš, Michal 1iai3 1.5 4 3 4 3 4 2 4 4 4 3.5 30.5 1040 Videopožičovňa2.5
Mihál, Martin 1iai3 3 4.5 5 3 3 3.5 4.5 4 3 5 5 34.5 6.540 Stávková kancelária
Minárčiný, Ján 1iai5 4 3.5 4.5 4.5 3.5 3 5 4.5 4.5 4.5 3.5 35 35 Trénerov záznamník
Moravec, Jakub 2iai 5 4 4 5 3 5 4.5 4 34.5 34.5
Moravec, Roman 2iai 0 3.5 1.5 4 2 3 1.5 4.5 4 4 26.5 531.5 ZOO6
Princ, Eduard 1iai3 2.5 4 4 2 5 2.5 4 2 5 4 31 3.534.5 Evidencia Skrípt9
Sokolová, Jana 1mAin/k 4.5 5 5 4.5 5 4 5 4.5 5 38.5 240 Archív pesničiek10
Stríbrnský, Róbert 1iai5 4.5 5 4.5 5 4 4.5 4.5 32 335 Metal Database10
Svitok, Peter 2iai 1.5 4 4 3.5 5 2 3.5 5 3.5 5 4.5 34.5 438.5 Hry/Hudobné médiá10
Šabík, Adam 1iai3 4.5 5 5 5 4 4.5 5 5 5 5 39.5 3.540 Lekáreň10
Švolík, Martin 1iai3 4 5 4 5 5 4.5 2 5 4.5 37 37 CMS/Blog5
Vodila, Ján 1iai3 5 5 5 4 4.5 5 2.5 4 35 540 Štatistika mužstva10
Vrecník, Roman 4.5 4 3.5 2.5 2 3.5 2 3.5 5 4.5 4 32.5 1.534 Hudobniny10
Zemanovič, Andrej 1iai5 3.5 5 4 4.5 3.5 3.5 2.5 5 3.5 5 4.5 35 540 Hotel8

Domáce úlohy

Počas semestra môžete získať spolu maximálne 10 bodov za nepovinné domáce úlohy (spolu s rozcvičkami nesmú presiahnuť celkový súčet 40 bodov).
Akceptujem len 100% správne, spustiteľné a odladené riešenia. Takže by ste si (u väčšiny úloh) mali svoj kód najskôr vyskúšať v praxi. Neakceptujem podobné riešenia (body dostane prvý).
Prosím, pokiaľ to zadanie úlohy umožňuje, posielajte iba samotnú procedúru/funkciu/metódu/kus kódu, ktorý ste mali urobiť priamo v tele e-mailu. Neposielajte celý projekt.
Od zverejnenia úlohy budete mať na riešenie vždy cca 7 dní.

Označenie komponentov

Odovzdať do skúšky
1 bod

Reprezentácia grafu obsahuje okrem reprezentácie vrcholov a hrán aj:

		type
		  TGraf = class
			... // vasa oblubena reprezentacia grafu
			Komponent: array of Integer;
			procedure UrobKomponenty;
		  end;
  		

Metóda UrobKomponenty do poľa Komponent pre každý vrchol grafu zapíše číslo komponentu, v ktorom sa tento vrchol nachádza. Ak sú dva vrcholy v tom istom komponente, majú v tomto poli rovnaké číslo. Ak je graf súvislý, všetky vrcholy majú hodnotu 1.

Pridaj most

Odovzdať do skúšky
1 bod

Naprogramujte funkciu grafu (function TGraf.PridajMost: Boolean;), ktorá nájde a pridá takú chýbajúcu hranu do grafu, aby klesol počet komponentov. Ak sa to podarí, vráti true. Ak sa hrana do grafu už pridať nedá, lebo graf je súvislý, vráti false.

Vizuálna aplikácia na grafy

Odovzdať do skúšky
1-3 body

Naprogramujte oknovú aplikáciu, ktorá bude vizualizovať vrcholy a hrany grafu na 2d grafickej ploche. Aplikácia musí vedieť minimálne korektne vykresliť nejaký graf s väčším počtom vrcholov (desiatky), či už náhodný, alebo zo súboru. Body navyše budú za možnosť pridávať/uberať do grafu vrcholy, hrany a ohodnotenia a drag'n'drop ovládanie polohy vrcholov, prípadne iné vylepšenia. Posielajte mi skomprimovaný celý projekt.

Porovnanie sortov

Odovzdať do skúšky
1-3 body

Vytvorte mini-aplikáciu (grafickú alebo konzolovú) na porovnávanie efektivity rôznych algoritmov usporiadania. Využite nasledovnú štruktúru procedurálnych typov (ak sa vám nezdá, môžete si ju upraviť, ale myšlienku treba zachovať):

  	type TPole = array of TPrvok;
  	// zaznam o priebehu jedneho behu sortovacieho algoritmu
  	type TStatistika = record sort: TSort; N, porovnania, vymeny: integer; end;
  	
	// porovna prvky na indexoch i,j; vrati true ak su spravne usporiadane(a[i]<a[j]), false ak su v zlom poradi(a[i]>=a[j]). urcuje poradie prvkov
	type TPorovnaj = function(var ai,aj: TPrvok; var stat: TStatistika): boolean;
	// vymeni prvky na indexoch i,j.
  	type TVymen = procedure(var pole: TPole; i,j: integer; var stat: TStatistika);
  	// usporiadaj premennu pole, prvky pritom porovnavaj pomocou funkcie porovnaj a vymienaj pomocou funkcie vymen. statistiku vrat v premennej stat.
  	type TSort = procedure(var pole: TPole; porovnaj: TPorovnaj; vymen: TVymen; var stat: TStatistika);
  	
  	// usporiadaj prvky pola niekolkymi sortami a vrat pole statistik. vsetky sorty budu zacinat z rovnakeho poradia.
  	function sortBenchmarkTest(var pole: TPole; sort: array of TSort): array of TStatistika;
  		

Pre realizáciu testu využite funckiu sortBenchmarkTest a jej výsledok (počty porovnaní a výmen) prehľadne zobrazte. Pre minimum treba implementovať aspoň 3 vami zvolené sorty, ktoré sa otestujú na tej istej náhodne generovanej postupnosti. Funkcie na porovnanie a výmenu prvkov by mali v štatistike počítať, koľkokrát boli vykonanné. Pre body navyše treba viac sortov, usporiadaní(zostupne, vzostupne, lexikograficky, inak...), predgenerované zaujímavé postupnosti na testovanie a porovnanie, užívateľskú prístupnosť, a pod.
Príklad s minsortom:
	procedure minsort(var pole: TPole; porovnaj: TPorovnaj; vymen: TVymen; var stat: TStatistika);
	var i,j,min_j: integer;
	begin
		stat.N := length(pole); // pocet prvkov
		for i:=low(pole) to high(pole)-1 do begin
			min_j := i;
			for j:=i+1 to high(pole) do
				if porovnaj(pole[j],pole[min_j], stat) then // ak j-ty prvok je mensi ako min_j-ty
					min_j := j;
			vymen(pole, i,j, stat);
		end;		
	end;
	
	function vzostupne(var ai,aj: TPrvok; var stat: TStatistika): boolean;
	begin
		inc(stat.porovnania);
		Result := (ai < aj);
	end;
	
	// ak by sme porovnavali datumy, tak napriklad takto
	function datumVzostupne(var ai,aj: TPrvok; var stat: TStatistika): boolean;
	begin
		inc(stat.porovnania);
		Result := false;
		if (ai.rok < aj.rok) then Result := true
		else if (ai.rok = aj.rok) then
			if (ai.mesiac < aj.mesiac) then Result := true
			else if (ai.mesiac = aj.mesiac) then
				if (ai.den < aj.den) then Result := true
	end;
	
	// a zavola sa to cca nejako takto
	var s: TStat; a: TPole;
	//...
	minsort(a, @vzostupne, @vymen, s);
	write('pocet prvkov: ',s.N,' vymen: ',s.vymeny,' porovnani: ',s.porovnania);

(Všeobecný) backtrack

Odovzdať do skúšky
2 body


Staré domáce úlohy

Generovanie haldy

Odovzdať do polnoci z 23.3.
1 bod

Naprogramujte generovanie haldy s daným počtom vrcholov. Halda (angl. heap) je binárny strom, ktorý ma minimálnu možnú hĺbku a všetky listy na najhlbšej úrovni sú "natlačené" vľavo. Na obsahu listov mi nezáleží, ale ideálne by bolo, keby boli po vypísaní inorderom usporiadané. Možno sa oplatí využiť vlastnosť, že plný binárny strom hĺbky H má 2H+1-1 vrcholov. Teda naopak, strom s N vrcholmi má hĺbku minimálne ceil(log2(N+1)-1) kde ceil vráti hornú celú časť, teda zaokrúhlenie nahor. Ľahšie sa to možno predstaví ako log2(najbližšia_väčšia_alebo_rovná_mocnina_dvojky(N+1))-1.

Aritmetický binárny strom

Odovzdať do polnoci 23.3.
0.5 boda + 1.5 boda

Aritmetický binárny strom má v listoch celé čísla a vo vnútorných uzloch má operáciu, kde ľavý a pravý podstrom predstavujú operandy, ktoré treba operáciou skombinovať (sčítať, odčítať, vynásobiť, vydeliť) Ak je operadom operácia, znamenaá to, že je akoby v zátvorke. Náčrt deklarácií pre triedy je nižšie. Takýto strom môžeme zapísať v troch tvaroch, podľa toho, či je operácia pred operandami, medzi operandami, alebo za operandami:

Doplňte, prípadne opravte implementáciu funkcie, ktorá vytvorí nový strom z reťazca zapísaného v tvare preorder. Podobne urobte funkciu ktorá sparsuje postorderovský zápis.
TBinarnyStrom = class
protected
	lavy,pravy: TBinarnyStrom;
public
	function pravyPodstrom: TBinarnyStrom;
	function lavyPodstrom: TBinarnyStrom;
	function vyhodnot: integer; virtual; abstract;
end

TZnamienko = class (TBinarnyStrom)
protected
	znamienko: char;
public
	constructor Create(zn: char);
	function vyhodnot: integer; override;
end

TCislo = class (TBinarnyStrom)
protected
	hodnota: integer;
public
	constructor Create(hod: integer);
	function vyhodnot: integer; override;
end

function parsujPreorder(input: string): TBinarnyStrom;       // + * 1 2 3  pochopi ako  (1 * 2) + 3    0.5 boda
var
  start, space: integer;

	function parsuj: TBinarnyStrom;
	begin
		// preskoc medzery
		while (space <= length(input)) and (_____________________) do
			inc(space);
			
		start := space; // tuto sa bude zacinat slovo
		
		// najdi dalsiu medzeru
		while (space <= length(input)) and (_____________________) do
			inc(space);
		
		// (space-start) je teraz vlastne dlzka slova

		if (space-start=1) and (_____________ in ['+','-','*','/']) then begin
			Result := _____________________;
			Result.lavy := parsuj; // rekurzivne sparsujeme zvysok stringu - prvy operand
			Result.pravy := parsuj; // a potom este dalsi zvysok - druhy operand
		end
		else
			Result := TCislo.Create(_____________________);
	end;

begin
	start := 1;
	space := 1;
	Result := parsuj;
end;

function parsujPostorder(input: string): TBinarnyStrom;       // 1 2 * 3 +  pochopi ako  (1 * 2) + 3    1.5 boda
// v zasade v mnohom podobne ako preorder, ale namiesto rekurzie bude mat zasobnik uzlov
// ked je nove nacitane slovo hodnota, prida novy uzol do zasobnika
// ked je nove slovo operator, vyberie a pouzije posledne dva prvky v zasobniku ako operandy operacie a do zasobnika prida takyto zlozeny uzol
    	

Spájaný zoznam

Odovzdať do polnoci 10.3.
1 bod + 1 bod

Vymen(i,j: integer)
Doprogramujte (alebo úplne preprogramujte) metódu spájaného zoznamu, ktorá vymení dva vrcholy určené indexami, aby fungovala správne vo všetkých prípadoch. (za 1 bod)
Otoc
Naprogramujte metódu spájaného zoznamu, ktorá otočí zoznam namieste, t.j. nevytvorí žiadny nový zoznam, pole ani inú množinu hodnôt, resp. vrcholov (ktorej by sa veľkosť menila podľa veľkosti pôvodného zoznamu). Môžete, ale nemusíte pri tom použiť metódu vymeň - ide to aj bez nej celkom ľahko. (za 1 bod)
Načaté riešenie: zoznam.pas