Komparatori

Komparator je program koji služi za provjeru točnosti korisnikovog rješenja zadatka.
Evaluator ima 7 već gotova komparatora: Moguće je i napisati vlastiti komparator. Za više o tome pogledajte pod "Izrada vlastitog komparatora".

Postojeći

defcomp

defcomp je "default comparator", tj. komparator koji se postavi odmah čim se napravi novi zadatak.
On uspoređuje tekstualno, riječ, po riječ.
Primjerice, korisnik ispiše:
1 1 3
A trebalo je biti:
1 2 3
defcomp će ispisati da je program ispisao "1", a trebalo je biti "2".

defcomp-u je svejedno ako ima viška razmaka ili entera.

defcomp podržava i negativne bodove. Sve što je potrebno učiniti da se to aktivira je staviti mu argument: "-neg decbroj" (bez navodnika), pri čemu je decbroj neki decimalni broj, tj. postotak s kojim se izračunava iznos negativnih bodova.
Primjerice, ako je broj bodova po test primjeru 100 i defcompov argument je "-neg 0.25", i ako je rješenje krivo, dobiveni broj bodova će biti -25.

silentdefcomp

silentdefcomp je komparator koji je skoro u potpunosti isti kao i defcomp, samo što ne ispisuje što je program trebao ispisati.
Umjesto toga, on jednostavno samo ispiše da li je rješenje točno ili nije.

partcomp

partcomp je komparator vrlo sličan defcomp-u, ali ukupni broj bodova po test primjeru će ovisiti o tome koliko je točnih elemenata.
Primjerice, izlazni test primjer je:
1 2
A korisnik ispiše:
1 1
Dobit će 50% bodova jer mu je samo pola rješenja točno.

silentpartcomp

silentpartcomp radi sve što i partcomp, osim što ne ispisuje elemente koji su krivi i što su trebali biti.

numcomp

numcomp je komparator za brojeve. Najbolje ga je koristiti ako se izlazni test primjeri sastoje od decimalnih i/ili realnih brojeva.
Za usporđivanje realnih brojeva koristi tip "double", a za uspoređivanje cijelih brojeva koristi tip "long long". (numcomp detektira o kojem se tipu. Ako je u izlaznom test primjeru broj sa '.', onda se radi o decimalnim brojkama, inaće se radi o cijelim.)
numcomp uspoređuje broj po broj, te mu ne smeta višak razmaka i entera.

numcomp nudi provjeravanje točnosti rješenja uz zaokruživanje, i to na slijedeći način: onoliko koliko ima decimala u izlaznom test podatku, tolika će biti preciznost.
Dopušteno odstupanje se računa po slijedećoj formuli: 1.1*10-n , gdje je n broj decimala.
Primjerice, ako se radi o broju 1.1234, dopušteno odstupanje će biti +-0.00011, te brojevi poput 1.1235 i 1.1233 će biti prihvačeni.
Još jedan primjer: U izlaznom test primjeru se nalazi
12.00000
A korisnik ispiše:
12
Rješenje će mu biti prihvačeno. To je prednost numcompa nad defcompom jer je potrebno manje paziti da se točno isti brojevi nalaze u test primjerima i u rješenjima zadataka.

numcomp ne podržava scientific brojeve koji sadržavaju znak 'E' (ili 'e') u sebi.

bincomp

bincomp je komparator za kompariranje "grafičkih" rezultata, tj. ne zanemaruje broj prelaska u novi red i broj razmaka za razliku od defcomp-a.
bincomp ne ispisuje kako bi trebalo biti točno rješenje, niti što je korisnikov program ispisao.

linecomp

linecomp je komparator za kompariranje po linijama, ali tako da redosljed linija nije bitan.
Primjerice, korisnik ispiše:
Neki
Primjer
Ludi
A test primjer je:
Neki
Ludi
Primjer
linecomp će javiti da je rješenje točno.


Izrada vlastitog komparatora

Ponekad je potrebno napraviti vlastiti komparator. Primjerice, kada je zadatak takav da nudi više točnih rješenja, pa je rješenje nemoguće provjeriti pomoću test primjera.

