commit 9efa9130f3945bcfec52a8d9cbaa4461f59d1dd5 Author: Szymon Karpiński Date: Mon Jul 27 17:05:12 2020 +0200 Original OI makefiles diff --git a/logo.pdf b/logo.pdf new file mode 100644 index 0000000..1d214cb Binary files /dev/null and b/logo.pdf differ diff --git a/makefile.doc b/makefile.doc new file mode 100644 index 0000000..afe26b7 --- /dev/null +++ b/makefile.doc @@ -0,0 +1,25 @@ +# +# Ogolny makefile do obslugi dokumentow Latexowych +# +TEX = $(wildcard [a-z]*.tex) +PDF = $(patsubst %.tex,%.pdf,$(TEX)) + +all: pdf + +pdf: $(PDF) + +%.pdf: %.tex + pdflatex $*.tex && pdflatex $*.tex + +%.dvi: %.tex + latex $*.tex + latex $*.tex + +# Tej opcji uzywamy przy wysylaniu paczki +clean: + rm -f *~ + rm -f *.log + rm -f *.aux + rm -f *.dvi + rm -f *.err + rm -f *.inf diff --git a/makefile.main b/makefile.main new file mode 100644 index 0000000..ecd3e98 --- /dev/null +++ b/makefile.main @@ -0,0 +1,1023 @@ +# +# OI Makefile +# Autor: Tomasz Walen, Rafal Rusin, Adam Iwanicki +# Historia: +# 1.06 : 2007.09.08 : AI - dodanie wsparcia dla Javy, raportu w formacie tabelki +# 1.07 : 2007.09.08 : AI - wypluwanie bledu w przypadku braku ustawionych limitow +# 1.08 : 2007.09.09 : AI - uzupelnienie raportu o jezyki w jakim sa zrodla +# 1.09 : 2007.09.09 : AI - dodanie sprawdzania nazw programow +# 1.10 : 2007.09.09 : AI - na zyczenie Jakuba Radoszewskiego weryfikator nie +# jest uruchamiany jesli program zakonczy sie beledem +# 1.11 : 2008.01.29 : AI - wymuszanie aby program w Javie dawal poprawne +# odpowiedzi w przeznaczonym czasie i pamieci +# 1.12 : 2008.10.17 : AI - dodanie do raportu dodatkowych informacji o systemie +# (pamiec, obciazenie procesora, limity) +# 1.13 : 2009.01.22 : AI - usuniecie ulimita dla Javy +# 1.14 : 2009.01.29 : AI - poprawienie porownania miedzy stringami przy checkerce +# 1.15 : 2009.02.03 : AI - dodanie mozliwosci ustawienia CFLAGS i swojego makefile'a +# 1.16 : 2009.03.27 : AI - dodanie pomijania mpstat (jesli nie ma go w systemie) oraz +# mozliwosci quickver (weryfikacja z pominieciem raportu) +# 1.17 : 2009.04.17 : AI - dodanie wymuszanie przebudowania dokumentow (.ps i .pdf), +# tak, aby miec pewnosc ze kompiluja sie na SInOlu. +# 1.18 : 2009.05.06 : AI - dodanie testowania valgrindem rozwiazania wzorcowego. +# 1.19 : 2009.12.05 : AI - dodanie usuwania *.valgrind do make clean w katalogu prog. +# 1.20 : 2009.12.09 : AI - dodanie zapezpiecznia przed zbyt dlugim dzialaniem programu. +# 1.21 : 2009.12.12 : AI - dodanie weryfikowania sum kontrolnych danych wejsciowych +# 1.22 : 2009.12.27 : AI - uruchomienie sleep jako oddzielnej grupy i zabicie jej. +# 1.23 : 2010.03.10 : AI - wiecej czasu rzeczywistego dla procesow, to tylko zabezpieczenie +# 1.24 : 2010.03.12 : AI - naprawa balaganu po real timeout, poprawa kolorow w raporcie, +# wyglada na to ze czasem sleep startuje pozniej i kill go nie zabija. + +VERSION = 1.24 + +SHELL := /bin/bash + +include makefile.in + +BIN_TIME = /usr/bin/time +TMP1 = .__tmp_1__~ +TMP2 = .__tmp_2__~ +TMP3 = .__tmp_3__~ +TMP4 = .__tmp_4__~ +MD5SUMS = in/.md5sums + +INGEN = $(shell if [ `find prog -name "$(ID)ingen.*" | wc -l` -gt 0 ] ; then echo 1 ; else echo 0 ; fi) +INWER = $(shell if [ `find prog -name "$(ID)inwer.*" | wc -l` -gt 0 ] ; then echo 1 ; else echo 0 ; fi) +CHECKER = $(shell if [ `find prog -name "$(ID)chk.*" | wc -l` -gt 0 ] ; then echo 1 ; else echo 0 ; fi) +PROGS_OPT= $(shell find prog -regex "prog/$(ID)[0-9]*\.\(c\|cpp\|pas\|ml\)" | sort -n -k 1.`echo "prog/$(ID)"| wc -c`) +PROGS_SLW= $(shell find prog -regex "prog/$(ID)s[0-9]*\.\(c\|cpp\|pas\|ml\)" | sort -n -k 1.`echo "prog/$(ID)s"| wc -c`) +PROGS_BAD= $(shell find prog -regex "prog/$(ID)b[0-9]*\.\(c\|cpp\|pas\|ml\)" | sort -n -k 1.`echo "prog/$(ID)b"| wc -c`) +PROGS_JAVA= $(shell find prog -regex "prog/$(ID)[0-9]*\.java" | sort -n -k 1.`echo "prog/$(ID)"| wc -c`) +PROGS_JAVA_SLW= $(shell find prog -regex "prog/$(ID)s[0-9]*\.java" | sort -n -k 1.`echo "prog/$(ID)"| wc -c`) +TESTS += $(shell find in -regex "in/$(ID)[0-9]*[a-z]?ocen.in" | sort -n -k 1.`echo "in/$(ID)"| wc -c` ) +TESTS += $(shell find in -regex "in/$(ID)[0-9]*[a-z]?.in" | sort -n -k 1.`echo "in/$(ID)"| wc -c` ) + +B_PROGS_WER= $(shell find prog -regex "prog/$(ID)[0-9]*wer[0-9]*\.\(c\|cpp\|pas\|ml\|java\)" | sort -n -k 1.`echo "prog/$(ID)"| wc -c`) +B_PROGS_SLW= $(shell find prog -regex "prog/$(ID)[0-9]*s\.\(c\|cpp\|pas\|ml\|java\)" | sort -n -k 1.`echo "prog/$(ID)"| wc -c`) +B_PROGS_BAD= $(shell find prog -regex "prog/$(ID)[0-9]*b\.\(c\|cpp\|pas\|ml\|java\)" | sort -n -k 1.`echo "prog/$(ID)"| wc -c`) + +.PHONY : clean clean-gen export verify tgz run inwer outgen verify_limits verify_names info report quickver ingen_md5 + +all: + # Podaj konkretny cel # + +export: + ## Przygotowanie paczki dla SInOl'a ## + make -C doc + make -C prog + make clean-gen + make clean + tar cvzf $(SIG).tgz --exclude "$(ID)/$(SIG).tgz" ../$(ID) + +run: + ## Uruchomienie rozwiązania wzorcowego ## + make _run_ver_n_$(ID).e + +oirun: + ## Uruchomienie rozwiązania wzorcowego ## + make _oirun_ver_n_$(ID).e + +run_%: + make _run_ver_n_$(ID)$*.e + +oirun_%: + make _oirun_ver_n_$(ID)$*.e + +jrun_%: + make _jrun_ver_n_$(ID)$*.e + +verify: clean verify_$(MODE) + +quickver: + @make verify QUICK=1 + +verify_red: + ## Automatyczna weryfikacja redacji ## + make -s "_verify_doc_$(ID)zad.tex" + make -s "_verify_in_$(ID)0.in" + make -s "_verify_out_$(ID)0.out" + make -C doc all + +info: + ## Wersja makefile'a $(VERSION) ## + ## Informacje o procesorze ## + @cat /proc/cpuinfo + @(ulimit -a) + @free + @if which mpstat >/dev/null ; then mpstat -P ALL; fi + +verify_limits: + ## Automatyczna weryfikacja limitow ## + ## + ## TIMELIMIT: $(TIMELIMIT) + ## SLOW_TIMELIMIT: $(SLOW_TIMELIMIT) + ## MEMLIMIT: $(MEMLIMIT) + ## + $(if $(TIMELIMIT),,$(error Brak ustawionego TIMELIMITu.)) + $(if $(SLOW_TIMELIMIT),,$(error Brak ustawionego SLOW_TIMELIMITu.)) + $(if $(MEMLIMIT),,$(error Brak ustawionego MEMLIMITu.)) + $(if $(shell if [ $(TIMELIMIT) -le 60 ]; then echo OK; fi),,$(error Za duzy TIMELIMIT: $(TIMELIMIT))) + $(if $(shell if [ $(SLOW_TIMELIMIT) -le 120 ]; then echo OK; fi),,$(error Za duzy SLOW_TIMELIMIT: $(SLOW_TIMELIMIT))) + $(if $(shell if [ $(MEMLIMIT) -le 512000 ]; then echo OK; fi),,$(error Za duzy MEMLIMIT: $(MEMLIMIT))) + + +verify_names: + ## Automatyczna weryfikacja nazw programow ## + $(if $(B_PROGS_BAD), $(error Niewlasciwe nazwy programow blednych ($(B_PROGS_BAD)). Nazwy powinny sie zaczynac od $(ID)b),) + $(if $(B_PROGS_SLW), $(error Niewlasciwe nazwy programow wolnych ($(B_PROGS_SLW)). Nazwy powinny sie zaczynac od $(ID)s),) + $(if $(B_PROGS_WER), $(error Niewlasciwe nazwy programow weryfikujacych ($(B_PROGS_WER)). Prosze nadac im nazwy zgodnie z typem $(ID), $(ID)s lub $(ID)b),) + + +report: + @printf " \n\ + \n\ + $(ID) - Raport \n\ + \n\ +
\n" 
+	#@make -s -C prog >/dev/null 2>/dev/null
+	#@make -s ingen >/dev/null 2>/dev/null
+	#@make -s inwer >/dev/null 2>/dev/null
+	#@make -s outgen >/dev/null 2>/dev/null
+	@echo "
" + @printf "

