Otočení spojového seznamu

Blíží se závěr semestru a jednou z věcí, které je třeba znát k úspěšnému složení zkoušky je práce s ukazateli. Proto jsme si zkusili naprogramovat proceduru, která otočí jednosměrný spojový seznam.

Na cvičení jsme vymysleli nerekurzivní variantu, která měla kvadratickou složitost vzhledem k počtu prvků. Rekurzivní varianta má složitost lineární. Výchozí zdrojový kód můžete použít k jejímu otestování:

procedure rev(var head: PBlok; var tail: PBlok);
var pom: longint;
    newHead,newTail: PBlok;
begin
{ prazdny seznam }
if head = nil then
	begin
		tail := nil;
		exit;
	end;

{ jednoprvkovy seznam }
if head^.next = nil then
	begin
		tail:= head;
		exit; 
	end;

{ dvouprvkovy seznam }
if head^.next^.next = nil then
	begin
		pom:=head^.value;
		head^.value:=head^.next^.value;
		head^.next^.value:=pom;
		tail:= head^.next;
		exit;
	end;

{ vice nez dvouprvkovy seznam }
newHead:= head^.next;
rev(newHead,newTail); { otoc zbytek seznamu }
newTail^.next:=head; { pripojeni puvodni hlavy }
head^.next:=nil;
tail:= head; { nastaveni vystupnich parametru }
head:=newHead;
end;

Minimax

Uvažujme pro jednoduchost deskovou hru dvou hráčů s plnou informací. Při takové hře oba hráči znají celý aktuální stav (popis hrací desky + informace o tom, kdo je na tahu). Máme-li naprogramovat umělou inteligenci do takové hry, potřebujeme nějak zjistit, jak dobrý je stav, do kterého můžeme hru dostat provedením nějakého konkrétního tahu. K ohodnocení nějakého konkrétního stavu hry S lze použít rekurzivní funkci zvanou minimax.

             | utility(S)                    // game over
minimax(S) = | min[s in next(S)](minimax(s)) // tahne min
             | max[s in next(S)](minimax(s)) // tahne max 

Přitom předpokládáme, že hrají dva hráči - min a max. První se snaží dosáhnout co nejnižšší hodnotu a druhý naopak co nejvyšší. Pouze koncové stavy (game over) mají definovánu hodnotu utility jako nějaké číslo. Ve stavu S, který není koncový se počítá funkce rekurzivně jako minimum/maximum ze všech stavů, do kterých se lze z S dostat legálním tahem hráče, který je zrovna na tahu. Všechny takové stavy obsahuje množina next(S).

Použití funkce minimax jsme si demonstrovali na zjednodušené variantě hry nim.

Domácí úkol

Nic nebylo zadáno. Doporučuji ale zkusit si další příklady s ukazateli.