Pri sastavljanju zadataka postoji opcija "upload comparator".
Tamo možete uploudati source vašeg komparatora.
Nakon što ga uploudate, možete klikom na link (ispod tog bloka za upload) pogledati da li se je uspješno kompajlirao.

Kako radi komparator?
Komparator se poziva sa dva argumenta: putanja do izlaznog test primjera, i putanja do ulaznog test primjera.
Ostali argumenti koje je moguće proslijediti komparatoru će biti odmah iza ta dva argumenta.
Rješenje korisnikovog programa (tj. točno ono što je korisnikov program ispisao) će biti poslano na standardni ulaz komparatora, tj. ono što komparator učitava "kao" sa tastature mora provjeriti da li je točno.
Ako je rješenje točno, program se treba izvršiti tako da vrati na kraju nulu, a ako je rješenje krivo, program treba na kraju vratiti jedan.

Kako napisati komparatora?
Neki dijelovi koda:
Dio C koda: Dio PAS koda:
#include <stdio.h>

int main(int argn, char *argv[]) {
	int tocnost;
	char *ulaz, *izlaz;
	FILE *datizlaz;

	izlaz = argv[1];
	ulaz = argv[2];

	datizlaz = fopen(izlaz, "rt");
	.................................
	. sa scanf ili sl. se skupljaju .
	. podaci za provjeru            .
	.................................

	return tocnost;
}
var ulaz,izlaz:string;
    tocnost:integer;
    datizlaz:text;

begin
	izlaz = ParamStr(1);
	ulaz = ParamStr(2);

	assign(datizlaz, izlaz);
	reset(datizlaz);
	..................................
	. sa readln ili sl. se skupljaju .
	. podaci za provjeru             .
	..................................

	halt(tocnost);
end.
Varijabla "izlaz" će sadržavati putanju do izlaznog test primjera (s kojim je moguće uspoređivati korisnikov ispis), a varijabla "ulaz" do ulaznog test primjera (test primjer koji je poslan korisnikovom programu). S time da izlazni test primjer ne mora nužno postajati - ovisno o tome da li je postavljen ili nije.
Poželjno je datoteke otvarati točno s tom putanjom, dakle, ne smije se modificirati tu putanju, pa onda otvarati datoteku s nekom drugom putanjom.
U slučaju da datoteka s ulaznim test primjerom nije potrebna, nije ju niti potrebno otvarati (kao datoteku).
Varijabla "tocnost" na kraju mora biti 0 ako je rješenje točno, a inače 1.
No moguće je i vratiti nešto osim toga da je rješenje samo krivo ili točno u cjelobrojnim postocima.
To je moguće po slijedećoj formuli:
tocnost = CP_PERCENT_OK + postotak
Primjerice, ako je postotak -25, onda će rješenju biti pridodijeljeno -0.25*broj_bodova_po_test_primjeru. Tj. ako je broj bodova po test primjeru bio 4, za taj test primjer korisnik će dobiti -1 bod.

Upozorenje: Komparator se pokreće pod neograničenim privilegijama! U slučaju da se skrši, trebalo bi cijelog evaluatora resetirati.
Komparatori moraju biti napisani tako da je sigurno da će se izvršiti unutar nekog kraćeg vremena!
Sve petlje bi trebale biti napisane tako da je sigurno da će se izvršiti.

Sve podržane izlazne vrijednosti (varijabla "tocnost"):
Ime konstante: Vrijednost: Značenje:
CP_OK 0 Rješenje je točno
CP_BAD 1 Rješenje je krivo
CP_ARGERR 2 Nedovoljan broj argumenata ili neka druga greška vezana uz argumente
CP_NOFILE 3 Ne postoji neka datoteka sa test primjerom
CP_PERCENT_NEG 10 Rješenje dobiva -100% bodova.
CP_PERCENT_OK 110 Rješenje dobiva 0% bodova.
(Svaka vrijednost između CP_PERCENT_NEG i CP_PERCENT_MAX određuje postotak bodova koji treba pridodijeliti.)
CP_PERCENT_MAX 210 Rješenje dobiva 100% bodova.
CP_FATALERROR 254 Došlo je do neke kritične greške u komparatoru, rješenje se ne da provjeriti