Raport

\n\ +

Legenda

\n\ + " + @echo "" + @for i in $(TESTS); do echo ""; done + @echo "" + @for i in $(PROGS_OPT); do j=`basename $$i`; if ! make -s _run_rep_o_$$j; then exit 1; fi; done + @for i in $(PROGS_JAVA); do j=`basename $$i`; if ! make -s _jrun_rep_o_$$j; then exit 1; fi; done + @for i in $(PROGS_SLW); do j=`basename $$i`; if ! make -s _run_rep_s_$$j; then exit 1; fi; done + @for i in $(PROGS_JAVA_SLW); do j=`basename $$i`; if ! make -s _jrun_rep_s_$$j; then exit 1; fi; done + @for i in $(PROGS_BAD); do j=`basename $$i`; if ! make -s _run_rep_o_$$j; then exit 1; fi; done + @for i in $(PROGS_WER); do j=`basename $$i`; if ! make -s _run_rep_o_$$j; then exit 1; fi; done + @printf "
langprogname`echo -n $$i | sed -e 's/ocen/*/' -e 's/in\/$(ID)//' -e 's/.in//'`
\n\n\n" + +oireport: + @printf " \n\ + \n\ + $(ID) - Raport \n\ + \n\ +
\n" 
+	#@make -s -C prog >/dev/null 2>/dev/null
+	#@make -s ingen >/dev/null 2>/dev/null
+	#@make -s inwer >/dev/null 2>/dev/null
+	#@make -s outgen >/dev/null 2>/dev/null
+	@echo "
" + @printf "

Raport

\n\ +

Legenda

