UL/FRI/UNI-RI/MOS/Izpiti/2006-06-08-prolog

Iz E-študij, proste zakladnice študentskega znanja

< UL | FRI | UNI-RI | MOS | Izpiti
Skoči na: navigacija, iskanje

Izpit z dne Napaka: neveljaven čas
UL/FRI/UNI-RI/MOS


Čas pisanja: ni podatka glej podobne izpite minut.
Literatura: ni podatka glej podobne izpite.

Mrzlica pred prihajajočim svetovnim prvenstvom narašča. Pobiralce stav zanima forma posameznih ekip, da slučajno ne bi bili z napačno ponujenimi stavami ob zaslužek. Na voljo so jim rezultati zadnjih medsebojnih prijateljskih tekem. Predikat win(ekipa1, ekipa2, rezultat) pove, da je prva ekipa premagala drugo z določenim rezultatom.

win(portugal, saudi_arabia, 3-0). win(mexico, paraguay, 2-1).
win(mexico, congo, 2-1). win(argentina, portugal, 3-2).
win(mexico, gana, 1-0). win(portugal, croatia, 2-0).
win(netherlands, ivory_coast, 3-1). win(argentina, hungary, 2-1).
win(netherlands, ecuador, 1-0). win(portugal, egypt, 2-0).
win(croatia, argentina, 3-2). win(ivory_coast, slovenia, 3-0).
win(south_corea, mexico, 1-0). win(netherlands, mexico, 2-1).


Podvprašanje 1

Poleg posameznih rezultatov je za pobiralce stav zanimiva tudi gol razlika posameznih moštev; to je razlika vseh danih in dobljenih golov na prijatelskih tekmah.
Napišite predikat gd(Team, GD), ki za podano moštvo vrne njegovo gol razliko.(35%)


Rešitev

gd(Team,GD) :-
	findall(X,(win(Team,_,X)),D),
	sum(D,Dobljeni),
	findall(X,(win(_,Team,X)),Z),
	sum(Z,Zgubljeni),
	GD is Dobljeni-Zgubljeni.
 
sum([],0).
sum([H|T],GD) :-
	sum(T,G2),
	GD is G2+H.

Preseljena Rešitev

gd(Team, GD):-
	    %Dobljene tekme
	    findall(X, win(Team, _, X-Y), XL),
	    findall(Y, win(Team, _, X-Y), YL),
	    sumListValues(XL, XS),
	    sumListValues(YL, YS),
	    DobljeniGoli is (XS - YS),
            %Zgubljene tekme
	    findall(LX, win(_, Team, LX-LY), LXL),
	    findall(LY, win(_, Team, LX-LY), LYL),
	    sumListValues(LXL, LXS),
	    sumListValues(LYL, LYS),
	    ZgubljeniGoli is (LXS - LYS),
	    GD is DobljeniGoli - ZgubljeniGoli.
 
 
sumListValues([], 0).
sumListValues([X|Y], Sum):-
			sumListValues(Y, Sum1),
			Sum is Sum1 + X.

Verjetno obstaja bolj elegantna rešitev. Če jo kdo ima naj me prosim popravi.

Elegantnejša rešitev

gd(Team,GD):-findall(X,(win(Team,_,X-Y);win(_,Team,Y-X)),Dani),
	     findall(Y,(win(Team,_,X-Y);win(_,Team,Y-X)),Prejeti),
	     countGoals(Dani,N1),
	     countGoals(Prejeti,N2),
	     GD is N1-N2.
 
countGoals([],0).
countGoals([G|R],N):-countGoals(R,N1),N is N1+G.

Popravljena elegantnejša rešitev.

Še ena - s sum:

gd(Team,GD):-
         findall(X,(win(Team,_,X-Y);win(_,Team,Y-X)),Dani),
	 findall(Y,(win(Team,_,X-Y);win(_,Team,Y-X)),Prejeti),
	 sum(Dani,N1),
	 sum(Prejeti,N2),
	 GD is N1-N2.

Še najelegantnejša rešitev:):

