From 9efa9130f3945bcfec52a8d9cbaa4461f59d1dd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szymon=20Karpi=C5=84ski?= Date: Mon, 27 Jul 2020 17:05:12 +0200 Subject: [PATCH] Original OI makefiles --- logo.pdf | Bin 0 -> 48936 bytes makefile.doc | 25 ++ makefile.main | 1023 +++++++++++++++++++++++++++++++++++++++++++++++++ makefile.prog | 71 ++++ oi.h | 637 ++++++++++++++++++++++++++++++ sinol.cls | 121 ++++++ 6 files changed, 1877 insertions(+) create mode 100644 logo.pdf create mode 100644 makefile.doc create mode 100644 makefile.main create mode 100644 makefile.prog create mode 100644 oi.h create mode 100644 sinol.cls diff --git a/logo.pdf b/logo.pdf new file mode 100644 index 0000000000000000000000000000000000000000..1d214cba0177be31849af6b1dbaa839b80a426b2 GIT binary patch literal 48936 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 literal 0 HcmV?d00001 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\ +
  • * - przy nazwie testu oznacza test typu ocen
  • \n\ +
  • kolor zielony oznacza poprawne zakonczenie programu
  • \n\ +
  • kolor zolty oznacza przekroczenie limitu czasu
  • \n\ +
  • kolor czerwony oznacza nieprawidlowa odpowiedz
  • \n\ +
  • kolor niebieski oznacza blad wykonania
" + @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\ +
  • * - przy nazwie testu oznacza test typu ocen
  • \n\ +
  • kolor zielony oznacza poprawne zakonczenie programu
  • \n\ +
  • kolor zolty oznacza przekroczenie limitu czasu
  • \n\ +
  • kolor czerwony oznacza nieprawidlowa odpowiedz
  • \n\ +
  • kolor niebieski oznacza blad wykonania
" + @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}