\n\ + " + @echo "" + @for i in $(TESTS); do echo ""; done + @echo "" + @for i in $(PROGS_OPT); do j=`basename $$i`; if ! make -s _oirun_rep_o_$$j; then exit 1; fi; done + @for i in $(PROGS_SLW); do j=`basename $$i`; if ! make -s _oirun_rep_s_$$j; then exit 1; fi; done + @for i in $(PROGS_BAD); do j=`basename $$i`; if ! make -s _oirun_rep_o_$$j; then exit 1; fi; done + @for i in $(PROGS_WER); do j=`basename $$i`; if ! make -s _oirun_rep_o_$$j; then exit 1; fi; done + @printf "
langprogname`echo -n $$i | sed -e 's/ocen/*/' -e 's/in\/$(ID)//' -e 's/.in//'`
\n\n\n" + +verify_opr: info verify_red verify_limits verify_names + ## Automatyczna weryfikacja opracowania ## + make -s "_verify_doc_$(ID)opr.tex" + make -C doc all + make -C prog all + make ingen + make ingen_md5 + make inwer + make outgen + @for i in `echo $(PROGS_OPT)`; do j="`basename $$i`"; j="`(echo $$j) | rev | cut -d. -f2- | rev`.e"; if ! make _run_ver_o_$$j; then exit 1; fi; done + @for i in `echo $(PROGS_SLW)`; do j="`basename $$i`"; j="`(echo $$j) | rev | cut -d. -f2- | rev`.e"; if ! make _run_ver_s_$$j; then exit 1; fi; done +ifndef QUICK + make report + make valgrind +endif + +oiverify_opr: info verify_red verify_limits verify_names + ## Automatyczna weryfikacja opracowania ## + make -s "_verify_doc_$(ID)opr.tex" + make -C doc all + make -C prog all + make ingen + make ingen_md5 + make inwer + make outgen + @for i in `echo $(PROGS_OPT)`; do j="`basename $$i`"; j="`(echo $$j) | rev | cut -d. -f2- | rev`.e"; if ! make _oirun_ver_o_$$j; then exit 1; fi; done + @for i in `echo $(PROGS_SLW)`; do j="`basename $$i`"; j="`(echo $$j) | rev | cut -d. -f2- | rev`.e"; if ! make _oirun_ver_s_$$j; then exit 1; fi; done +ifndef QUICK + make oireport + make valgrind +endif + +verify_wer: verify_opr + ## Automatyczna weryfikacja weryfikacji ## + make -s "_verify_doc_$(ID)wer.tex" + +verify_tlu_%: + ## Automatyczne weryfikacja tlumaczenia ## + make -s "_verify_doc_$(ID)zad-$*.tex" + +verify_tlu: verify_red + +_verify_in_%: + @if [ ! -f "in/$*" ] ; then echo Brak pliku in/$* ; exit 1 ; fi + +_verify_out_%: + @if [ ! -f "out/$*" ] ; then echo Brak pliku out/$* ; exit 1 ; fi + +_verify_prog_%: + @if [ ! -f "prog/$*" ] ; then echo Brak pliku prog/$* ; exit 1 ; fi + +_verify_doc_%: + @if [ ! -f "doc/$*" ] ; then echo Brak pliku doc/$* ; exit 1 ; fi + make -C doc -B $(patsubst %.tex,%.pdf,$*) + +clean: + rm -f *~ + make -C doc clean + make -C prog clean + +###################################################################### +# Usunięcie testów genereowanych automatycznie +###################################################################### +clean-gen: + @if [ "$(INGEN)" -eq 1 ] ; then \ + if [ -e in/tmp ]; then rm -r in/tmp; fi ; \ + mkdir in/tmp ; \ + if [ -f prog/$(ID)ingen.sh ] ; then \ + cd in/tmp ; ../../prog/$(ID)ingen.sh ; \ + else \ + make -C prog $(ID)ingen.e ; \ + cd in/tmp ; ../../prog/$(ID)ingen.e ; \ + fi ; \ + INGEN_FILES="`echo *.in`"; \ + cd ../.. ; \ + rm -r in/tmp ; \ + for i in $$INGEN_FILES; do \ + j=`basename $$i .in`; \ + echo Kasuje in/$$j.in; rm -f in/$$j.in; \ + echo Kasuje out/$$j.out; rm -f out/$$j.out; \ + done ;\ + fi + +mrproper: + make -C doc no_binaries + @if [ "$(INGEN)" -eq 1 ] ; then \ + make clean-gen ; \ + fi + make -C prog clean + @echo Usuwanie plikow OUT + rm -f out/* + +############################################################################ +# Przygotowanie danych wejściowych generowanych automatycznie +############################################################################ +ingen: + @if [ "$(INGEN)" -eq 1 ] ; then \ + if [ -f prog/$(ID)ingen.sh ] ; then \ + cd in ; ../prog/$(ID)ingen.sh ; \ + else \ + make -C prog $(ID)ingen.e ; \ + cd in ; ../prog/$(ID)ingen.e ; \ + fi ; \ + fi + + +############################################################################ +# Weryfikacja losowosci danych wejściowych +############################################################################ +ingen_md5: $(MD5SUMS) + ## Weryfikacja zgodnosci wygenerowanych danych wejsciowych + ## + ## Na komputerze uzytkownika pliki wejsciowe mialy nastepujace sumy kontrolne: + @cat $(MD5SUMS) + @md5sum -c $(MD5SUMS) || echo -n + +############################################################################ +# Weryfikacja poprawności danych wejściowych +############################################################################ +inwer: + @if [ "$(INWER)" -eq 1 ] ; then \ + make -C prog $(ID)inwer.e ; \ + for i in $(TESTS) ; do \ + printf "%-11s ... " `basename $$i` ; \ + if ! prog/$(ID)inwer.e < $$i ; then \ + echo "ZLE!!!" ; \ + exit 1 ; \ + fi ; \ + done ; \ + else \ + echo "Brak weryfikatora do testów" ; \ + exit 2 ; \ + fi + @md5sum in/* > $(MD5SUMS) + + +############################################################################ +# Wygenerowanie wzorcowych odpowiedzi dla bieżącego zestawu testów +############################################################################ +outgen: + make -C prog $(ID).e + @for i in $(TESTS) ; do \ + printf "%-11s ... " `basename $$i` ; \ + prog/$(ID).e < $$i > out/`basename $$i .in`.out ; \ + echo OK ; \ + done + + +############################################################################ +# Uruchomienie programu prog/$(ID)%.e na bieżącym zestawie testów +# Ustawienie zmiennej ACC_TERM na 1 powoduje, ze wywlaszczane testy +# sa uwazane za OK. +# Ustawienie STOP_ON_WRONG na 1 powoduje przerwanie po napotkaniu +# testu, ktorego program nie przechodzi +############################################################################ +_run_ver_n_%: + make -s -C prog $* + @if [ "$(CHECKER)" -eq "1" ] ; then make -C prog $(ID)chk.e ; fi + @ACC_TERM=0;\ + STOP_ON_WRONG=0;\ + T_LIMIT=$(TIMELIMIT);\ + RT_LIMIT=$$(($(TIMELIMIT) * 10 + 100)); \ + PID='';\ + function sig_handler() { \ + if [ -n "$$PID" ]; then \ + kill -SIGKILL -$$PID >/dev/null 2>&1; \ + wait $$PID >/dev/null 2>&1; \ + fi; \ + }; \ + trap sig_handler SIGINT ; \ + for i in $(TESTS) ; do \ + j=out/`basename $$i .in`.out ; \ + \ + printf "%-11s " `basename $$i` ; \ + \ + rm -f $(TMP3);\ + rm -f $(TMP1);\ + setsid bash -c "ulimit -v $(MEMLIMIT); ulimit -t $$T_LIMIT ; \ + $(BIN_TIME) -f \"%U\" -o $(TMP2) prog/$* <$$i >$(TMP1)" >/dev/null 2>&1 & \ + PID=$$!; \ + setsid bash -c "sleep $$RT_LIMIT && kill -SIGKILL -$$PID" >/dev/null 2>&1 & \ + S_PID=$$!; \ + while ! kill -0 -$$S_PID >/dev/null 2>&1; do true; done; \ + wait $$PID >/dev/null 2>&1; \ + if [ "0" -eq "$$?" ]; then echo "OK" >$(TMP3); else echo "STOPPED" >$(TMP3); fi; \ + if [ "`cat $(TMP3)`" = OK ]; then TERM=0; else TERM=1; fi;\ + rm -f $(TMP3);\ + kill -SIGKILL -$$S_PID >/dev/null 2>&1; \ + if [ "0" -eq "$$?" ]; then TIMEOUT=0; else TIMEOUT=1; TERM=1; echo "$$RT_LIMIT.00" > $(TMP2); fi;\ + wait $$S_PID >/dev/null 2>&1; \ + TIME=`cat $(TMP2)` ; echo -n "$$TIME " ; \ + \ + if [ $$TERM -eq 0 ]; then \ + if [ "$(CHECKER)" -eq "1" ] ; then \ + prog/$(ID)chk.e $$i $(TMP1) $$j > $(TMP2) ; \ + RES=`head -n 1 $(TMP2)` ; \ + COMMENT=`head -n 2 $(TMP2) | tail -n 1` ; \ + if [ "$$RES" != "OK" ] ; then RES="WRONG_ANSWER" ; fi ; \ + else \ + if diff -q $$j $(TMP1) > /dev/null ; then \ + RES="OK" ; \ + else \ + RES="WRONG_ANSWER" ; \ + fi ; \ + COMMENT="" ; \ + fi ; \ + fi; \ + if [ $$TERM -eq 1 ]; then RES="WRONG (TIMEOUT)"; fi; \ + if [ $$TERM -eq 1 ] && [ "$$ACC_TERM" = 1 ]; then RES="OK"; fi; \ + if [ $$TIMEOUT -eq 1 ]; then RES="\x1b[31m!REAL TIMEOUT!\x1b[0m"; fi; \ + printf "$$RES $$COMMENT\n" ; \ + rm -f $(TMP1) $(TMP2) ; \ + if [ "$$RES" != "OK" ] && [ "$$STOP_ON_WRONG" = 1 ]; then exit 1; fi;\ + done + +_oirun_ver_n_%: + make -s -C prog $* + @if [ "$(CHECKER)" -eq "1" ] ; then make -C prog $(ID)chk.e ; fi + @ACC_TERM=0;\ + STOP_ON_WRONG=0;\ + T_LIMIT=$(TIMELIMIT);\ + RT_LIMIT=$$(($(TIMELIMIT) * 10 + 100)); \ + PID='';\ + function sig_handler() { \ + if [ -n "$$PID" ]; then \ + kill -SIGKILL -$$PID >/dev/null 2>&1; \ + wait $$PID >/dev/null 2>&1; \ + fi; \ + }; \ + trap sig_handler SIGINT ; \ + for i in $(TESTS) ; do \ + j=out/`basename $$i .in`.out ; \ + \ + printf "%-11s " `basename $$i` ; \ + \ + rm -f $(TMP3);\ + rm -f $(TMP1);\ + setsid bash -c "ulimit -v $(MEMLIMIT); ulimit -t $$T_LIMIT ; \ + $(OI_TIME) ./prog/$* <$$i >$(TMP1) 2>$(TMP2)" >/dev/null 2>&1 & \ + PID=$$!; \ + setsid bash -c "sleep $$RT_LIMIT && kill -SIGKILL -$$PID" >/dev/null 2>&1 & \ + S_PID=$$!; \ + while ! kill -0 -$$S_PID >/dev/null 2>&1; do true; done; \ + wait $$PID >/dev/null 2>&1; \ + if [ "0" -eq "$$?" ]; then echo "OK" >$(TMP3); else echo "STOPPED" >$(TMP3); fi; \ + if [ "`cat $(TMP3)`" = OK ]; then TERM=0; else TERM=1; fi;\ + rm -f $(TMP3);\ + kill -SIGKILL -$$S_PID >/dev/null 2>&1; \ + if [ "0" -eq "$$?" ]; then TIMEOUT=0; else TIMEOUT=1; TERM=1; echo "$$RT_LIMIT.00" > $(TMP2); fi;\ + wait $$S_PID >/dev/null 2>&1; \ + cat $(TMP2) | tail -n 1 | cut -d ' ' -f 2 | cut -d 's' -f 1 > $(TMP4); mv $(TMP4) $(TMP2); \ + TIME=`cat $(TMP2)` ; echo -n "$$TIME " ; \ + \ + if [ $$TERM -eq 0 ]; then \ + if [ "$(CHECKER)" -eq "1" ] ; then \ + prog/$(ID)chk.e $$i $(TMP1) $$j > $(TMP2) ; \ + RES=`head -n 1 $(TMP2)` ; \ + COMMENT=`head -n 2 $(TMP2) | tail -n 1` ; \ + if [ "$$RES" != "OK" ] ; then RES="WRONG_ANSWER" ; fi ; \ + else \ + if diff -q $$j $(TMP1) > /dev/null ; then \ + RES="OK" ; \ + else \ + RES="WRONG_ANSWER" ; \ + fi ; \ + COMMENT="" ; \ + fi ; \ + fi; \ + if [ $$TERM -eq 1 ]; then RES="WRONG (TIMEOUT)"; fi; \ + if [ $$TERM -eq 1 ] && [ "$$ACC_TERM" = 1 ]; then RES="OK"; fi; \ + if [ $$TIMEOUT -eq 1 ]; then RES="\x1b[31m!REAL TIMEOUT!\x1b[0m"; fi; \ + printf "$$RES $$COMMENT\n" ; \ + rm -f $(TMP1) $(TMP2) ; \ + if [ "$$RES" != "OK" ] && [ "$$STOP_ON_WRONG" = 1 ]; then exit 1; fi;\ + done + +_jrun_ver_n_%: + make -s -C prog $* + @if [ "$(CHECKER)" -eq "1" ] ; then make -C prog $(ID)chk.e ; fi + @ACC_TERM=0;\ + STOP_ON_WRONG=0;\ + T_LIMIT=$(TIMELIMIT);\ + RT_LIMIT=$$(($(TIMELIMIT) * 10 + 100)); \ + PID='';\ + function sig_handler() { \ + if [ -n "$$PID" ]; then \ + kill -SIGKILL -$$PID >/dev/null 2>&1; \ + wait $$PID >/dev/null 2>&1; \ + fi; \ + }; \ + trap sig_handler SIGINT ; \ + for i in $(TESTS) ; do \ + j=out/`basename $$i .in`.out ; \ + \ + printf "%-11s " `basename $$i` ; \ + \ + rm -f $(TMP3);\ + rm -f $(TMP1);\ + setsid bash -c "$(BIN_TIME) -f \"%U\" -o $(TMP2) prog/$* <$$i >$(TMP1)" >/dev/null 2>&1 & \ + PID=$$!; \ + setsid bash -c "sleep $$RT_LIMIT && kill -SIGKILL -$$PID" >/dev/null 2>&1 & \ + S_PID=$$!; \ + while ! kill -0 -$$S_PID >/dev/null 2>&1; do true; done; \ + wait $$PID >/dev/null 2>&1; \ + if [ "0" -eq "$$?" ]; then echo "OK" >$(TMP3); else echo "STOPPED" >$(TMP3); fi; \ + if [ "`cat $(TMP3)`" = OK ]; then TERM=0; else TERM=1; fi;\ + rm -f $(TMP3);\ + kill -SIGKILL -$$S_PID >/dev/null 2>&1; \ + if [ "0" -eq "$$?" ]; then TIMEOUT=0; else TIMEOUT=1; TERM=1; echo "$$RT_LIMIT.00" > $(TMP2); fi;\ + wait $$S_PID >/dev/null 2>&1; \ + TIME=`cat $(TMP2)` ; echo -n "$$TIME " ; \ + \ + if [ $$TERM -eq 0 ]; then \ + if [ "$(CHECKER)" -eq "1" ] ; then \ + prog/$(ID)chk.e $$i $(TMP1) $$j > $(TMP2) ; \ + RES=`head -n 1 $(TMP2)` ; \ + COMMENT=`head -n 2 $(TMP2) | tail -n 1` ; \ + if [ "$$RES" != "OK" ] ; then RES="WRONG_ANSWER" ; fi ; \ + else \ + if diff -q $$j $(TMP1) > /dev/null ; then \ + RES="OK" ; \ + else \ + RES="WRONG_ANSWER" ; \ + fi ; \ + COMMENT="" ; \ + fi ; \ + fi; \ + if [ $$TERM -eq 1 ]; then RES="WRONG (TIMEOUT)"; fi; \ + if [ $$TERM -eq 1 ] && [ "$$ACC_TERM" = 1 ]; then RES="OK"; fi; \ + if [ $$TIMEOUT -eq 1 ]; then RES="\x1b[31m!REAL TIMEOUT!\x1b[0m"; fi; \ + printf "$$RES $$COMMENT\n" ; \ + rm -f $(TMP1) $(TMP2) ; \ + if [ "$$RES" != "OK" ] && [ "$$STOP_ON_WRONG" = 1 ]; then exit 1; fi;\ + done + +_run_ver_o_%: + make -s -C prog $* + @if [ "$(CHECKER)" -eq "1" ] ; then make -C prog $(ID)chk.e ; fi + @ACC_TERM=0;\ + STOP_ON_WRONG=1;\ + T_LIMIT=$(TIMELIMIT);\ + RT_LIMIT=$$(($(TIMELIMIT) * 10 + 100)); \ + PID='';\ + function sig_handler() { \ + if [ -n "$$PID" ]; then \ + kill -SIGKILL -$$PID >/dev/null 2>&1; \ + wait $$PID >/dev/null 2>&1; \ + fi; \ + }; \ + trap sig_handler SIGINT ; \ + for i in $(TESTS) ; do \ + j=out/`basename $$i .in`.out ; \ + \ + printf "%-11s " `basename $$i` ; \ + \ + rm -f $(TMP3);\ + rm -f $(TMP1);\ + setsid bash -c "ulimit -v $(MEMLIMIT); ulimit -t $$T_LIMIT ; \ + $(BIN_TIME) -f \"%U\" -o $(TMP2) prog/$* <$$i >$(TMP1)" >/dev/null 2>&1 & \ + PID=$$!; \ + setsid bash -c "sleep $$RT_LIMIT && kill -SIGKILL -$$PID" >/dev/null 2>&1 & \ + S_PID=$$!; \ + while ! kill -0 -$$S_PID >/dev/null 2>&1; do true; done; \ + wait $$PID >/dev/null 2>&1; \ + if [ "0" -eq "$$?" ]; then echo "OK" >$(TMP3); else echo "STOPPED" >$(TMP3); fi; \ + if [ "`cat $(TMP3)`" = OK ]; then TERM=0; else TERM=1; fi;\ + rm -f $(TMP3);\ + kill -SIGKILL -$$S_PID >/dev/null 2>&1; \ + if [ "0" -eq "$$?" ]; then TIMEOUT=0; else TIMEOUT=1; TERM=1; echo "$$RT_LIMIT.00" > $(TMP2); fi;\ + wait $$S_PID >/dev/null 2>&1; \ + TIME=`cat $(TMP2)` ; echo -n "$$TIME " ; \ + \ + if [ $$TERM -eq 0 ]; then \ + if [ "$(CHECKER)" -eq "1" ] ; then \ + prog/$(ID)chk.e $$i $(TMP1) $$j > $(TMP2) ; \ + RES=`head -n 1 $(TMP2)` ; \ + COMMENT=`head -n 2 $(TMP2) | tail -n 1` ; \ + if [ "$$RES" != "OK" ] ; then RES="WRONG_ANSWER" ; fi ; \ + else \ + if diff -q $$j $(TMP1) > /dev/null ; then \ + RES="OK" ; \ + else \ + RES="WRONG_ANSWER" ; \ + fi ; \ + COMMENT="" ; \ + fi ; \ + fi; \ + if [ $$TERM -eq 1 ]; then RES="WRONG (TIMEOUT)"; fi; \ + if [ $$TERM -eq 1 ] && [ "$$ACC_TERM" = 1 ]; then RES="OK"; fi; \ + if [ $$TIMEOUT -eq 1 ]; then RES="\x1b[31m!REAL TIMEOUT!\x1b[0m"; fi; \ + printf "$$RES $$COMMENT\n" ; \ + rm -f $(TMP1) $(TMP2) ; \ + if [ "$$RES" != "OK" ] && [ "$$STOP_ON_WRONG" = 1 ]; then exit 1; fi;\ + done + +_jrun_ver_o_%: + make -s -C prog $* + @if [ "$(CHECKER)" -eq "1" ] ; then make -C prog $(ID)chk.e ; fi + @ACC_TERM=0;\ + STOP_ON_WRONG=1;\ + T_LIMIT=$(TIMELIMIT);\ + RT_LIMIT=$$(($(TIMELIMIT) * 10 + 100)); \ + PID='';\ + function sig_handler() { \ + if [ -n "$$PID" ]; then \ + kill -SIGKILL -$$PID >/dev/null 2>&1; \ + wait $$PID >/dev/null 2>&1; \ + fi; \ + }; \ + trap sig_handler SIGINT ; \ + for i in $(TESTS) ; do \ + j=out/`basename $$i .in`.out ; \ + \ + printf "%-11s " `basename $$i` ; \ + \ + rm -f $(TMP3);\ + rm -f $(TMP1);\ + setsid bash -c "ulimit -t $$T_LIMIT ; \ + $(BIN_TIME) -f \"%U\" -o $(TMP2) prog/$* <$$i >$(TMP1)" >/dev/null 2>&1 & \ + PID=$$!; \ + setsid bash -c "sleep $$RT_LIMIT && kill -SIGKILL -$$PID" >/dev/null 2>&1 & \ + S_PID=$$!; \ + while ! kill -0 -$$S_PID >/dev/null 2>&1; do true; done; \ + wait $$PID >/dev/null 2>&1; \ + if [ "0" -eq "$$?" ]; then echo "OK" >$(TMP3); else echo "STOPPED" >$(TMP3); fi; \ + if [ "`cat $(TMP3)`" = OK ]; then TERM=0; else TERM=1; fi;\ + rm -f $(TMP3);\ + kill -SIGKILL -$$S_PID >/dev/null 2>&1; \ + if [ "0" -eq "$$?" ]; then TIMEOUT=0; else TIMEOUT=1; TERM=1; echo "$$RT_LIMIT.00" > $(TMP2); fi;\ + wait $$S_PID >/dev/null 2>&1; \ + TIME=`cat $(TMP2)` ; echo -n "$$TIME " ; \ + \ + if [ $$TERM -eq 0 ]; then \ + if [ "$(CHECKER)" -eq "1" ] ; then \ + prog/$(ID)chk.e $$i $(TMP1) $$j > $(TMP2) ; \ + RES=`head -n 1 $(TMP2)` ; \ + COMMENT=`head -n 2 $(TMP2) | tail -n 1` ; \ + if [ "$$RES" != "OK" ] ; then RES="WRONG_ANSWER" ; fi ; \ + else \ + if diff -q $$j $(TMP1) > /dev/null ; then \ + RES="OK" ; \ + else \ + RES="WRONG_ANSWER" ; \ + fi ; \ + COMMENT="" ; \ + fi ; \ + fi; \ + if [ $$TERM -eq 1 ]; then RES="WRONG (TIMEOUT)"; fi; \ + if [ $$TERM -eq 1 ] && [ "$$ACC_TERM" = 1 ]; then RES="OK"; fi; \ + if [ $$TIMEOUT -eq 1 ]; then RES="\x1b[31m!REAL TIMEOUT!\x1b[0m"; fi; \ + printf "$$RES $$COMMENT\n" ; \ + rm -f $(TMP1) $(TMP2) ; \ + if [ "$$RES" != "OK" ] && [ "$$STOP_ON_WRONG" = 1 ]; then exit 1; fi;\ + done + +_run_ver_s_%: + make -s -C prog $* + @if [ "$(CHECKER)" -eq "1" ] ; then make -C prog $(ID)chk.e ; fi + @ACC_TERM=1;\ + STOP_ON_WRONG=1;\ + T_LIMIT=$(SLOW_TIMELIMIT);\ + RT_LIMIT=$$(($(SLOW_TIMELIMIT) * 10 + 100)); \ + PID='';\ + function sig_handler() { \ + if [ -n "$$PID" ]; then \ + kill -SIGKILL -$$PID >/dev/null 2>&1; \ + wait $$PID >/dev/null 2>&1; \ + fi; \ + }; \ + trap sig_handler SIGINT ; \ + for i in $(TESTS) ; do \ + j=out/`basename $$i .in`.out ; \ + \ + printf "%-11s " `basename $$i` ; \ + \ + rm -f $(TMP3);\ + rm -f $(TMP1);\ + setsid bash -c "ulimit -v $(MEMLIMIT); ulimit -t $$T_LIMIT ; \ + $(BIN_TIME) -f \"%U\" -o $(TMP2) prog/$* <$$i >$(TMP1)" >/dev/null 2>&1 & \ + PID=$$!; \ + setsid bash -c "sleep $$RT_LIMIT && kill -SIGKILL -$$PID" >/dev/null 2>&1 & \ + S_PID=$$!; \ + while ! kill -0 -$$S_PID >/dev/null 2>&1; do true; done; \ + wait $$PID >/dev/null 2>&1; \ + if [ "0" -eq "$$?" ]; then echo "OK" >$(TMP3); else echo "STOPPED" >$(TMP3); fi; \ + if [ "`cat $(TMP3)`" = OK ]; then TERM=0; else TERM=1; fi;\ + rm -f $(TMP3);\ + kill -SIGKILL -$$S_PID >/dev/null 2>&1; \ + if [ "0" -eq "$$?" ]; then TIMEOUT=0; else TIMEOUT=1; TERM=1; echo "$$RT_LIMIT.00" > $(TMP2); fi;\ + wait $$S_PID >/dev/null 2>&1; \ + TIME=`cat $(TMP2)` ; echo -n "$$TIME " ; \ + \ + if [ $$TERM -eq 0 ]; then \ + if [ "$(CHECKER)" -eq "1" ] ; then \ + prog/$(ID)chk.e $$i $(TMP1) $$j > $(TMP2) ; \ + RES=`head -n 1 $(TMP2)` ; \ + COMMENT=`head -n 2 $(TMP2) | tail -n 1` ; \ + if [ "$$RES" != "OK" ] ; then RES="WRONG_ANSWER" ; fi ; \ + else \ + if diff -q $$j $(TMP1) > /dev/null ; then \ + RES="OK" ; \ + else \ + RES="WRONG_ANSWER" ; \ + fi ; \ + COMMENT="" ; \ + fi ; \ + fi; \ + if [ $$TERM -eq 1 ]; then RES="WRONG (TIMEOUT)"; fi; \ + if [ $$TERM -eq 1 ] && [ "$$ACC_TERM" = 1 ]; then RES="OK"; fi; \ + if [ $$TIMEOUT -eq 1 ]; then RES="\x1b[31m!REAL TIMEOUT!\x1b[0m"; fi; \ + printf "$$RES $$COMMENT\n" ; \ + rm -f $(TMP1) $(TMP2) ; \ + if [ "$$RES" != "OK" ] && [ "$$STOP_ON_WRONG" = 1 ]; then exit 1; fi;\ + done + +_jrun_ver_s_%: + make -s -C prog $* + @if [ "$(CHECKER)" -eq "1" ] ; then make -C prog $(ID)chk.e ; fi + @ACC_TERM=1;\ + STOP_ON_WRONG=1;\ + T_LIMIT=$(SLOW_TIMELIMIT);\ + RT_LIMIT=$$(($(SLOW_TIMELIMIT) * 10 + 100)); \ + PID='';\ + function sig_handler() { \ + if [ -n "$$PID" ]; then \ + kill -SIGKILL -$$PID >/dev/null 2>&1; \ + wait $$PID >/dev/null 2>&1; \ + fi; \ + }; \ + trap sig_handler SIGINT ; \ + for i in $(TESTS) ; do \ + j=out/`basename $$i .in`.out ; \ + \ + printf "%-11s " `basename $$i` ; \ + \ + rm -f $(TMP3);\ + rm -f $(TMP1);\ + setsid bash -c "ulimit -t $$T_LIMIT ; \ + $(BIN_TIME) -f \"%U\" -o $(TMP2) prog/$* <$$i >$(TMP1)" >/dev/null 2>&1 & \ + PID=$$!; \ + setsid bash -c "sleep $$RT_LIMIT && kill -SIGKILL -$$PID" >/dev/null 2>&1 & \ + S_PID=$$!; \ + while ! kill -0 -$$S_PID >/dev/null 2>&1; do true; done; \ + wait $$PID >/dev/null 2>&1; \ + if [ "0" -eq "$$?" ]; then echo "OK" >$(TMP3); else echo "STOPPED" >$(TMP3); fi; \ + if [ "`cat $(TMP3)`" = OK ]; then TERM=0; else TERM=1; fi;\ + rm -f $(TMP3);\ + kill -SIGKILL -$$S_PID >/dev/null 2>&1; \ + if [ "0" -eq "$$?" ]; then TIMEOUT=0; else TIMEOUT=1; TERM=1; echo "$$RT_LIMIT.00" > $(TMP2); fi;\ + wait $$S_PID >/dev/null 2>&1; \ + TIME=`cat $(TMP2)` ; echo -n "$$TIME " ; \ + \ + if [ $$TERM -eq 0 ]; then \ + if [ "$(CHECKER)" -eq "1" ] ; then \ + prog/$(ID)chk.e $$i $(TMP1) $$j > $(TMP2) ; \ + RES=`head -n 1 $(TMP2)` ; \ + COMMENT=`head -n 2 $(TMP2) | tail -n 1` ; \ + if [ "$$RES" != "OK" ] ; then RES="WRONG_ANSWER" ; fi ; \ + else \ + if diff -q $$j $(TMP1) > /dev/null ; then \ + RES="OK" ; \ + else \ + RES="WRONG_ANSWER" ; \ + fi ; \ + COMMENT="" ; \ + fi ; \ + fi; \ + if [ $$TERM -eq 1 ]; then RES="WRONG (TIMEOUT)"; fi; \ + if [ $$TERM -eq 1 ] && [ "$$ACC_TERM" = 1 ]; then RES="OK"; fi; \ + if [ $$TIMEOUT -eq 1 ]; then RES="\x1b[31m!REAL TIMEOUT!\x1b[0m"; fi; \ + printf "$$RES $$COMMENT\n" ; \ + rm -f $(TMP1) $(TMP2) ; \ + if [ "$$RES" != "OK" ] && [ "$$STOP_ON_WRONG" = 1 ]; then exit 1; fi;\ + done + + +define get_rep_result + PID=$$!; \ + setsid bash -c "sleep $$RT_LIMIT && kill -SIGKILL -$$PID" >/dev/null 2>&1 & \ + S_PID=$$!; \ + while ! kill -0 -$$S_PID >/dev/null 2>&1; do true; done; \ + wait $$PID >/dev/null 2>&1; \ + RES=$$?; \ + kill -SIGKILL -$$S_PID >/dev/null 2>&1; \ + if [ "0" -eq "$$?" ]; then TIMEOUT=0; else TIMEOUT=1; TERM=1; echo "$$RT_LIMIT.00" > $(TMP2); fi;\ + wait $$S_PID >/dev/null 2>&1; \ + TIME=`cat $(TMP2)`; \ + \ + if [ "$$RES" -eq "0" ]; then \ + if [ "$(CHECKER)" -eq "1" ] ; then \ + prog/$(ID)chk.e $$i $(TMP1) $$j > $(TMP2) ; \ + RES=`head -n 1 $(TMP2)` ; \ + if [ "$$RES" != "OK" ] ; then RES="WRONG_ANSWER" ; fi ; \ + else \ + if diff -q $$j $(TMP1) > /dev/null ; then \ + RES="OK" ; \ + else \ + RES="WRONG_ANSWER" ; \ + fi ; \ + fi ; \ + elif [ "$$TIMEOUT" -eq "1" ]; then \ + RES="RT_TIMEOUT"; \ + TIME=$$RT_LIMIT; \ + elif [ "$$RES" -eq "137" ]; then \ + RES="TIMEOUT"; \ + TIME=$$T_LIMIT; \ + else \ + RES="RTE"; \ + TIME=`tail -n 1 $(TMP2)`; \ + fi; \ + rm -f $(TMP1) $(TMP2) ; \ + \ + printf "%ss\n" "$$RES" "$$TIME" +endef + +define get_oirep_result + PID=$$!; \ + setsid bash -c "sleep $$RT_LIMIT && kill -SIGKILL -$$PID" >/dev/null 2>&1 & \ + S_PID=$$!; \ + while ! kill -0 -$$S_PID >/dev/null 2>&1; do true; done; \ + wait $$PID >/dev/null 2>&1; \ + RES=$$?; \ + kill -SIGKILL -$$S_PID >/dev/null 2>&1; \ + if [ "0" -eq "$$?" ]; then TIMEOUT=0; else TIMEOUT=1; TERM=1; echo "$$RT_LIMIT.00" > $(TMP2); fi;\ + wait $$S_PID >/dev/null 2>&1; \ + cat $(TMP2) | tail -n 1 | cut -d ' ' -f 2 | cut -d 's' -f 1 > $(TMP4); mv $(TMP4) $(TMP2); \ + TIME=`cat $(TMP2)`; \ + \ + if [ "$$RES" -eq "0" ]; then \ + if [ "$(CHECKER)" -eq "1" ] ; then \ + prog/$(ID)chk.e $$i $(TMP1) $$j > $(TMP2) ; \ + RES=`head -n 1 $(TMP2)` ; \ + if [ "$$RES" != "OK" ] ; then RES="WRONG_ANSWER" ; fi ; \ + else \ + if diff -q $$j $(TMP1) > /dev/null ; then \ + RES="OK" ; \ + else \ + RES="WRONG_ANSWER" ; \ + fi ; \ + fi ; \ + elif [ "$$TIMEOUT" -eq "1" ]; then \ + RES="RT_TIMEOUT"; \ + TIME=$$RT_LIMIT; \ + elif [ "$$RES" -eq "137" ]; then \ + RES="TIMEOUT"; \ + TIME=$$T_LIMIT; \ + else \ + RES="RTE"; \ + TIME=`tail -n 1 $(TMP2)`; \ + fi; \ + rm -f $(TMP1) $(TMP2) ; \ + \ + printf "%ss\n" "$$RES" "$$TIME" +endef + +_jrun_rep_o_%: + PROG="`basename $* | rev | cut -d. -f2- | rev`.e"; \ + LANG="`basename $* | rev | cut -d. -f1 | rev`"; \ + T_LIMIT=$(TIMELIMIT);\ + RT_LIMIT=$$(($(TIMELIMIT) * 10 + 100)); \ + PID='';\ + function sig_handler() { \ + if [ -n "$$PID" ]; then \ + kill -SIGKILL -$$PID >/dev/null 2>&1; \ + wait $$PID >/dev/null 2>&1; \ + fi; \ + }; \ + trap sig_handler SIGINT ; \ + echo "$$LANG$$PROG" ; \ + for i in $(TESTS) ; do \ + j=out/`basename $$i .in`.out ; \ + \ + rm -f $(TMP3) $(TMP1);\ + setsid bash -c "ulimit -t $$T_LIMIT ; \ + $(BIN_TIME) -f \"%U\" -o $(TMP2) prog/$$PROG <$$i >$(TMP1)" >/dev/null 2>&1 & \ + $(get_rep_result); \ + done + +_jrun_rep_s_%: + PROG="`basename $* | rev | cut -d. -f2- | rev`.e"; \ + LANG="`basename $* | rev | cut -d. -f1 | rev`"; \ + T_LIMIT=$(SLOW_TIMELIMIT);\ + RT_LIMIT=$$(($(SLOW_TIMELIMIT) * 10 + 100)); \ + PID='';\ + function sig_handler() { \ + if [ -n "$$PID" ]; then \ + kill -SIGKILL -$$PID >/dev/null 2>&1; \ + wait $$PID >/dev/null 2>&1; \ + fi; \ + }; \ + trap sig_handler SIGINT ; \ + echo "$$LANG$$PROG" ; \ + for i in $(TESTS) ; do \ + j=out/`basename $$i .in`.out ; \ + \ + rm -f $(TMP3) $(TMP1);\ + setsid bash -c "ulimit -t $$T_LIMIT ; \ + $(BIN_TIME) -f \"%U\" -o $(TMP2) prog/$$PROG <$$i >$(TMP1)" >/dev/null 2>&1 & \ + $(get_rep_result); \ + done + +_run_rep_o_%: + PROG="`basename $* | rev | cut -d. -f2- | rev`.e"; \ + LANG="`basename $* | rev | cut -d. -f1 | rev`"; \ + T_LIMIT=$(TIMELIMIT);\ + RT_LIMIT=$$(($(TIMELIMIT) * 10 + 100)); \ + PID='';\ + function sig_handler() { \ + if [ -n "$$PID" ]; then \ + kill -SIGKILL -$$PID >/dev/null 2>&1; \ + wait $$PID >/dev/null 2>&1; \ + fi; \ + }; \ + trap sig_handler SIGINT ; \ + echo "$$LANG$$PROG" ; \ + for i in $(TESTS) ; do \ + j=out/`basename $$i .in`.out ; \ + \ + rm -f $(TMP3) $(TMP1) ;\ + setsid bash -c "ulimit -v $(MEMLIMIT); ulimit -t $$T_LIMIT ; \ + $(BIN_TIME) -f \"%U\" -o $(TMP2) prog/$$PROG <$$i >$(TMP1)" >/dev/null 2>&1 & \ + $(get_rep_result); \ + done + +_run_rep_s_%: + PROG="`basename $* | rev | cut -d. -f2- | rev`.e"; \ + LANG="`basename $* | rev | cut -d. -f1 | rev`"; \ + T_LIMIT=$(SLOW_TIMELIMIT);\ + RT_LIMIT=$$(($(SLOW_TIMELIMIT) * 10 + 100)); \ + PID='';\ + function sig_handler() { \ + if [ -n "$$PID" ]; then \ + kill -SIGKILL -$$PID >/dev/null 2>&1; \ + wait $$PID >/dev/null 2>&1; \ + fi; \ + }; \ + trap sig_handler SIGINT ; \ + echo "$$LANG$$PROG" ; \ + for i in $(TESTS) ; do \ + j=out/`basename $$i .in`.out ; \ + \ + rm -f $(TMP3) $(TMP1);\ + setsid bash -c "ulimit -v $(MEMLIMIT); ulimit -t $$T_LIMIT ; \ + $(BIN_TIME) -f \"%U\" -o $(TMP2) prog/$$PROG <$$i >$(TMP1)" >/dev/null 2>&1 & \ + $(get_rep_result); \ + done + +_oirun_rep_o_%: + PROG="`basename $* | rev | cut -d. -f2- | rev`.e"; \ + LANG="`basename $* | rev | cut -d. -f1 | rev`"; \ + T_LIMIT=$(TIMELIMIT);\ + RT_LIMIT=$$(($(TIMELIMIT) * 10 + 100)); \ + PID='';\ + function sig_handler() { \ + if [ -n "$$PID" ]; then \ + kill -SIGKILL -$$PID >/dev/null 2>&1; \ + wait $$PID >/dev/null 2>&1; \ + fi; \ + }; \ + trap sig_handler SIGINT ; \ + echo "$$LANG$$PROG" ; \ + for i in $(TESTS) ; do \ + j=out/`basename $$i .in`.out ; \ + \ + rm -f $(TMP3) $(TMP1) ;\ + setsid bash -c "ulimit -v $(MEMLIMIT); ulimit -t $$T_LIMIT ; \ + $(OI_TIME) ./prog/$$PROG <$$i >$(TMP1) 2>$(TMP2)" >/dev/null 2>&1 & \ + $(get_oirep_result); \ + done + +_oirun_rep_s_%: + PROG="`basename $* | rev | cut -d. -f2- | rev`.e"; \ + LANG="`basename $* | rev | cut -d. -f1 | rev`"; \ + T_LIMIT=$(SLOW_TIMELIMIT);\ + RT_LIMIT=$$(($(SLOW_TIMELIMIT) * 10 + 100)); \ + PID='';\ + function sig_handler() { \ + if [ -n "$$PID" ]; then \ + kill -SIGKILL -$$PID >/dev/null 2>&1; \ + wait $$PID >/dev/null 2>&1; \ + fi; \ + }; \ + trap sig_handler SIGINT ; \ + echo "$$LANG$$PROG" ; \ + for i in $(TESTS) ; do \ + j=out/`basename $$i .in`.out ; \ + \ + rm -f $(TMP3) $(TMP1);\ + setsid bash -c "ulimit -v $(MEMLIMIT); ulimit -t $$T_LIMIT ; \ + $(OI_TIME) ./prog/$$PROG <$$i >$(TMP1) 2>$(TMP2)" >/dev/null 2>&1 & \ + $(get_oirep_result); \ + done + +valgrind: + make -C prog ${ID}.valgrind + @echo "