gd(Team,Gd):-
	findall(G,((win(Team,_,X-Y);win(_,Team,Y-X)),G is X-Y),L),
	sumlist(L,Gd).

Podvprašanje 2

Kaj odgovori prolog na naslednja vprašanja? V pravilnem vrstnem redu navedite vse odgovore! (20%)

a) ?- win(portugal, X, 2-0).
b) ?- win(netherlands, X, _).
c) ?- win(X, mexico, _), !, win(mexico, Y, _).
d) ?- win(X, Y, _-2).

Rešitev
a)
X = croatia;
X = egypt;
No

b)
X = ivory_coast
X = ecuador
X = mexico

c)

X = south_corea,
Y = paraguay;
X = south_corea,
Y = congo
X = south_corea,
Y = gana

d)

X = argentina,
Y = portugal;
X = croatia,
Y = argentina;

Podvprašanje 3

Kako bi zastavili naslednja vprašanja?(20%) Pozor!! NE PISATI PROGRAMCKOV AMPAK IZJAVE!

a)Katere ekipe je premagala argentina?
b)Ali obstaja kakšen cikel treh ekip, tako da je prva ekipa premagala drugo, druga je premagala tretjo in tretja je premagala prvo?
c)S koliko različnimi ekipami je prijateljske tekme igrala argentina?
d)Katere ekipe so katerokoli drugo ekipo premagale za vsaj dva gola (zanima nas seznam takšnih ekip brez ponavljanja)?

Resitev

a) win(argentina, X,_).

b) win(Y,X,_), win(X,Z,_), win(Z,Y,_).

c)

findall(X,((win(argentina,X,_));(win(X,argentina,_))),L).


Mislim da zgornja rešitev ni pravilna, saj bo iste ekipe 2x štela. Prav tako, je treba podati število različnih ekip in jih ne našteti.
Moja rešitev

 setof(Z,Z^D^F^(win(argentina,Z,D);win(Z,argentina,F)),_L),
count(_L, X).

Ampak namesto count na koncu verjetno uporabiš length()? Moja rešitev

findall(N,(win(argentina,N,_);win(N,argentina,_)),_Stevilo), length(_Stevilo,M).

Tretja rešitev

findall(X,(win(argentina,X,_);win(X,argentina,_)),_Seznam), setof(X,memeber(X,_Seznam),_Seznam1), length(_Seznam1,N).


d)

setof(X, (R^(win(X,_,R)), R>=2), S).

Rešitev ni prava! To je prava rešitev:

findall(X,(win(X,_,Y-Z), N is Y-Z, N>=2),_Seznam), setof(X,member(X,_Seznam),Seznam1).

Namesto N is Y-Z, N>=2, lahko napišemo 2>=Y-Z

Podvprašanje 4

Ekipe bodo v prvem krogu tekmovanja razdeljene po skupinah. Predikat group(Team, Group) pove v kateri skupini igtra katera ekipa. Za ekipo velja, da je varna (glede uvrstitve v naslednji krog), če jo v prijateljskih tekmah ni premagala kakšna ekipa iz iste skupine. Nespretni pobiralec stav je za to, da bi izvedel katere ekipe so varne napisal naslednji program:(25%)

safe(Team):-
group(Team, G), group(Opponent, G), \+win(Opponent, Team, _).

a) Pomagajte nerodnemu pobiralcu stav in program ustrezno popravite!
b) Dodajte pogoj, da je ekipa za katero preverjate, če je varna, odigrala vsaj dve tekmi z nasprotnicami iz iste skupine(lahko tudi dve tekmi z istim nasprotnikom).

Resitev

a)

safe(Team):-
(group(Team, G), group(Opponent, G), win(Opponent, Team, _)) -> fail ; true.



b)

safe1(Team):-
             findall(Opponent, (group(Team, G), group(Opponent, G), win(Team, Opponent, _)), Z),
             length(Z, K), 
             2 =< K,
             safe(Team).
Osebna orodja
Imenski prostori
Različice
Dejanja
navigacija

Tiskanje/izvoz
orodja