Valgrind

\n\n" + @PROG="${ID}.valgrind"; \ + RT_LIMIT=$$(($(TIMELIMIT) * 15 + 150)); \ + PID='';\ + function sig_handler() { \ + if [ -n "$$PID" ]; then \ + kill -SIGKILL -$$PID >/dev/null 2>&1; \ + wait $$PID >/dev/null 2>&1; \ + fi; \ + }; \ + trap sig_handler SIGINT ; \ + for i in $(TESTS) ; do \ + j=out/`basename $$i .in`.out ; \ + \ + rm -f $(TMP3) $(TMP1) ;\ + setsid bash -c "$(BIN_TIME) -f \"%U\" -o $(TMP2) \ + valgrind --error-exitcode=1 --leak-check=no prog/$$PROG <$$i >$(TMP1)" >/dev/null 2>&1 & \ + $(get_rep_result); \ + done + @echo "
\n" diff --git a/makefile.prog b/makefile.prog new file mode 100644 index 0000000..ecd6366 --- /dev/null +++ b/makefile.prog @@ -0,0 +1,71 @@ +# +# ogolny makefile do kompilowania programow +# 2005.07.22 - modyfikacja parametrow kompilacji (aiwanicki) +# 2009.12.05 - dodanie usuwania plikow .valgrind +# 2012.10.13 - opcja -U-FORTIFY_SOURCE +# + +include ../makefile.in + +GCC_OPT = -Wall -lm -O2 -Wno-unused-result -Werror ${CFLAGS} +GPP_OPT = -Wall -lm -O2 -Wno-unused-result -Werror -I ~/.sinol ${CXXFLAGS} +PPC_OPT = -O2 -XS -Xt -Ci -Cr -Co -gl -g ${PASFLAGS} + +PRG_C = $(wildcard *.c) +PRG_CPP = $(wildcard *.cpp) +PRG_JAVA = $(wildcard *.java) +PRG_PAS = $(wildcard *.pas) +PRG_ML = $(wildcard *.ml) +PRG = $(PRG_C) $(PRG_CPP) $(PRG_PAS) $(PRG_ML) + +EXE_C = $(patsubst %.c,%.e,$(PRG_C)) +EXE_CPP = $(patsubst %.cpp,%.e,$(PRG_CPP)) +EXE_JAVA = $(patsubst %.java,%.e,$(PRG_JAVA)) +EXE_PAS = $(patsubst %.pas,%.e,$(PRG_PAS)) +EXE_ML = $(patsubst %.ml,%.e,$(PRG_ML)) +EXE = $(EXE_C) $(EXE_CPP) $(EXE_JAVA) $(EXE_PAS) $(EXE_ML) + +all: $(EXE) ${ID}.valgrind + +%.e: %.pas + fpc $(PPC_OPT) $*.pas ${PAS_LDFLAGS} + mv $* $*.e + +%.e: %.c + gcc $(GCC_OPT) $^ -o $*.e ${C_LDFLAGS} + +%.e: %.cpp + g++ $(GPP_OPT) $^ -o $*.e ${CXX_LDFLAGS} + +%.e: %.java + javac $(JAVA_OPT) $^ + MEM=$$(($(MEMLIMIT) / 1000))M; \ + echo "ulimit -v unlimited ; java -client -Xmx$$MEM -Xms$$MEM -Xss$$MEM -cp \`dirname \$$0\` $*" > $*.e + chmod 755 $*.e + +%.e: %.ml + ocamlopt $^ -o $*.e + rm -f *.cmx + rm -f *.cmi + rm -f *.cmo + +%.valgrind: %.c + gcc -O2 ${CFLAGS} -g -lm $^ -o $*.valgrind ${C_LDFLAGS} + +%.valgrind: %.cpp + g++ -O2 ${CXXFLAGS} -g -lm $^ -o $*.valgrind ${CXX_LDFLAGS} + +%.valgrind: %.pas %.e + cp $*.e $*.valgrind + +clean: + rm -f *.o + rm -f *.e + rm -f *.valgrind + rm -f *~ + rm -f *.class + rm -f *.cmx + rm -f *.cmi + rm -f *.cmo + +-include makefile.user diff --git a/oi.h b/oi.h new file mode 100644 index 0000000..0ff7f69 --- /dev/null +++ b/oi.h @@ -0,0 +1,637 @@ +/* + oi.h - pakiet funkcji do pisania weryfikatorow wejsc (inwer) i wyjsc (chk) + Wersja: 1.3 + Autor: Piotr Niedzwiedz + W razie problemow, bledow lub pomyslow na ulepszenie pisac na dzwiedziux@gmail.com + + Historia: + 1.1: Poprawka readInt (liczby ujemne). + 1.2: Zmiana nazwy, dodano namespace oi, dodano Random i MultipleRecursiveGenerator + 1.3: Poprawienie stylu kodu(Google code style). + Zablokowano konstruktory kopiujące. + Dopisano randomShuffle. + Dopisano randInt i zmieniono nazwy metod Random na bardziej intiucyjne. +*/ + +#ifndef OI_LIB_OI_H_ +#define OI_LIB_OI_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +using std::vector; +using std::max; +using std::swap; + +// We want prevent usage of standard random function. +int rand(){ + fprintf(stderr, "DONT USE rand or random_shuffle!\nUse oi::Random class.\n"); + exit(1); + return 0; +} + +namespace oi { + +enum Lang { + EN = 0, + PL = 1 +}; + +class Reader; + +class Scanner { + protected: + static const int realNumbersLimit = 20; + + Lang lang; + Reader* reader; + void(*end)(const char* msg, int line, int position); + + void readULL(unsigned long long int limit, unsigned long long int &val, bool &sign); + void readLDB(long double limit, long double &val, bool &sign); + + public: + Scanner(const char* file, Lang _lang = Lang(EN)); + Scanner(const char* file, void(*endf)(const char* msg, int line, int position), Lang _lang = Lang(EN)); + Scanner(FILE* input, Lang _lang = Lang(EN)); + Scanner(FILE* input, void(*endf)(const char* msg, int line, int position), Lang _lang = Lang(EN)); + ~Scanner(); + + void error(const char* msg); + + // Skips all whitespaces until any occurrence of EOF or other non-white character. + int skipWhitespaces(); + // Skips all whitespaces until any occurrence of EOF, EOLN or other non-white character. + int skipWhitespacesUntilEOLN(); + + int readInt(int min_value = INT_MIN, int max_value = INT_MAX); + unsigned int readUInt(unsigned int min_value = 0, unsigned int max_value = UINT_MAX); + long long readLL(long long int min_value = LLONG_MIN, long long int max_value = LLONG_MAX); + unsigned long long readULL(unsigned long long int min_value = 0, unsigned long long int max_value = ULLONG_MAX); + + float readFloat(float min_value, float max_value); + double readDouble(double min_value, double max_value); + long double readLDouble(long double min_value, long double max_value); + + char readChar(); + + // Newline character is read, but isn't added to s + int readLine(char* s, int size); + + // Reads a string until occurrence of EOF, EOLN or whitespace. + // Returns the number of characters read (possibly 0). + int readString(char* s, int size); + + void readEof(); + void readEofOrEoln(); + void readEoln(); + void readSpace(); + void readTab(); + + bool isEOF(); + private: + Scanner(Scanner &s) {} +}; + +class MultipleRecursiveGenerator; + +class Random { + public: + Random(); + explicit Random(unsigned int seed); + ~Random(); + void setSeed(unsigned int seed); + + // Random number from range <0..2^31 - 1> + int rand(); + + // randS* - signed * + // randU* - unsigned * + int randSInt(); + unsigned int randUInt(); + long long randSLL(); + unsigned long long randULL(); + + template + void randomShuffle(RandomAccessIterator first, RandomAccessIterator last); + + private: + Random(Random &r) {} + MultipleRecursiveGenerator* mrg_; + void init(); +}; + +class MultipleRecursiveGenerator { + public: + MultipleRecursiveGenerator(unsigned int modulo, + const vector &A); + void setSeed(unsigned int seed); + unsigned int next16Bits(); + + private: + int n_; + unsigned int modulo_; + vector A_; + vector X_; +}; + +class Reader { + private: + static const int bufferSize = 1000; + char Buffer[bufferSize]; + int head, tail; + int line, position; + void fillBuffer(); + FILE* input; + public: + explicit Reader(const char* file); + explicit Reader(FILE* _input); + ~Reader(); + bool isEOF(); + int getLine() {return line;} + int getPosition() {return position;} + char read(bool move = false); + private: + Reader(Reader &r) {}; +}; + + +const char* msgLeadingZeros[]= { + "Leading zeros", + "Zera wiodace"}; +const char* msgMinusZero[]= { + "Minus zero -0", + "Minus zero -0"}; +const char* msgNoNumber[]= { + "No number", + "Brak liczby"}; +const char* msgNoChar[]= { + "No char - EOF", + "Brak znaku - EOF"}; +const char* msgNotEof[]= { + "Not EOF", + "Brak konca pliku"}; +const char* msgNotEoln[]= { + "Not EOLN", + "Brak konca linii"}; +const char* msgNotEofOrEoln[]= { + "Not EOF or EOLN", + "Brak konca linii i brak konca pliku"}; +const char* msgNotSpace[]= { + "Not space", + "Brak spacji"}; +const char* msgNotTab[]= { + "Not tab", + "Brak znaku tabulacji"}; +const char* msgOutOfRangeInt[]= { + "Integer out of range", + "Liczba calkowita spoza zakresu"}; +const char* msgOutOfRangeReal[]= { + "Real number out of range", + "Liczba rzeczywista spoza zakresu"}; +const char* msgRealNumberLimit[]= { + "Too many digits after dot", + "Za duzo cyfr po kropce dziesietnej"}; +const char* msgBadRealNumberFormat[]= { + "Bad real number format", + "Niepoprawny format liczby rzeczywistej"}; + +// ------------------------------- Implementation ----------------------------- + +typedef unsigned long long ull; +typedef unsigned int uint; +typedef long long ll; +typedef long double ldb; + + +inline bool isDot(char x) { + return x == '.'; +} + +inline bool isEOLN(char x) { + return x == '\n'; +} + +inline bool isMinus(char x) { + return x == '-'; +} + +inline bool isSpace(char x) { + return x == ' '; +} + +inline bool isTab(char x) { + return x == '\t'; +} + +inline bool isWhitespace(char x) { + return x == ' ' || x == '\t' || x == '\n'; +} + +void endDefault(const char* msg, int line, int position) { + printf("ERROR(line: %d, position: %d): %s\n", line, position, msg); + exit(1); +} + +// ------------------------------- Random ------------------------------------- + +void Random::init() { +// Here is a reference about it: +// http://random.mat.sbg.ac.at/results/karl/server/node7.html + vector A(5, 0); + A[0] = 107374182, A[4] = 104480; + unsigned int modulo = 2147483647; // 2^31 -1 + mrg_ = new MultipleRecursiveGenerator(modulo, A); +} + +Random::Random() { + init(); +} + +Random::Random(unsigned int seed) { + init(); + setSeed(seed); +} + +Random::~Random() { + delete mrg_; +} + +void Random::setSeed(unsigned int seed) { + mrg_->setSeed(seed); +} + +#define RAND_TYPE(type, iter)\ + type res = 0;\ + for (int i = 0; i < iter; ++i) {\ + res += ((type)mrg_->next16Bits()) << (i * 16);\ + }\ + return res; + + +int Random::rand() { + int x = randSInt(); + if (x<0) return ~x; + return x; +} + +int Random::randSInt() { + RAND_TYPE(int, 2); +} + +unsigned int Random::randUInt() { + RAND_TYPE(unsigned int, 2); +} + +long long Random::randSLL() { + RAND_TYPE(long long, 4); +} + +unsigned long long Random::randULL() { + RAND_TYPE(unsigned long long, 4); +} + +template +void Random::randomShuffle(RandomAccessIterator first, RandomAccessIterator last) { + int n = last - first; + for (int i = 1; i < n; ++i) { + int to = rand() % (i+1); + swap(first[to], first[i]); + } +} + +// ----------------------- MultipleRecursiveGenerator ------------------------- + +MultipleRecursiveGenerator::MultipleRecursiveGenerator( + unsigned int modulo, + const vector &A) : modulo_(modulo), A_(A) { + n_ = A_.size(); + X_ = vector(n_, 0); + setSeed(0); +} + +void MultipleRecursiveGenerator::setSeed(unsigned int seed) { + for (int i = 0; i < n_; ++i) { + seed = (seed + 1) % modulo_; + X_[i] = seed; + } + for (int i = 0; i < n_; ++i) next16Bits(); +} + +unsigned int MultipleRecursiveGenerator::next16Bits() { + unsigned int res = 0; + for (int i = 0; i < n_; ++i) { + res = (res + (long long)A_[i] * X_[i]) % modulo_; + if (i < n_ - 1) X_[i] = X_[i+1]; + } + X_[n_ - 1] = res; + return res; +} + +// --------------------------- Reader's methods ------------------------------- + +Reader::Reader(const char* file) { + assert((input = fopen(file, "r")) != NULL); + head = tail= 0; + line = position = 1; +} + +Reader::Reader(FILE* _input) { + input = _input; + head = tail = 0; + line = position = 1; +} + +Reader::~Reader() { + assert(fclose(input) == 0); +} + +void Reader::fillBuffer() { + while ((tail + 1) % bufferSize != head) { + int v = getc(input); + if (v == EOF) break; + Buffer[tail] = v; + tail = (tail + 1) % bufferSize; + } +} + +bool Reader::isEOF() { + fillBuffer(); + return head == tail; +} + +char Reader::read(bool move) { + fillBuffer(); + assert((head != tail) || (!move)); + if (head == tail) return 0; + char v = Buffer[head]; + if (move) { + if (isEOLN(v)) { + line++; + position = 1; + } else { + position++; + } + head = (head + 1) % bufferSize; + } + return v; +} + +// ---------------------------- Scanner's methods ----------------------------- + +Scanner::Scanner(const char* file, Lang _lang): lang(_lang) { + reader = new Reader(file); + end = endDefault; +} + +Scanner::Scanner(const char* file, void(*endf)(const char* msg, int line, int position), Lang _lang): lang(_lang) { + reader = new Reader(file); + end = endf; +} + +Scanner::Scanner(FILE* input, Lang _lang): lang(_lang) { + reader = new Reader(input); + end = endDefault; +} + +Scanner::Scanner(FILE* input, void(*endf)(const char* msg, int line, int position), Lang _lang): lang(_lang) { + reader = new Reader(input); + end = endf; +} + +Scanner::~Scanner() { + delete reader; +} + +void Scanner::error(const char* msg) { + int l = reader->getLine(); + int p = reader->getPosition(); + delete reader; + (*end)(msg, l, p); +} + +int Scanner::skipWhitespaces() { + int result = 0; + while (isWhitespace(reader->read())) { + reader->read(1); + result++; + } + return result; +} + + +int Scanner::skipWhitespacesUntilEOLN() { + int result = 0; + while (isWhitespace(reader->read()) && !isEOLN(reader->read())) { + reader->read(1); + result++; + } + return result; +} + + +// INTEGERS + +int Scanner::readInt(int min_value, int max_value) { + return (int)readLL(min_value, max_value); +} + +uint Scanner::readUInt(uint min_value, uint max_value) { + return (uint)readULL(min_value, max_value); +} + +inline bool lower_equal(ull a, bool sign_a, ull b, bool sign_b) { + if (sign_a != sign_b) return sign_a; + if (sign_a) return a >= b; + return a <= b; +} +inline ull spec_abs(ll x) { + if (x < 0) return (-(x + 1)) + 1; + return x; +} + +ll Scanner::readLL(ll min_value, ll max_value) { + assert(min_value <= max_value); + bool sign; + ull val; + readULL(max(spec_abs(min_value), spec_abs(max_value)), val, sign); + ll v = val; + if (!(lower_equal(spec_abs(min_value), min_value < 0, v, sign) && + lower_equal(v, sign, spec_abs(max_value), max_value < 0))) + error(msgOutOfRangeInt[lang]); + if (sign) v *= -1; + return v; +} + +ull Scanner::readULL(ull min_value, ull max_value) { + assert(min_value <= max_value); + bool sign; + ull val; + readULL(max_value, val, sign); + if (sign) error(msgOutOfRangeInt[lang]); + if (!(min_value <= val)) + error(msgOutOfRangeInt[lang]); + return val; +} + +// REAL NUMBERS + +float Scanner::readFloat(float min_value, float max_value) { + return (float)readLDouble(min_value, max_value); +} + +double Scanner::readDouble(double min_value, double max_value) { + return (double)readLDouble(min_value, max_value); +} + +long double Scanner::readLDouble(long double min_value, long double max_value) { + assert(min_value <= max_value); + bool sign; + ldb val; + readLDB(max(fabsl(min_value), fabsl(max_value)), val, sign); + if (sign) val *= -1; + if (!(min_value <= val && val <= max_value)) + error(msgOutOfRangeReal[lang]); + return val; +} + +// STRINGS + +int Scanner::readString(char* s, int size) { + int x = 0; + while ( x < size - 1 && !isEOF() && !isWhitespace(reader->read())) + s[x++] = reader->read(1); + s[x]=0; + return x; +} + +int Scanner::readLine(char* s, int size) { + int x = 0; + while ( x < size - 1 && !isEOLN(reader->read()) && !isEOF()) + s[x++] = reader->read(1); + s[x] = 0; + if (isEOLN(reader->read())) reader->read(1); + return x; +} + +char Scanner::readChar() { + if (reader->isEOF()) error(msgNoChar[lang]); + return reader->read(1); +} + +// WHITESPACES + +void Scanner::readEof() { + if (!reader->isEOF()) error(msgNotEof[lang]); +} + +void Scanner::readEoln() { + if (!isEOLN(reader->read())) error(msgNotEoln[lang]); + reader->read(1); +} + +void Scanner::readEofOrEoln() { + if (isEOLN(reader->read())) { + reader->read(1); + } else if (!reader->isEOF()) { + error(msgNotEofOrEoln[lang]); + } +} + + +void Scanner::readSpace() { + if (!isSpace(reader->read())) error(msgNotSpace[lang]); + reader->read(1); +} + +void Scanner::readTab() { + if (!isTab(reader->read())) error(msgNotTab[lang]); + reader->read(1); +} + +bool Scanner::isEOF() { + return reader->isEOF(); +} + + +// PROTECTED + +void Scanner::readULL(ull limit, ull &val, bool &sign) { + sign = 0; + val = 0; + sign = isMinus(reader->read()); + if (sign) reader->read(1); + int zeros = 0; + int valDigits = 0; + while ('0' == reader->read()) { + zeros++; + valDigits++; + reader->read(1); + if (zeros > 1) error(msgLeadingZeros[lang]); + } + int limDigits = 0; + ull tmp = limit; + while (tmp) { + limDigits++; + tmp /= 10; + } + if (!limDigits) limDigits = 1; + while (isdigit(reader->read())) { + valDigits++; + if (valDigits > limDigits) error(msgOutOfRangeInt[lang]); + char x = reader->read(1); + if (valDigits == limDigits) { + if (limit / 10 < val) error(msgOutOfRangeInt[lang]); + if (limit / 10 == val && limit % 10 < (ull)(x - '0')) error(msgOutOfRangeInt[lang]); + } + val = val * 10 + x - '0'; + } + if (val > 0 && zeros) error(msgLeadingZeros[lang]); + if (sign && zeros) error(msgMinusZero[lang]); + if (!valDigits) error(msgNoNumber[lang]); +} + +void Scanner::readLDB(ldb limit, ldb &val, bool &sign) { + sign = 0; + val = 0; + sign = isMinus(reader->read()); + if (sign) reader->read(1); + int zeros = 0; + int valDigits = 0; + while ('0' == reader->read()) { + zeros++; + valDigits++; + reader->read(1); + if (zeros > 1) error(msgLeadingZeros[lang]); + } + if (zeros && isdigit(reader->read())) error(msgLeadingZeros[lang]); + while (isdigit(reader->read())) { + valDigits++; + char x = reader->read(1); + val = val * 10.0 + x - '0'; + } + if (!valDigits) error(msgNoNumber[lang]); + if (isDot(reader->read())) { + reader->read(1); + ldb dec = 1; + int dotDigits = 0; + while (isdigit(reader->read())) { + dotDigits++; + if (dotDigits > realNumbersLimit) error(msgRealNumberLimit[lang]); + char x = reader->read(1); + dec /= 10.0; + val += dec * (x - '0'); + } + if (!dotDigits) error(msgBadRealNumberFormat[lang]); + } +} + +} // namespace oi + +#endif // OI_LIB_OI_H_ diff --git a/sinol.cls b/sinol.cls new file mode 100644 index 0000000..6be74eb --- /dev/null +++ b/sinol.cls @@ -0,0 +1,121 @@ +%The MIT License (MIT) +% +%Copyright (c) 2014 Karol Farbiś, Marek Sommer +% +%Permission is hereby granted, free of charge, to any person obtaining a copy +%of this software and associated documentation files (the "Software"), to deal +%in the Software without restriction, including without limitation the rights +%to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +%copies of the Software, and to permit persons to whom the Software is +%furnished to do so, subject to the following conditions: +% +%The above copyright notice and this permission notice shall be included in all +%copies or substantial portions of the Software. +% +%THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +%IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +%FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +%AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +%LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +%OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +%SOFTWARE. + +\NeedsTeXFormat{LaTeX2e} +\ProvidesClass{sinol}[2014/02/10] + +\LoadClass[10pt, a4paper]{article} +\RequirePackage{polski} +\RequirePackage[utf8]{inputenc} +\RequirePackage{fancyhdr} +\RequirePackage{lastpage} +\RequirePackage{verbatim} +\RequirePackage[margin=2cm, a4paper, bottom=4.5cm]{geometry} +\RequirePackage{amsmath} +\RequirePackage{graphicx} +\RequirePackage{titlesec} + +\newcommand{\RAM@}{BRAK RAMU} +\newcommand{\data@}{BRAK DATY} +\newcommand{\nazwa@}{BRAK NAZWY} +\newcommand{\kontest@}{BRAK KONKURSU} +\newcommand{\ID}{XXX} + +\newcommand{\id}[1]{\renewcommand{\ID}{#1}} +\newcommand{\signature}[1]{} +\newcommand{\iomode}[1]{} +\renewcommand{\day}[1]{} +\newcommand{\RAM}[1]{\renewcommand{\RAM@}{#1}} +\renewcommand{\date}[1]{\renewcommand{\data@}{#1}} +\renewcommand{\title}[1]{\renewcommand{\nazwa@}{#1}} +\newcommand{\konkurs}[1]{\renewcommand{\kontest@}{#1}} + +\fancyhead{} +\fancyfoot{} + +\fancyhead[L]{\kontest@} +\fancyhead[C]{\includegraphics[width=2cm]{logo.pdf}} +\fancyhead[R]{\data@} +\fancyfoot[R]{\textit{\nazwa@}} +\fancyfoot[C]{\textit{\thepage/\pageref{LastPage}}} + +\pagestyle{fancy} + +\setlength{\headheight}{70pt} +\setcounter{secnumdepth}{0} + +\setlength\parindent{0pt} +\setlength\parskip{10pt} + +\titlespacing{\section}{9pt}{-3pt}{-3pt} +\titleformat{\subsection}{\bf}{}{0pt}{} +\titlespacing{\subsection}{9pt}{-3pt}{-3pt} + +\newenvironment{tasktext}{%startproblex +{% +\vspace*{-40pt}\noindent% +Dostępna pamięć: \RAM@{}MB% +\begin{center}% +\vspace*{3ex}% +\vspace*{-10pt}% +\textit{ \Huge \nazwa@ }% +\vspace*{-10pt}% +\vspace*{-10pt}% +\vspace*{3ex}% +\end{center}% +% +\noindent% +}% +}{} + +\newcommand\twocol[2]{% +\begin{center}% +\begin{minipage}[t]{0.5\textwidth}% +\vspace{0pt}% +{#1}% +\end{minipage}\hfill% +\begin{minipage}[t]{0.5\textwidth}% +\vspace{0pt}% +{#2}% +\end{minipage}% +\end{center}} + +\newcommand{\includefile}[1]{% +\vspace*{-3ex}% +\verbatiminput{#1}% +\vspace*{-4ex}% +} + +\newcommand{\makeexamplef}[2]{% +\begin{tabular}{|p{0.47\textwidth}|p{0.47\textwidth}|}% +\hline% +\centering \texttt{Wejście} & \centering\let\\\tabularnewline\texttt{Wyjście} \\% +\hline% +\includefile{#1} & \includefile{#2} \\% +\hline% +\end{tabular}\\[2ex]% +} + +\newcommand{\makeexample}[1]{\makeexamplef{../in/\ID#1.in}{../out/\ID#1.out}} +\newcommand{\makeexamplex}[1]{\makeexamplef{../in/\ID#1.in}{../out/\ID#1x.out}} + +\newcommand{\makecompactexample}{\section{Przykład}\makeexample0}