diff --git a/example_package/.gitignore b/example_package/.gitignore index 8ebc407b..4374419c 100644 --- a/example_package/.gitignore +++ b/example_package/.gitignore @@ -15,6 +15,8 @@ out/*.out # LaTeX *.pdf !doc/abczad.pdf +!doc/abcopi.pdf +!doc/abcopr.pdf *.ps !doc/logo.* diff --git a/example_package/README.md b/example_package/README.md new file mode 100644 index 00000000..c6778c50 --- /dev/null +++ b/example_package/README.md @@ -0,0 +1,465 @@ + + + +# **Szablon paczki** + +- [**Ogólne informacje**](#ogólne-informacje) +- [**doc**](#doc) + - [**talentTex.cls**](#talenttexcls) +- [**prog**](#prog) + - [**Rozwiązania**](#rozwiązania) + - [**ingen**](#ingen) + - [**inwer**](#inwer) + - [**checkerka**](#checkerka) + - [**oi.h**](#oih) + - [**Scanner (Wczytywanie)**](#scanner-wczytywanie) + - [Są 3 tryby wczytywania danych](#są-3-tryby-wczytywania-danych) + - [**Najważniejszą funkcją jest wczytywanie** i realizuje ją w następujący sposób](#najważniejszą-funkcją-jest-wczytywanie-i-realizuje-ją-w-następujący-sposób) + - [**CheckerVerdict**](#checkerverdict) + - [**checker\_test**](#checker_test) + - [**InwerVerdict**](#inwerverdict) + - [**bug**](#bug) + - [**oi\_assert**](#oi_assert) + - [**Random**](#random) +- [in i out](#in-i-out) + - [Testy ocen](#testy-ocen) + - [Generowanie](#generowanie) +- [dlazaw](#dlazaw) +- [attachment](#attachment) +- [**config.yml**](#configyml) + - [Interactive tasks](#interactive-tasks) + - [Time](#time) + - [Memory](#memory) + - [Title](#title) + - [Scores](#scores) + - [Task ID](#task-id) + - [Contest type](#contest-type) + - [Expected scores](#expected-scores) + +## **Ogólne informacje** + +Jest to przykładowy szablon paczki, który zaleca się używać. +Jedynie dla zadań interaktywnych jest on inny i jeszcze nie został przygotowany. + +Aktualna wersja paczki znajduje się na [GitHubie](https://github.com/Stowarzyszenie-Talent/st-make/tree/main/example_package). +Można ją pobrać używając komendy `st-make init ID`, gdzie ID to 3-literowy skrót zadania. + +Do kompilacji paczki i innych czynności używamy skryptu `st-make`. +Jest on dostępny na [GitHubie](https://github.com/Stowarzyszenie-Talent/st-make). +Można go pobrać komendą `pip3 install st-make`. + +## **doc** + +Ten folder zawiera wszystkie dokumenty i pliki potrzebne do ich wygenerowania (pdf, tex, doc, img, ...). + +- `{ID}zad.tex` - treść zadania. +- `{ID}opr.tex` - dokument z opracowaniem zadania. +Posiada wszelkie informacje techniczne o zadaniu. +- `{ID}opi.tex` - dokument z opisem rozwiązania. + +Do kompilacji dokumentów latexowych służy `st-make doc`. + +### **talentTex.cls** + +Jest to klasa używana w plikach `.tex`. +Nadaje ona odpowiedni wygląd dokumentom. +Automatycznie tworzy ona nagłówki i stopki. +Wystarczy że stworzymy treść dokumentu pomiędzy znacznikami `\start` i `\finish`. +Dodatkowo udostępnia następujące funkcje: + +- `\tc{n}` - Stylizuje podany tekst na talentowy kolor. +- `\plainimg{img1.jpg}` - Wstawia obrazek o podanej ścieżce. +- `\img{img1.jpg}{opis}{t/b}` - Wstawia obrazek o podanej ścieżce z opisem u góry lub na dole. +Można też `\timg{img1.jpg}{opis}`, `\bimg{img1.jpg}{opis}`. +- `\start{}` - Rozpoczyna treść, musi być na samym początku treści dokumentu. +- `\finish{}` - Kończy treść, musi być na samym końcu treści dokumentu. +- `\tSection{text}` - Nagłówek w stylu talentu. +- `\tCustomSection{text}{0pt}` - Nagłówek w stylu talentu, z możliwością ustawienia odstępu od poprzedniego akapitu. +- `\tSmallSection{text}` - Mały nagłówek w stylu talentu. +- `\makecompactexample{id}` - dodaje automatycznie test "abc0{id}" z paczki, wejście i wyjście będą obok siebie. +- `\makestandardexample{id}` - dodaje automatycznie test "abc0{id}" z paczki, wejście i wyjście będą pod sobą. + +Przy kompilacji testy są automatycznie czytane z folderów ./in i ./out. +Należy się upewnić, że są one wygenerowane w momencie kompilacji treści. +Te polecenia również tworzą nagłówek "Wejście" i "Wyjście". + +- `\ocen{\testOcen{}{} ...}` - Lista wszystkich testów ocen. +- `\testOcen{nazwa_testu}{opis_testu}` - Pojedynczy test ocen z opisem. +- `\ocenTable{}` - Tworzy tabelę z podzadaniami. Automatycznie tworzy nagłówek (Nr & Ograniczenia & Punkty). +- `\ocenRow{nr & opis & punkty}` - Pojedynczy wiersz tabeli: kolejne komórki powinny być rozdzielone znakiem &. + Jeśli chcesz mieć 2 linie w pojedynczej komórce tabeli użyj `\ocenElement{text}`. + +## **prog** + +W tym katalogu znajdują się wszystkie programy. +Ważną rzeczą jest aby programy **kompilowały się bez warningów** przy użyciu `st-make`. + +### **Rozwiązania** + +Nazewnictwo: + +- `{ID}.` - **Rozwiązanie wzorcowe**, np. `abc.cpp`. +Ten program jest wzorcowym i to on generuje poprawne odpowiedzi. +- `{ID}{cyfra}{suffix}.` - Rozwiązania poprawne, na przykład: `abc.cpp`, `abc.cpp`, `abc.cpp`, `abc104.py`, +- `{ID}s{cyfra}{suffix}.` - Rozwiązania wolne, na przykład: `abcs1.cpp`, `abcs3_brute_n_kwadrat.cpp`, `abcs13.py`, +- `{ID}b{cyfra}{suffix}.` - Rozwiązania niepoprawne, na przykład: `abcb1.cpp`, `abcb3_heura.cpp`, `abcb10.py`, + +Każdy program musi mieć inną nazwę po usunięciu rozszerzeń. + +Zalecamy nazywać programy kolejnymi cyframi. `abc.cpp`, `abc2.cpp`, `abc3.py`, `abcs1.cpp`, `abcs2.cpp`, `abcb1.cpp`, ... + +Rozwiązania poprawne to takie które działają w odpowiedniej złożoności i dają dobre wyniki (wolny Python też tu należy). +Programy wolne to takie co mają gorszą złożoność czasową i dają dobre wyniki. +Programy błędne to takie co dają złe wyniki. +Na przykład jak mamy wolny program co daje złe wyniki to damy go do grupy błędnych. + +Każdy kod w pierwszych liniach powinien mieć komentarz opisujący: autora kodu, nazwę zadania, złożoność czasową i pamięciową oraz opis jakie to jest rozwiązanie. +Dodatkowo kody powinny być czytelne, najlepiej zaopatrzone w komentarze i nie zawierające makr oraz define-ów itp. co utrudnia ich czytanie. + +### **ingen** + +`{ID}ingen.cpp` + +Generuje pliki `.in`. +Dzięki temu, że generator jest w paczce, łatwiej będzie w przyszłości zedytować testy. + +Ingen powinien: + +- Po uruchomieniu (bez żadnych argumentów) wygenerować w bieżącym katalogu odpowiednie pliki z danymi wejściowymi. +- Generować liczby losowe za pomocą `oi.h`. +- Każdy test (lub grupa testów) powinna mieć osobnego seeda. +- Być w pełni deterministyczny, czyli za każdym razem ma generować dokładnie te same testy. + Na przykład można inicjować ziarno generatora liczb losowych stałą wartością. +- Idealnie odzwierciedlać format testu, podanego w treści zadania. +- Na końcu pliku wypisać znak końca linii, a na końcu wierszy **nie** wypisywać białych znaków. + +### **inwer** + +`{ID}inwer.cpp` + +Służy do sprawdzenia czy pliki `.in` spełniają założenia z treści. +Jednocześnie pokazuje przydatne informacje o testach. + +Inwer powinien: + +- Wczytywać plik wejściowy za pomocą pakietu `oi.h`. +- Zawierać ograniczenia z treści zadania w formie stałych. + Duże stałe podajemy w sposób czytelny, np. jako iloczyny innych stałych lub w notacji naukowej. +- W przypadku poprawnej weryfikacji ma wypisać w jednej linii krótką charakterystykę testu + (wartości najważniejszych parametrów) i skończyć działanie kodem 0. + Wypisany komentarz ma na celu upewnienie się, że test należy do odpowiedniej grupy oraz, że każda grupa testów zawiera testy z wartościami brzegowymi + (na przykład minimalne i maksymalne ograniczenia na `n`, drzewa w postaci ścieżki i gwiazdy, itd). +- Wypisać również numery podzadań, które pasują do tego testu, + lub nazwy testów ocen, które pasują do tego testu. + (należy inwerem się upewnić, że testy przykładowe i ocen są dokładnie takie, jak w treści). +- W przypadku błędnej weryfikacji wypisać informację o błędzie i skończyć działanie kodem niezerowym. + Można używać funkcji `assert` a najlepiej `oi_asert` z `oi.h`. +- Sprawdzać, czy dane wejściowe są idealnie zgodne z opisem treści zadania, **z dokładnością do każdego białego znaku**. + Nie mogą pojawić się żadne zbędne białe znaki. + +### **checkerka** + +`abcchk.cpp` + +W przypadku zadań z jednoznaczną odpowiedzią nie dodajemy tego programu. System SIO ma domyślną chekierkę, która porównuje odpowiedź z wzorcową. + +W przypadku zadań, w których istnieje wiele poprawnych odpowiedzi, paczka musi zawierać weryfikator danych wyjściowych. +Oprócz tego, do każdego komunikatu, który może wypisać weryfikator, powinno istnieć rozwiązanie błędne lub istnieć w programie test jednostkowy, który powoduje wypisanie tego komunikatu. + +Checkerka powinna: + +- Być **napisana wydajnie**, gdyż w trakcie zawodów jest on uruchamiany bardzo wiele razy. +- Być uruchamiana w następujący sposób: `./{ID}chk wejście wyjście_zawodnika wyjście_wzorcowe`. +- Wczytywać pliki za pomocą pakietu `oi.h`. +- Wypisać odpowiedź w następującym formacie: + - Pierwszy wiersz powinien zawierać jedno słowo: + - `OK` - jeśli odpowiedź jest poprawna, lub + - `WRONG`- w przeciwnym przypadku. + - Drugi wiersz (opcjonalnie) powinien zawierać komentarz do + odpowiedzi zawodnika (np. przyczyny uznania rozwiązania za niepoprawne). + - Trzeci wiersz (opcjonalnie) powinien zawierać jedną liczbę całkowitą + z przedziału [0, 100] oznaczającą (w procentach) liczbę punktów, którą należy przyznać zawodnikowi za test. +- Domyślnie za samo `OK` dostaje się 100 punktów, a za `WRONG` 0 punktów. +- Pozwala na zbędne białe znaki tylko i wyłącznie na końcu linii i na końcu wyjścia oraz na **brak końca linii na końcu wyjścia** (ważne!). +- Działał poprawnie nawet dla bardzo złośliwych danych (np. nie można nic zakładać o długości ciągów znaków znajdujących się w odpowiedzi zawodnika). + +### **oi.h** + +Jest to biblioteka ułatwiająca pisanie programów w paczce. +Jednocześnie pozawala uniknąć masy błędów. +Jest wymagane by wszędzie tam gdzie to możliwe jej używać. +Umożliwia ona nam następujące rzeczy. + +#### **Scanner (Wczytywanie)** + +Służy do wczytywania danych z plików. +Dzięki temu nie musimy martwić się co user dał na wejściu, tylko mówimy co oczekujemy. + +##### Są 3 tryby wczytywania danych + +| tryb | eof | nl | destruktor | +| ---------- | :--------------: | :----------: | :----------: | +| UserOutput | ignoruje nl i ws | ignoruje ws | wczytuje eof | +| Lax | ignoruje nl i ws | ignoruje ws | - | +| TestInput | - | - | wczytuje eof | + +Jak widać służą one do pomijania bądź nie, pustych linii na końcu pliku i białych znaków na końcu linii oraz czy zostanie na koniec jeszcze wczytany eof. +Nadal warto (i zalecamy) sprawdzać samemu czy nastąpił koniec pliku. + +Aby móc korzystać z wczytywania trzeba zainicjować scanner: + +- `scanner = oi::Scanner{stdin, oi::Scanner::Mode::[tryb], oi::Lang::[PL/EN]};` +- `scanner = oi::Scanner(argv[1], oi::Scanner::Mode::[tryb], [scanner_lang]);` + +Teraz scanner możemy używać jak cin, czyli `scanner >>`. +Wersje językowe są dostępne tylko te 2, w tych językach będą wypisywane komunikaty związane z błędami wczytywania. + +Do wywoływania błędów scanner używa funkcji error(Msg&&... msg), która, wypisuje błędy podczas wczytywania. +W schemacie: ```[mode]Wiersz [last_char_pos.line], [pozycja] [last_char_pos.pos]: [msg]...``` + +##### **Najważniejszą funkcją jest wczytywanie** i realizuje ją w następujący sposób + +- pojedynczy znak - `>> 'x' >> ' '` - +Pozwala wczytać pojedynczy, konkretny znak. +- EOF (koniec pliku) - `>> oi::eof` - +Wczytuje koniec pliku zgodnie z trybem pracy. +- EOL (koniec linii) - `>> oi::nl` - +Wczytuje koniec linii zgodnie z trybem pracy. +- ignorowanie znaków białych - `>> oi::ignore_ws` - +Pomija wszystkie znaki białe do następnego znaku lub końca linii. +- linia - `>> oi::Line(a, b)` - +Wczytuje cały wiersz (łacznie z białymi znakami) do zmiennej `a`, która jest stringiem. Długość linii ma być nie dłuższy niż `size_t b`. +- string - `>> oi::Str(a, b)` - +Wczytuje string (słowo do pierwszego białego znaku) do zmiennej `a` o maksymalnej długości `b`. +- char - `>> oi::Char(a, b)` - +Wczytuje znak do `char a` z podanej puli dozwolonych charów `b` gdzie `b` to `std::string` lub `char*`. +- liczba - `>> oi::Num(a, b, c)` - +Wczytuje liczbę `a` (int, float, ...) która ma być w podanym zakresie od `b` do `c`. + +Podawanie zakresu może wydawać się żmudne, ale pozwala zapobiec, że ktoś poda nieskończenie długie słowo, albo że przegapimy sprawdzenie czy liczba jest w odpowiednim zakresie. + +Wszystkie te funkcje w przypadku gdy wczytają coś, co nie pasuje do opisu, zgłoszą błąd i zakończą działanie programu z kodem niezerowym. + +#### **CheckerVerdict** + +oi.h udostępnia nam obiekt `checker_verdict` klasy CheckerVerdict. +Używamy go standardowo `oi::checker_verdict.[coś]`. +Udostępnia on nam poniższe funkcje: + +- **exit_ok()** - +Kończy sprawdzanie z sukcesem dając 100 punktów. +Zwraca `OK\n\n100\n`. +- **exit_ok_with_score(int score, Msg&&... msg)** - +Kończy sprawdzanie z sukcesem z podanym wynikiem i wiadomością/ciami. +Zwraca `OK\n[msg]\n[score]\n`. +- **set_partial_score(int score, Msg&&... msg)** - +Ustawia wynik częściowy który zostanie zwrócony gdy nastąpi błąd. +Czyli zamiast 0 punktów otrzyma się tyle ile się przypisało z danym komentarzem. +- **exit_wrong(Msg&&... msg)** - +Kończ sprawdzanie z błędem i daje 0 punktów, chyba, że ustawiono partial_score. +Zwraca `WRONG\n[msg]\n0\n` albo `OK\n[partial_score_msg]; [msg]\n[partial_score]\n` albo `OK\n[msg]\n[partial_score]\n`. + +Jeżeli w programie używamy `partial_score` to: + +- Trzymajmy zmienną mówiącą jaki jest wynik częściowy. +- Trzymajmy zmienną mówiącą ile user może zdobyć punktów (do_zdobycia). +- Używamy `exit_ok_with_score(do_zdobycia)` zamiast `exit_ok()`. + +#### **checker_test** + +oi.h udostępnia możliwość pisania testów do chekerki. +Te testy są uruchamiane tylko lokalnie. +Istnieją 2 sposoby ich pisania. +Przykład obu z nich jest zaimplementowany w przykładowym `abcchk.cpp`. + +#### **InwerVerdict** + +oi.h udostępnia nam obiekt `inwer_verdict` klasy InwerVerdict. +Używamy go jako strumień wyjścia, a mianowicie: +`oi::inwer_verdict.[coś] << [msg]`. +Gdzie `msg` to wiadomość którą chcemy pokazać przed zakończeniem. +Natomiast `coś` to jedna z podanych opcji: + +- **exit_ok()** - Kończy program pomyślnie. +- **exit_wrong()** - Kończy program z błędem. + +My będziemy używać tylko `oi::inwer_verdict.exit_ok() << [msg]`. +Druga opcja jest używana systemowo i będziemy ją zgłaszać np. przez `oi_assert()` lub `oi::bug(Msg&&... msg)`. + +#### **bug** + +Wywołując `oi::bug(Msg&&... msg)`, program zakończy się niepowodzeniem. +Wyświetli on wtedy podaną wiadomość/ci, w formacie `BUG: [msg]` i zakończy działanie z kodem 2. + +#### **oi_assert** + +Działa podobnie do zwykłego asserta. +Wywołując `oi_assert(condition, msg...);`, sprawdzi założenie, a jak będzie błędne to poda dokładny komunikat co jest nie tak. +Wypisze on `[FILE]:[LINE]: [func]: Assertion '[condition]' failed.` lub +`[FILE]:[LINE]: [func]: Assertion '[condition]' failed: [msg]` + +#### **Random** + +Służy do losowania wartości i jest wymagane używać go zamiast zwykłego rand(), std::mt19937 lub innych mechanizmów losujących. +Zapewnia on uniwersalny sposób generowania liczb (pseudo) losowych. +Klasa `Random` udostępnia: + +- **Random(uint_fast64_t seed = 5489)** +- **void shuffle(T begin, T end)** +- **void shuffle(T& container)** +- **operator()(T min, T max)** + +Tak więc aby utworzyć obiekt robimy `oi::Random rng;` lub `oi::Random rng(seed);`. +Aby zmienić seed nadpisujemy `rng = oi::Random(new_seed);`. +Aby użyć robimy `rng(min, max);`. +Pod wartości min i max podstawiamy zakres z jakiego chcemy wylosować wartość. +Obsługiwane są wszystkie typy numeryczne (int, float, char, ...). +Możemy również pomieszać jakiś kontener Używając `rng.shuffle()`, podając mu albo kontener albo początek i koniec przedziału. + +## in i out + +Są to foldery, w których znajdują się testy. +Testy nazywamy `{ID}{grupa}{nr_testu}.{in/out}`. + +Grupa: + +- 0 - są to testy wstępne, nie liczą się do oceny i uczestnik ma do nich dostęp na zawodach. +- 1,2,... - zwyczajna grupa, punkty za nią dostaniemy jak przejdą wszystkie testy z danej grupy. + +nr_testu to ciąg alfanumeryczny, zaczynający się od litery. +Przyjeło się, że są to kolejne litery alfabetu angielskiego. +A jak się skończą to stawiemy wiecej liter: a, ... z, aa, ab, ..., zz, aaa, ... + +Przykładowe nazwy to: `abc0a.in`, `abc1a.in`, `abc1b.out`, `abc3z.in`, `abc3aa.in`. + +Ciekawą formą nazywania jest też `{ID}{grupa}t{nr}`, np `abc1t1.in`, jednak nie chce się przyjąć. + +### Testy ocen + +Anomalią od powyższych reguł są testy ocen. +Testy opisane jako `{ID}{liczba}ocen.in` są zaliczane jako **testy wstępne** (grupa 0). +Na przykład `abc1ocen.in`, `abc2ocen.out`. +Obecnie można dawać po prostu `0a`, `0b`, ... `0e`, a w treści podać tylko np a i b. + +### Generowanie + +Pliki in generuje ingen, a pliki out generuje program wzorcowy. +Testy korzystające z ingen będą tworzone dopiero na systemie, więc folder in będzie najczęściej pusty. +To samo tyczy się plików out, one też są generowane na systemie. +Możemy jednak sami dodać ręcznie testy, które nie są tworzone przez ingena i one tu mają się znajdować. +Jednak, najlepiej by wszystko było generowane przez ingen. +W przypadku konfliktu nazwy ręcznego i automatycznego testu, ten automatyczny nadpisze ręczny. + +## dlazaw + +W tym folderze są trzymane pliki dla zawodników. +Między innymi przydaje się w zadaniach interaktywnych gdzie jest udostępniana jakaś biblioteczka. + +**Uwaga** testów ocen tu nie dajemy, są one automatycznie dodawane podczas eksportu paczki przy użyciu `st-make export`. + +## attachment + +Pliki znajdujące się w tym folderze są udostępniane bezpośrednio użytkownikowi. +`st-make export` tworzy ten folder i dodaje do niego skompresowany folder `dlazaw` oraz skompresowany folder z testami wstępnymi i ocen. + +## **config.yml** + +Wszystkie informacje opisane tutaj są również opisane w configu. + +For more options see: [link to github](https://github.com/sio2project/sinol-make/blob/main/example_package/config.yml). +Or here are some basic ones. + +### Interactive tasks + +Extra compilation arguments can be defined in `extra_compile_args` key. +Each language can have different extra arguments. +Additional files used in compilation can be defined in `extra_compilation_files` key. +They are copied to the directory where the source code is compiled. +All languages have the same additional files. + +```text +extra_compilation_args: + cpp: ['abclib.cpp'] + +extra_compilation_files: ['abclib.cpp', 'abclib.h'] +``` + +### Time + +```text +time_limit: 1000 # ms + +time_limits: + 2: 2000 + 5: 7000 +``` + +More precise time limit for each group or test can be defined in `time_limits` key. +The more precise time limit has higher priority (first group, then global time limit). + +### Memory + +```text +memory_limit: 262144 # kB + +memory_limits: + 3: 131072 + 4: 131072 +``` + +More precise memory limits can be defined in `memory_limits` key. +Same as with time limits, the more precise memory limit has higher priority. + +### Title + +```text +title: Przykładowy tytuł +``` + +Task title visible in the system. +If there are Polish characters, they should be written for better readability. + +### Scores + +```text +scores: + 1: 20 + 2: 80 +``` + +Number of points for each group can be defined in `scores` key. +If this key is not specified, then all groups have the same number of points. +(if number of groups doesn't divide 100, then the last groups will have the remaining points). +Group 0 always has zero points. + +### Task ID + +```text +sinol_task_id: abc +``` + +This key represents the short name (consisting of 3 letters) of the task. +The names of files in `prog/`, `doc/`, `in/` and `out/` directories have to start with this task id. +This key is only used by `st-make`: running `st-make export` creates +an archive with the proper name, which sio2 uses as the task id. + +### Contest type + +```text +sinol_contest_type: talent +``` + +sinol-make can behave differently depending on the value of `sinol_contest_type` key. +Mainly, it affects how points are calculated. +If the key is not specified, then (in st-make) `talent` is used. In sinol-make (OI version) is used 'default'. + +### Expected scores + +```text +sinol_expected_scores: {} +``` + +st-make can check if the solutions run as expected when using `run` command. +Key `sinol_expected_scores` defines expected scores for each solution on each tests. +There should be no reason to change this key manually. +It is automatically generated and managed by st-make. diff --git a/example_package/config.yml b/example_package/config.yml index 0e7ee3af..c5d37650 100644 --- a/example_package/config.yml +++ b/example_package/config.yml @@ -1,7 +1,9 @@ -title: Przykładowy tytuł +title: Przykładowy tytuł zadania sinol_task_id: abc +sinol_contest_type: talent + memory_limit: 262144 # kB time_limit: 1000 # ms @@ -84,6 +86,15 @@ scores: # an archive with the proper name, which sio2 uses as the task id. +### Contest type + +# sinol_contest_type: talent + +# sinol-make can behave differently depending on the value of `sinol_contest_type` key. +# Mainly, it affects how points are calculated. +# If the key is not specified, then (in st-make) `talent` is used. In sinol-make (OI version) is used 'default'. + + ### expected scores # sinol_expected_scores: {} @@ -92,5 +103,3 @@ scores: # Key `sinol_expected_scores` defines expected scores for each solution on each tests. # There should be no reason to change this key manually. # It is automatically generated and managed by st-make. - -sinol_expected_scores: {} diff --git a/example_package/doc/abcopi.pdf b/example_package/doc/abcopi.pdf new file mode 100644 index 00000000..ec57fbcf Binary files /dev/null and b/example_package/doc/abcopi.pdf differ diff --git a/example_package/doc/abcopi.tex b/example_package/doc/abcopi.tex index 59b73651..ca080cea 100644 --- a/example_package/doc/abcopi.tex +++ b/example_package/doc/abcopi.tex @@ -1,11 +1,7 @@ -\documentclass[12pt]{article} -\usepackage{geometry} -\geometry{a4paper} -\usepackage{amssymb} -\usepackage{polski} +\documentclass[opi]{talentTex} -\title{Opis rozwiązania} -\date{} % pozostaw puste +\title{Przykładowy tytuł zadania} +\id{abc} %%%%%%%%%%%%%%%%%% % Przydatne komendy: @@ -15,13 +11,21 @@ % Dokumentacja: % https://www.overleaf.com/learn -\begin{document} -\maketitle +%%%%%%%%%%%%%%%%%% +% Komendy talentowe +% \start{} % Rozpoczyna treść, musi być na samym początku treści opisu rozwiązania. +% \finish{} % Kończy treść, musi być na samym końcu treści opisu rozwiązania. +% \tSection{text} % Nagłówek w stylu talentu. +% \tCustomSection{text}{xpt} % Nagłówek w stylu talentu, z możliwością ustawienia odstępu 'x' od poprzedniego akapitu. +% \tSmallSection{text} % Mały nagłówek w stylu talentu. +% \tc{text} % Styl używany do oznaczania zmiennych. + +\start{} -\section{Sekcja} +\tSection{Sekcja} Uzupełnij ten plik według własnych upodobań stylistycznych. Jedyna ważna rzecz, to aby każdy po przeczytaniu umiał rozwiązać to zadanie. -\end{document} \ No newline at end of file +\finish{} diff --git a/example_package/doc/abcopr.pdf b/example_package/doc/abcopr.pdf new file mode 100644 index 00000000..3207639f Binary files /dev/null and b/example_package/doc/abcopr.pdf differ diff --git a/example_package/doc/abcopr.tex b/example_package/doc/abcopr.tex index 953a0bac..ac696d88 100644 --- a/example_package/doc/abcopr.tex +++ b/example_package/doc/abcopr.tex @@ -1,11 +1,7 @@ -\documentclass[12pt]{article} -\usepackage{geometry} -\geometry{a4paper} -\usepackage{amssymb} -\usepackage{polski} +\documentclass[opr]{talentTex} -\title{Opracowanie} -\date{} % pozostaw puste +\title{Przykładowy tytuł zadania} +\id{abc} %%%%%%%%%%%%%%%%%% % Przydatne komendy: @@ -15,22 +11,36 @@ % Dokumentacja: % https://www.overleaf.com/learn -\begin{document} -\maketitle +%%%%%%%%%%%%%%%%%% +% Komendy talentowe +% \start{} % Rozpoczyna treść, musi być na samym początku treści opeacowania. +% \finish{} % Kończy treść, musi być na samym końcu treści opeacowania. +% \tSection{text} % Nagłówek w stylu talentu. +% \tCustomSection{text}{xpt} % Nagłówek w stylu talentu, z możliwością ustawienia odstępu 'x' od poprzedniego akapitu. +% \tSmallSection{text} % Mały nagłówek w stylu talentu. +% \tc{text} % Styl używany do oznaczania zmiennych. + +\start{} + +\tSection{Pochodzienie zadanie} + + +\tSection{Poziom zadania, trudnoości} + -\section{Poziom zadania, statystyki} +\tSection{Podzadania} -\section{Ustawienie limitów} +\tSection{Istniejące rozwiązania} -\section{Istniejące rozwiązania} +\tSection{Jak wygenerowano testy} -\section{Jak wygenerowano testy} +\tSection{Ustawienie limitów} -\section{Inne} +\tSection{Inne} -\end{document} \ No newline at end of file +\finish{} diff --git a/example_package/doc/abczad.pdf b/example_package/doc/abczad.pdf index 8c09a9fc..d6f41b92 100644 Binary files a/example_package/doc/abczad.pdf and b/example_package/doc/abczad.pdf differ diff --git a/example_package/doc/abczad.tex b/example_package/doc/abczad.tex index 42a1dc38..c31f8356 100644 --- a/example_package/doc/abczad.tex +++ b/example_package/doc/abczad.tex @@ -1,13 +1,13 @@ \documentclass[zad]{talentTex} -\title{Przykładowe zadanie z długą nazwą} + +\title{Przykładowy tytuł zadania} \id{abc} -\iomode{stdin} % stdin / interactive -\Time{10,5} % Nie dodawać "s" -\Memory{256} % Nie dodawać "MB" -% Poniższe pola uzupełnia kierownik konkursu. +\iomode{stdin} % stdin +\Memory{256} % w MB +\Time{2,4} % w sekundach +\group{A} \konkurs{SKN 2023/24} \day{Runda 17} -\group{A} % Sama literka / nazwa %%%%%%%%%%%%%%%%%% % Przydatne komendy: @@ -19,20 +19,20 @@ %%%%%%%%%%%%%%%%%% % Komendy talentowe -% \start{} % Rozpoczyna treść, musi być na samym początku treści zadania -% \finish{} % Kończy treść, musi być na samym końcu treści zadania -% \tSection{text} % Nagłówek w stylu talentu -% \tNoSkipSection{text} % Jak wyżej, tylko bez odstępu od poprzedniego akapitu -% \tSmallSection{text} % Mały nagłówek w stylu talentu -% \tc{text} % Styl używany do oznaczania zmiennych -% \makecompactexample{id} % 2 style dodawania automatycznie testów "zad0{id}" z paczki -% \makestandardexample{id} % compact - obok siebie, standard - pod sobą +% \start{} % Rozpoczyna treść, musi być na samym początku treści zadania. +% \finish{} % Kończy treść, musi być na samym końcu treści zadania. +% \tSection{text} % Nagłówek w stylu talentu. +% \tCustomSection{text}{xpt} % Nagłówek w stylu talentu, z możliwością ustawienia odstępu 'x' od poprzedniego akapitu. +% \tSmallSection{text} % Mały nagłówek w stylu talentu. +% \tc{text} % Styl używany do oznaczania zmiennych. +% \makecompactexample{id} % 2 style dodawania automatycznie testów "zad0{id}" z paczki. +% \makestandardexample{id} % compact - obok siebie, standard - pod sobą. % % Przy kompilacji testy są automatycznie czytane z folderów ./in i ./out -% \ocen{text} % Lista wszystkich testów ocen -% \testOcen{text}{text2} % Pojedyńczy test ocen z opisem -% \ocenTable{text} % Tabela z podzadaniami -% \ocenRow{text} % Pojedyńczy wiersz tabeli: kolejne komórki powinne być rodzielone znakiem & -% \ocenElement{text} % Jeśli chcesz mieć 2 linie w pojedyńczej komórce tabeli +% \ocen{text} % Lista wszystkich testów ocen. +% \testOcen{text}{text2} % Pojedyńczy test ocen z opisem. +% \ocenTable{text} % Tabela z podzadaniami. +% \ocenRow{text} % Pojedyńczy wiersz tabeli: kolejne komórki powinne być rodzielone znakiem &. +% \ocenElement{text} % Jeśli chcesz mieć 2 linie w pojedyńczej komórce tabeli. \start{} @@ -59,10 +59,10 @@ \tSection{Przykład} -\makecompactexample{} % abc0.in -> {}, abc0x.in -> {x} +\makestandardexample{a} % abc0.in -> {}, abc0x.in -> {x} \makecompactexample{a} % testy muszą być wygenerowane więc użyj st-make ingen outgen -\tNoSkipSection{Wyjaśnienie przykładów}{0pt} +\tCustomSection{Wyjaśnienie przykładów}{5pt} \tSmallSection{Przykład 1} @@ -92,8 +92,8 @@ \ocenTable{ \ocenRow{1 & $\tc{n} \leq 100$ & 30} - \ocenRow{2 & \ocenElement{$\tc{n} \leq 1000$ Dwie\\ Linie} & 50} - \ocenRow{3 & Bez ograniczeń & 20} + \ocenRow{2 & \ocenElement{$\tc{n} \leq 1000$ Dwie\\ Linie} & 20} + \ocenRow{3 & Bez ograniczeń & 50} } \finish{} diff --git a/example_package/doc/logo-orig.jpg b/example_package/doc/logo-orig.jpg deleted file mode 100644 index cfaddf52..00000000 Binary files a/example_package/doc/logo-orig.jpg and /dev/null differ diff --git a/example_package/doc/talentTex.cls b/example_package/doc/talentTex.cls index d7c40170..1a2be40c 100644 --- a/example_package/doc/talentTex.cls +++ b/example_package/doc/talentTex.cls @@ -1,6 +1,7 @@ % Latex style for Talent (https://talent.edu.pl) statemnts % % Copyright (c) Stanisław Czech 2024 +% Copyright (c) Jakub Rożek 2024 % Provided under MIT licence % % Based on sinol.cls made by: @@ -9,10 +10,14 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\NeedsTeXFormat{LaTeX2e} +% Formalności %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\def\sinolVersion{0.0.4} +\NeedsTeXFormat{LaTeX2e} +\def\sinolVersion{0.0.5} \ProvidesClass{talentTex}[Stowarzyszenie Talent \sinolVersion] + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Include pakietów %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \RequirePackage[T1]{fontenc} \RequirePackage{epsf} @@ -22,10 +27,24 @@ \RequirePackage[latin2,utf8]{inputenc} \RequirePackage{verbatim} \RequirePackage{xcolor} +\RequirePackage{xstring} +\RequirePackage{xparse} + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% Opcje dotyczace kodowania +% Plików w paczce %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\def\sinolInputEncoding{utf8} +\def\sinolTestIn{../in} +\def\sinolTestOut{../out} +\def\sinolContestLogo{logo.jpg} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Kolory +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\definecolor{talentBrown}{RGB}{97, 31, 30} +\definecolor{talentBlue}{RGB}{0, 56, 117} % logo +% \definecolor{talentBlue}{RGB}{31, 101, 157} % środek +% \definecolor{talentBlue}{RGB}{31, 129, 189} % Jasny (SZU) +% \definecolor{talentBlue}{RGB}{31, 73, 125} % Ciemny %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % zmienne logiczne @@ -41,62 +60,69 @@ \newif\ifgroupdefed \groupdefedfalse % czy podano grupę \newif\ifMemorydefed \Memorydefedfalse % czy podano dostępną pamięć \newif\iftimedefed \timedefedfalse % czy podano czas działania -\newif\ifCountrydefed \Countrydefedfalse % Czy zdefiniowano kraj + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Obsługa plików: inf, err +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\chardef\inffile=15 % plik wejsciowy (np. testy) +\chardef\errfile=14 % plik wyjsciowy +\chardef\tmpfile=13 % plik tymczasowy +% \infoutput{} --- wyprowadza do pliku informacyjnego +\newcommand{\infoutput}[1]{% + \immediate\write\inffile{#1} +} -\newcommand\?[1]{ - [[#1]] +% \erroutput{} --- wyprowadza do pliku z bledami +\newcommand{\erroutput}[1]{% + \immediate\write\errfile{#1} + \global\sinolerrorstrue } -\def\cstyle{inline} +% \erroutputWrongSection{}{} --- +% wyprowadza informacje o blednej nazwie rodzialu +\newcommand{\erroutputWrongSection}[2]{% + \erroutput{bledna nazwa lub lokalizacja rozdzialu '#1', spodziewane '#2'}% +} -\newcounter{sinolCommentNumber} -\global\def\comments{} -\newcommand\commentStyle[1]{ - \edef\cstyle{#1} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Czynności przed i po - otwiera pliki inf err +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\AtBeginDocument{% + \immediate\openout\inffile \jobname.inf + \immediate\openout\errfile \jobname.err } -\newcommand\showComments{ - \def\@empty{} - \ifx\comments\@empty\else - \section{\sinolSNameUwagi} - \comments +\AtEndDocument{% + \ifsinolerrors + \immediate\write16{SINOL: znaleziono bledy (zob. \jobname.err) !} + \fi + \ifsinolshortages + \immediate\write16{SINOL: znaleziono niedoprecyzowania (wystepuje '[[[...]]]')} \fi } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% rozwijajace \uppercase +% Definicje %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + \def\ucase#1{\expandafter\uppercase\expandafter{#1}} \def\lcase#1{\expandafter\lowercase\expandafter{#1}} -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% logo -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\def\LOGO{ - \leavevmode - \hbox{ - \vbox to 0pt{ - \vss - \hbox{ - \includegraphics[height=1.143cm,bb=0 0 900 300]{\sinolContestLogo}% - } - } - } + +\def\?#1{ + [[#1]] } -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% \ifundef{}{}{} -% --- wykonuje jeden z blokow, w zaleznosci od tego, -% czy makro jest zdefiniowane -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + \def\ifundef#1#2#3{ \expandafter - \ifx\csname #1\endcsname\relax + \ifx\csname#1\endcsname\relax #2 \else #3 \fi } + \def\ifeq#1#2#3{ \edef\@tempeqa{#1} \edef\@tempeqb{#2} @@ -104,6 +130,7 @@ #3 \fi } + \def\ifneq#1#2#3{ \edef\@tempeqa{#1} \edef\@tempeqb{#2} @@ -112,151 +139,88 @@ \fi } - -\definecolor{talentBlue}{RGB}{0, 56, 117} % logo -% \definecolor{talentBlue}{RGB}{31, 101, 157} % środek -% \definecolor{talentBlue}{RGB}{31, 129, 189} % Jasny (SZU) -% \definecolor{talentBlue}{RGB}{31, 73, 125} % Ciemny -\definecolor{talentBrown}{RGB}{97, 31, 30} -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% numery plikow -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\chardef\inffile=15 % plik wejsciowy (np. testy) -\chardef\errfile=14 % plik wyjsciowy -\chardef\tmpfile=13 % plik tymczasowy -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% dane do metryki -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\def\sinolHistory{} -\def\sinolSignature{} -\def\sinolDocVersion{} -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% \concludedecls --- uruchamiane po przeczytaniu deklaracji -% \concludetext --- uruchamiane po przeczytaniu tekstu -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\newcommand{\concludedecls}{} -\newcommand{\concludetext}{} -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% numer rozdzialu -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\newcount\sinolSectionNumber \sinolSectionNumber=0 -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% Footnote-ki indeksowane symbolami, a nie liczbami. -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\def\thefootnote{\fnsymbol{footnote}} -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% \infoutput{} --- wyprowadza do pliku informacyjnego -% \erroutput{} --- wyprowadza do pliku z bledami -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\newcommand{\infoutput}[1]{ - \immediate\write\inffile{#1} +\newcommand{\iffileexists}[3]{ + \immediate\openin\tmpfile #1\par + \ifeof\tmpfile + \immediate\closein\tmpfile + #3 + \else + \immediate\closein\tmpfile + #2 + \fi } -\newcommand{\erroutput}[1]{ - \immediate\write\errfile{#1} - \global\sinolerrorstrue +\newcommand{\twocol}[2]{ + \noindent + \begin{minipage}[t]{0.5\textwidth} + {#1} + \end{minipage}\hfill + \begin{minipage}[t]{0.5\textwidth} + {#2} + \end{minipage} } -\newcommand{\tSection}[1]{ - \tNoSkipSection{#1}{15pt} -} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\newcommand{\tSmallSection}[1]{ - { - \setlength\parindent{0pt} - \setlength\parskip{5pt} - \par - { - \fontfamily{ptm} - \color{talentBlue} - \textbf{#1} +\def\LOGO{ + \leavevmode + \hbox{ + \vbox to 0pt{ + \vss + \hbox{ + \includegraphics[height=1.143cm,bb=0 0 900 300]{\sinolContestLogo}% + } } } - \setlength\parskip{2pt} - \par } - -\newcommand{\tNoSkipSection}[2]{ - { - \setlength\parindent{0pt} - \setlength\parskip{#2} - \par - { - \fontfamily{ptm} - \color{talentBlue} - \Large - \textbf{#1} - } - } - \setlength\parskip{2pt} - \par +\def\tophugetitle{ + \begin{minipage}[t]{0.8\textwidth} + \setlength{\parindent}{-4pt} + \color{talentBlue} + \fontfamily{ptm} + \huge + \textbf{\sinolTitle} + \end{minipage} } +\def\topinformationbar{} -\newcommand{\tc}[1]{ - \fontfamily{ptm} - \color{talentBlue} - \textbf{#1} - \color{black} -} +\def\sinolHistory{} +\def\sinolSignature{} -\newlength{\imgwidth} -% podpis pod/nad obrazkiem -\newcommand\imgcaption[1]{ -\def\capwidth{\textwidth} -\addtolength\capwidth{-1cm} -\centerline{\begin{minipage}{\capwidth}\footnotesize #1\end{minipage}} -} +% uruchamiane po przeczytaniu deklaracji +\newcommand{\concludedecls}{ + % Sprawdzanie istnienia definicji + \ifundef{ID}{ + \erroutput{brak 3-literowego identyfikatora (klauzula \string\id)} + \def\ID{XXX} + }{} + \def\infile{{\ttfamily \lcase{\ID}.in}} + \def\outfile{{\ttfamily \lcase{\ID}.out}} + \ifundef{sinolTitle}{ + \erroutput{brak tytułu (klauzula \string\title)} + \def\sinolTitle{\?{brak tytułu}} + }{} + \def\sinolIdSignature{\ucase{\ID}} + \let\oldsection\section +} + +% uruchamiane po przeczytaniu tekstu +\newcommand{\concludetext}{} -% rysunek #1-plik, #2-podpis, #3-gdzie podpis (t-na gorze, b-na dole) -\newcommand\img[3]{ - \def\tmparg{#3} - \def\tmpb{b} - \setlength\imgwidth{\textwidth} - \addtolength\imgwidth{-2cm} - \begin{center} - \begin{minipage}{\imgwidth} - \ifx\tmparg\tmpb - $$\includegraphics{#1}$$ - \hrule - \smallskip - \imgcaption{#2} - \else - \imgcaption{#2} - \smallskip - \hrule - \smallskip - $$\includegraphics{#1}$$ - \fi - \end{minipage}\end{center} -} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Przypisanie stałych przez użytkownika +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% rysunek z podpisem na gorze -\newcommand\timg[2]{\img{#1}{#2}{t}} -% rysunek z podpisem na dole -\newcommand\bimg[2]{\img{#1}{#2}{b}} -\newcommand\plainimg[1]{$\includegraphics{#1}$} -% tryb dwukolumnowy (kolumny -- #1 i #2) -\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{\id}[1]{ + \edef\ID{#1} + \infoutput{[id][#1]} } - -\let\oldpagestyle\pagestyle -\def\sinolPageStyle{fancy} -\renewcommand{\pagestyle}[1]{ - \gdef\sinolPageStyle{#1} - \oldpagestyle{#1} +\renewcommand{\title}[1]{ + \def\sinolTitle{#1} + \infoutput{[title][#1]} } \newcommand{\signature}[1]{ @@ -268,14 +232,9 @@ \newcommand{\history}[3]{ \edef\sinolHistory{\noindent $\bullet$\ v.\,#3: #1, #2\par\sinolHistory} \infoutput{[history][#1][#2][#3]} - \gdef\sinolDocVersion{#3} \DocVersiondefedtrue } -\newcommand{\uses}[1]{ - \infoutput{[uses][#1]} -} - \newcommand{\etap}[1]{ \def\sinolEtap{#1} \global\etapdefedtrue @@ -302,43 +261,13 @@ } \newcommand{\Time}[1]{ - \def\sinolTime{#1\,s} + \def\sinolTime{#1} \global\timedefedtrue } -\newcommand{\Country}[1]{ - \def\sinolCountry{#1} - \global\Countrydefedtrue -} - \newcommand{\infile}{{\ttfamily XXX.IN}} \newcommand{\outfile}{{\ttfamily XXX.IN}} -\def\sinolContestLogo{logo.jpg} - -\def\sinolSolNameC{.c} -\def\sinolSolNameCPP{.cpp} -\def\sinolSolNamePAS{.pas} - -\def\sinolTitleZadanie{Zadanie} - -\def\sinolSNamePrzyklad{Przykład} -\def\sinolSNameZadanie{Zadanie} -\def\sinolSNameWejscie{Wejście} -\def\sinolSNameWyjscie{Wyjście} -\def\sinolSNameRozwiazanieWzorcowe{Rozwiązanie wzorcowe} -\def\sinolSNameTesty{Testy} -\def\sinolSNameUwagi{Uwagi} -\def\sinolSNameHistory{HISTORIA} - -\def\sinolEtapText{etap} -\def\sinolGroupText{Grupa} -\def\sinolDayText{} -\def\sinolKonkursText{} -\def\sinolSourceText{Plik źródłowy} -\def\sinolMemoryText{Pamięć} -\def\sinolTimeText{Czas} - \newcommand{\iomode}[1]{ \def\sinolIOmode{#1} \ifeq{#1}{files}{ @@ -346,8 +275,8 @@ \gdef\sinolExampleOutputText{poprawnym wynikiem jest plik wyjściowy \outfile{}:} } \ifeq{#1}{stdin}{ - \gdef\sinolExampleInputText{\color{talentBlue}\bf Wejście:\color{black} } - \gdef\sinolExampleOutputText{\color{talentBlue}\bf Wyjście:\color{black} } + \gdef\sinolExampleInputText{{\color{talentBlue}\bf Wejście:}} + \gdef\sinolExampleOutputText{{\color{talentBlue}\bf Wyjście:}} } \ifeq{#1}{outputonly}{ \gdef\sinolExampleInputText{Wejście:} @@ -359,210 +288,126 @@ \gdef\sinolExampleOutputText{Wyjście:} } } - \iomode{stdin} -\newcommand{\iffileexists}[3]{ - \immediate\openin\tmpfile #1\par - \ifeof\tmpfile - \immediate\closein\tmpfile - #3 - \else - \immediate\closein\tmpfile - #2 - \fi -} - -\AtBeginDocument{ - \immediate\openout\inffile \jobname.inf - \immediate\openout\errfile \jobname.err -} - -\AtEndDocument{ - \ifsinolerrors - \immediate\write16{SINOL: znaleziono błędy (zob. \jobname.err)!} - \fi - \ifsinolshortages - \immediate\write16{SINOL: znaleziono niedoprecyzowania (występuje '[[[...]]]')} - \fi -} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Nazwy wyświetlane (zmiana języka, narazie tu ręcznie) +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\def\sinolSNamePrzyklad{Przykład} +\def\sinolSNameZadanie{Zadanie} +\def\sinolSNameWejscie{Wejście} +\def\sinolSNameWyjscie{Wyjście} +\def\sinolSNameRozwiazanieWzorcowe{Rozwiązanie wzorcowe} +\def\sinolSNameTesty{Testy} +\def\sinolSNameUwagi{Uwagi} +\def\sinolSNameHistory{HISTORIA} +\def\sinolSNameOpis{Opis rozwiązania} +\def\sinolSNameOpracowanie{Opracowanie} -\newcommand\includefile[1]{ -\vspace{-0.7em} -\verbatiminput{#1} -} +\def\sinolTitleZadanie{Zadanie} +\def\sinolEtapText{etap} +\def\sinolGroupText{Grupa} +\def\sinolDayText{} +\def\sinolKonkursText{} +\def\sinolSourceText{Plik źródłowy} +\def\sinolMemoryText{Pamięć} +\def\sinolTimeText{Czas} -\def\sinolCatNameZad{zad} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Opcje talentTex +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \DeclareOption{zad}{ - \def\sinolcat{zad} - \def\xsinolcat{\sinolTitleZadanie} - \renewcommand{\title}[1]{ - \def\sinolTitle{#1} - \infoutput{[title][#1]} - } - \newcommand{\id}[1]{ - \edef\ID{#1} - \infoutput{[id][#1]} - } - - \newcommand{\exampleinputimg}[1]{ - \edef\exampleInImg{#1} - } - - \newcommand{\exampleoutputimg}[1]{ - \edef\exampleOutImg{#1} - } - - \newcommand{\exampleimg}[1]{ - \edef\exampleImg{#1} - } - - \newcommand{\makemetric}{ + \renewcommand{\topinformationbar}{ + \hbox to \hsize { - \footnotesize - {\noindent\bfseries \sinolSNameHistory:}\par - \sinolHistory - } - } - - \newcommand{\exampleinput}[1]{ - \iffileexists{\sinolTestIn/\ID0#1.in}{ - \includefile{\sinolTestIn/\ID0#1.in} - }{ - \iffileexists{\ID0#1.in}{ - \includefile{\ID0#1.in} - }{ - \smallskip - \bf{brak pliku {\ttfamily\ID0#1.in}}\par - \erroutput{brak pliku '\ID0#1.in'} - \smallskip - } - } - } - - \newcommand{\exampleoutput}[1]{ - \iffileexists{\sinolTestOut/\ID0#1.out}{ - \includefile{\sinolTestOut/\ID0#1.out} - }{ - \iffileexists{\ID0#1.out}{ - \includefile{\ID0#1.out} - }{ - \smallskip - \?{brak pliku {\ttfamily\ID0#1.out}}\par - \erroutput{brak pliku '\ID0#1.out'} - \smallskip - } - } - } - - \def\sinolTestIn{../in} - - \def\sinolTestOut{../out} - - \def\@exampleputtogetherh#1#2{\twocol{#1}{#2}} - - \def\@exampleputtogetherv#1#2{#1 #2} - - \newcommand{\makestandardexampleinput}[1]{ - \noindent\sinolExampleInputText - \ifundef{exampleInImg}{ - \exampleinput{#1} - }{ - \@exampleputtogetherimg{\exampleinput}{\plainimg{\exampleInImg}} - } - } - - \newcommand{\makestandardexampleoutput}[1]{ - \noindent\sinolExampleOutputText - \ifundef{exampleOutImg}{ - \exampleoutput{#1} - }{ - \@exampleputtogetherimg{\exampleoutput}{\plainimg{\exampleOutImg}} + \begin{minipage}[t]{1\textwidth} + \setlength{\parindent}{-2pt} + \def\@tempempty{} + \bf + \fontfamily{ptm} + \color{talentBlue} + % + %% Konkurs pokazuje się tylko gdy jest niepusty + \ifkonkursdefed + \ifx\sinolKonkurs\@tempempty + \else\sinolKonkursText\sinolKonkurs.\ + \fi + \else\?{brak konkursu}\erroutput{brak konkursu}\fi + % + %% Dzień pokazuje się tylko gdy jest niepusty + \ifdaydefed + \ifx\sinolDay\@tempempty + \else\sinolDayText\sinolDay.\ + \fi + \else\?{brak dnia}\erroutput{brak dnia}\fi + % + % Grupa + \ifgroupdefed + \if\sinolGroup\@tempempty + \else\sinolGroupText:\,\sinolGroup.\ + \fi + \else\?{brak grupy}\erroutput{brak grupy}\fi + % + % Dostępna pamięć -- pokazuje sie tylko gdy + % nie jest pusta i jest zdefiniowana + \ifMemorydefed + \ifx\sinolMemory\@tempempty + \else\sinolMemoryText:\,\sinolMemory\,MB.\ + \fi + \else\?{brak limitu pamięci}\erroutput{brak limitu pamięci}\fi + % + %% Limit czasu -- pokazuje się tylko gdy nie jest pusty i jest zdefiniowany. + \iftimedefed + \ifx\sinolTime\@tempempty + \else\sinolTimeText:\,\sinolTime\,s.\ + \fi + \else\?{brak limitu czasu}\erroutput{brak limitu czasu}\fi + \hfill + \end{minipage} } } - \newcommand{\loadtestdir}{ - \openin\tmpfile testdir.inp - \ifeof\tmpfile -% TW, zazwyczaj ten plik nie jest stosowany, wiec komunikat o bledzie nie jest -% konieczny -% \write16{SINOL: brak pliku 'testdir.inp'} - \else - \read\tmpfile to\sinolTestIn - \ifeof\tmpfile - \write16{SINOL: plik 'testdir.inp' skonczyl sie zbyt wczesnie} - \else - \read\tmpfile to\sinolTestOut - \fi - \fi - \closein\tmpfile - } - - \newcommand{\@makestandardexampletext}[1]{ - \@exampleputtogethertext{ - \makestandardexampleinput{#1} - }{ - \makestandardexampleoutput{#1} - } - } +} - \newcommand{\@makeexample}[1]{ - \loadtestdir - \ifundef{exampleImg}{ - \@makestandardexampletext{#1} - }{ - \@exampleputtogetherimg{ - \@makestandardexampletext{#1} - }{ - \plainimg{\exampleImg} - } +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\DeclareOption{opi}{ + \renewcommand{\topinformationbar}{ + \hbox to \hsize + { + \begin{minipage}[t]{1\textwidth} + \setlength{\parindent}{-2pt} + \def\@tempempty{} + \bf + \fontfamily{ptm} + \color{talentBlue} + \Large + \sinolSNameOpis + \hfill + \end{minipage} } } +} - - \newcommand{\makestandardexample}[1]{ - \let\@exampleputtogetherimg=\@exampleputtogetherh - \let\@exampleputtogethertext=\@exampleputtogetherv - \@makeexample{#1} - } - - \newcommand{\makecompactexample}[1]{ - \setlength\parskip{-15pt} - \def\@exampleputtogetherimg##1##2{ - \@exampleputtogetherv{##1}{ - \begin{center} - ##2 - \end{center} - } +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\DeclareOption{opr}{ + \renewcommand{\topinformationbar}{ + \hbox to \hsize + { + \begin{minipage}[t]{1\textwidth} + \setlength{\parindent}{-2pt} + \def\@tempempty{} + \bf + \fontfamily{ptm} + \color{talentBlue} + \Large + \sinolSNameOpracowanie + \hfill + \end{minipage} } - \let\@exampleputtogethertext=\@exampleputtogetherh - \@makeexample{#1} - \setlength\parskip{-15pt} - } - - \renewcommand{\concludedecls}{ - % Sprawdzanie istnienia definicji - \ifundef{ID}{ - \erroutput{brak 3-literowego identyfikatora (klauzula \string\id)} - \def\ID{XXX} - }{} - \def\infile{{\ttfamily \lcase{\ID}.in}} - \def\outfile{{\ttfamily \lcase{\ID}.out}} - \ifundef{sinolTitle}{ - \erroutput{brak tytułu (klauzula \string\title)} - \def\sinolTitle{\?{brak tytułu}} - }{} - \def\sinolIdSignature{\ucase{\ID}} - \let\oldsection\section - } - - \renewcommand{\concludetext}{ - \ifeq{\cstyle}{appendix}{\showComments} } } +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \DeclareOption*{\PassOptionsToClass{\CurrentOption}{article}} \ProcessOptions\relax \PassOptionsToClass{a4paper}{article} @@ -574,7 +419,6 @@ \setlength{\textwidth}{168mm} % {180mm} \setlength{\textheight}{265mm} % {257mm} \setlength{\oddsidemargin}{0pt} -\setlength{\topmargin}{0pt} \setlength{\hoffset}{-4mm} % this means 1in-15mm \setlength{\voffset}{-30mm} % this means 1in-15mm \setlength{\topmargin}{0pt} @@ -582,6 +426,99 @@ \renewcommand{\headrulewidth}{0pt} \renewcommand{\footrulewidth}{0.4pt} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Wygląd dokumentu +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\pagestyle{fancy} +\lfoot{Stowarzyszenie Talent (talent.edu.pl)} +\rfoot{\sinolTitle\ - \ID} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Definicja przestrzeni dokumentu: 'tasktext' +\newenvironment{tasktext}{ + \concludedecls + % Tytuł + \leftline{% + \tophugetitle% + } + % Logo + \rightline{ + \hbox to\hsize{\hfil\LOGO} + } + \smallskip + % Linia + { + \color{talentBrown} + \hrule height 2pt \relax + } + \smallskip + \topinformationbar + \bigskip +}{ + \concludetext + \closeout\inffile + \closeout\errfile +} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Komendy dostępne w klasie talentTex +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% komendy do obsługi plików + +\newcommand{\includefile}[1]{ +\vspace{-0.7em} +\verbatiminput{#1} +} + +\newcommand{\exampleinput}[1]{ + \iffileexists{\sinolTestIn/\ID0#1.in}{ + \includefile{\sinolTestIn/\ID0#1.in} + }{ + \smallskip + \?{brak pliku {\ttfamily\ID0#1.in}}\par + \erroutput{brak pliku '\ID0#1.in' w scieżce '\sinolTestIn'} + \smallskip + } +} + +\newcommand{\exampleoutput}[1]{ + \iffileexists{\sinolTestOut/\ID0#1.out}{ + \includefile{\sinolTestOut/\ID0#1.out} + }{ + \smallskip + \?{brak pliku {\ttfamily\ID0#1.out}}\par + \erroutput{brak pliku '\ID0#1.out' w scieżce '\sinolTestOut'} + \smallskip + } +} + +\newcommand{\makeexampleinput}[1]{ + \noindent\sinolExampleInputText + \exampleinput{#1} +} + +\newcommand{\makeexampleoutput}[1]{ + \noindent\sinolExampleOutputText + \exampleoutput{#1} +} + +\newcommand{\makestandardexample}[1]{% + \makeexampleinput{#1}% + \makeexampleoutput{#1}% +} + +\newcommand{\makecompactexample}[1]{ + \twocol{\makeexampleinput{#1}}{\makeexampleoutput{#1}} + \vspace{15pt} + \setlength\parskip{15pt} + \par + \setlength\parskip{0pt} + \par +} + +% pozostałe komendy +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + \newcommand{\start}{ \begin{document} \begin{tasktext} @@ -592,6 +529,94 @@ \end{document} } +\newlength{\imgwidth} + +% podpis pod/nad obrazkiem +\newcommand{\imgcaption}[1]{ + \def\capwidth{\textwidth} + \addtolength\capwidth{-1cm} + \centerline{\begin{minipage}{\capwidth}\footnotesize #1\end{minipage}} +} + +% rysunek #1-plik, #2-podpis, #3-gdzie podpis (t-na gorze, b-na dole) +\newcommand{\img}[3]{ + \def\tmpargthree{#3} + \def\tmpb{b} + \setlength\imgwidth{\textwidth} + \addtolength\imgwidth{-2cm} + \begin{center} + \begin{minipage}{\imgwidth} + \ifx\tmpargthree\tmpb + $$\includegraphics[width=1\imgwidth]{#1}$$ + \hrule + \smallskip + \imgcaption{#2} + \else + \imgcaption{#2} + \smallskip + \hrule + \smallskip + $$\includegraphics[width=1\imgwidth]{#1}$$ + \fi + \end{minipage}\end{center} +} + +\newcommand{\timg}[2]{\img{#1}{#2}{t}} +\newcommand{\bimg}[2]{\img{#1}{#2}{b}} +\newcommand{\plainimg}[1]{$$\includegraphics{#1}$$} + +\newcommand{\tSection}[1]{ + \tCustomSection{#1}{15pt} +} + +\newcommand{\tsection}[1]{ + \tSection{#1} +} + +\newcommand{\tSmallSection}[1]{ + { + \setlength\parindent{0pt} + \setlength\parskip{5pt} + \par + { + \fontfamily{ptm} + \color{talentBlue} + \textbf{#1} + } + } + \setlength\parskip{2pt} + \par +} + +\newcommand{\tCustomSection}[2]{ + { + \setlength\parindent{0pt} + \setlength\parskip{#2} + \par + { + \fontfamily{ptm} + \color{talentBlue} + \Large + \textbf{#1} + } + } + \setlength\parskip{2pt} + \par +} + +\newcommand{\tc}[1]{% + \ifmmode + \StrLen{#1}[\textLength] + \ifnum\textLength=1 + \textcolor{talentBlue}{\textbf{\fontfamily{ptm}\selectfont #1}}% + \else + \textcolor{talentBlue}{\mathbf{{\fontfamily{ptm}\selectfont #1}}}% + \fi + \else + \textcolor{talentBlue}{\textbf{\fontfamily{ptm}\selectfont #1}}% + \fi +} + \newcommand{\ocen}[1]{ \begin{enumerate} \setlength\itemindent{-13pt} @@ -601,7 +626,7 @@ } \newcommand{\testOcen}[2]{ - \item[] \textbf{\color{talentBlue}#1: \ }{#2} + \item[] \textbf{\color{talentBlue}\ID#1: \ }{#2} } \newcommand{\ocenTable}[1]{ @@ -609,7 +634,7 @@ } \newcommand{\customOcenTable}[3]{ - \begin{center} % Gdybyśmy jednak chcieli po lewej to 'flushleft'. + \begin{center} \begin{tabular}{#1} \hline #2 \\ @@ -628,103 +653,3 @@ #1 \end{tabular} } - -\lfoot[L]{Stowarzyszenie Talent (talent.edu.pl)} -\rfoot{\sinolTitle\ -\ \ID} -\pagestyle{fancy} - -\newenvironment{tasktext}{ - \expandafter\inputencoding\expandafter{\sinolInputEncoding} - { - \leftline{ - \begin{minipage}[t]{0.8\textwidth} - \setlength{\parindent}{-4pt} - \color{talentBlue} - \fontfamily{ptm} - \huge - - \textbf{\sinolTitle} - - \end{minipage} - } - \rightline{ - \hbox to\hsize{\hfil\LOGO} - } - } - \smallskip - { - \color{talentBrown} - \hrule height 2pt \relax - } - \concludedecls - \color{talentBlue} - \smallskip - \hbox to \hsize - { - \begin{minipage}[t]{1\textwidth} - \setlength{\parindent}{-2pt} - \def\@tempempty{} - \bf - \fontfamily{ptm} - % - %% Konkurs pokazuje się tylko gdy jest niepusty - \ifkonkursdefed - \ifx\sinolKonkurs\@tempempty - \else\sinolKonkursText\sinolKonkurs.\ - \fi - \else\?{brak konkursu}\erroutput{brak konkursu}\fi - % - %% Dzień pokazuje się tylko gdy jest niepusty - \ifdaydefed - \ifx\sinolDay\@tempempty - \else\sinolDayText\sinolDay.\ - \fi - \else\?{brak dnia}\erroutput{brak dnia}\fi - % - % Grupa - \ifgroupdefed - \ifx\sinolGroup\@tempempty - \else\sinolGroupText:\,\sinolGroup.\ - \fi - \else\?{brak grupy}\erroutput{brak grupy}\fi - % - % Dostępna pamięć -- pokazuje sie tylko gdy - % nie jest pusta i jest zdefiniowana - \ifMemorydefed - \ifx\sinolMemory\@tempempty - \else\sinolMemoryText:\,\sinolMemory\,MB.\ - \fi - \else\?{brak limitu pamięci}\erroutput{brak limitu pamięci}\fi - % - %% Limit czasu -- pokazuje się tylko gdy nie jest pusty i jest zdefiniowany. - \iftimedefed - \ifx\sinolTime\@tempempty - \else\sinolTimeText:\,\sinolTime.\ - \fi - \else\?{brak limitu czasu}\erroutput{brak limitu pamięci}\fi - \hbox to 0pt {\vbox to 0pt {\begin{itemize} \item[] \end{itemize}\vss}} - % Powyzsza linijka to smutny hak, ktory wymusza, zeby itemize'y - % generowaly prawidlowe odstepy. Nie wiem dlaczego to dziala, nie wiem dlaczego - % bez tego nie dziala. Have fun. - % Imo raczej można usunąć. - \hfill - \end{minipage} - } - \color{black} - \noindent - \smallskip - \par - \ignorespacesafterend -}{ - \concludetext - \closeout\inffile - \closeout\errfile -} - -% Odstepy w itemize -\def\@listi{\leftmargin\leftmargini - \parsep 0\p@ \@plus1\p@ \@minus\p@ - \partopsep 3\p@ \@plus1\p@ \@minus\p@ - \topsep 3\p@ \@plus1\p@ \@minus0\p@ - \itemsep 3\p@ \@plus1\p@ \@minus\p@} -\let\@listI\@listi diff --git a/example_package/in/abc0.in b/example_package/in/abc0.in deleted file mode 100644 index 38e65937..00000000 --- a/example_package/in/abc0.in +++ /dev/null @@ -1,3 +0,0 @@ --1 1 -3 -3 2 1 diff --git a/example_package/in/abc0a.in b/example_package/in/abc0a.in index 38e65937..8d04f961 100644 --- a/example_package/in/abc0a.in +++ b/example_package/in/abc0a.in @@ -1,3 +1 @@ --1 1 -3 -3 2 1 +1 2 diff --git a/example_package/out/abc0.out b/example_package/out/abc0.out deleted file mode 100644 index e8538b62..00000000 --- a/example_package/out/abc0.out +++ /dev/null @@ -1,2 +0,0 @@ -0.00000000 -1 2 3 diff --git a/example_package/out/abc0a.out b/example_package/out/abc0a.out index e8538b62..9165052f 100644 --- a/example_package/out/abc0a.out +++ b/example_package/out/abc0a.out @@ -1,2 +1 @@ -0.00000000 -1 2 3 +3.00000000 diff --git a/example_package/prog/abc.cpp b/example_package/prog/abc.cpp index 83cf097d..8d70c3ca 100644 --- a/example_package/prog/abc.cpp +++ b/example_package/prog/abc.cpp @@ -1,15 +1,14 @@ // Author : st-make -// Task : Zadanie przykładowe +// Task : Przykładowy tytuł zadania // Memory : O(1) -// Time : O(n) +// Time : O(1) // Solv : Rozwiązanie wzorcowe #include using namespace std; -long double a, b; -int n; +double a, b; int main() { ios_base::sync_with_stdio(0); @@ -17,16 +16,6 @@ int main() { cin >> a >> b; cout << fixed << setprecision(8) << a + b << '\n'; - - cin >> n; - for (int i=1; i<=n; ++i) { - // rozwiązanie wzorcowe nie powinno wypisywać na końcu wiersza białych znaków - if (i > 1) { - cout << ' '; - } - cout << i; - } - cout << '\n'; return 0; } diff --git a/example_package/prog/abcb.cpp b/example_package/prog/abcb.cpp deleted file mode 100644 index 8d5c871f..00000000 --- a/example_package/prog/abcb.cpp +++ /dev/null @@ -1,35 +0,0 @@ -// Author : st-make -// Task : Zadanie przykładowe -// Memory : O(1) -// Time : O(n) -// Solv : Rozwiązanie błędne - używa int zamiast double - -#include - -using namespace std; - -int a, b; -int n; - -int main() { - ios_base::sync_with_stdio(0); - cin.tie(0); - - cin >> a >> b; - cout << fixed << setprecision(8) << a + b << '\n'; - - cin >> n; - for (int i=1; i<=n; ++i) { - if (i > 1) cout << ' '; - cout << i; - } - cout << '\n'; - - return 0; -} - -// wzorcówka musi nazywać się abc.* -// pozostałe programy wzorcowe powinny nazywać się abc{}.* -// programy wolne powinny nazywać się abcs{}.* -// programy błędne powinny nazywać się abcb{}.* -// jako {} najlepiej dawać kolejne liczby od 1. Przykład: abcs2.cpp, abc10.py. diff --git a/example_package/prog/abcchk.cpp b/example_package/prog/abcchk.cpp index e171d6da..eb8e9f60 100644 --- a/example_package/prog/abcchk.cpp +++ b/example_package/prog/abcchk.cpp @@ -1,7 +1,10 @@ +#include #include "oi.h" -const int MIN_N = 1; -const int MAX_N = 10'000; +using namespace std; + +const int MIN_N = 0; +const int MAX_N = 1'000'000; [[noreturn]] void checker( [[maybe_unused]] oi::Scanner& tin, @@ -11,48 +14,22 @@ const int MAX_N = 10'000; // This is an example checker with partial scores. // Remove or change the code as needed. - // First line ok -> 20 points - // Second line ok -> 80 points - // Both wrong -> 0 points - int max_score = 100; - string verdict_comment; - double a, b; tin >> oi::Num{a, -1e6, 1e6} >> ' ' >> oi::Num{b, -1e6, 1e6} >> oi::nl; - // `oi::Num{a, x, y}` reads "a", where "a" is in the range - int n; - tin >> oi::Num{n, MIN_N, MAX_N} >> oi::nl; double sum; - user >> oi::Num{sum, -2e6, 2e6} >> oi::nl; + user >> oi::Num{sum, 2*MIN_N, 2*MAX_N}; // `oi::nl` in mode `oi::Scanner::Mode::UserOutput` ignores whitespaces before the newline. + // We do not load a newline in the last line. + if (fabs((a + b) - sum) > 1e-6) { - // If you want to fail the whole test, you could use `oi::checker_verdict.exit_wrong()` - // Here we want to check the output parts separately. - max_score = 80; - verdict_comment = "Pierwszy wiersz jest niepoprawny"; - oi::checker_verdict.set_partial_score(0, verdict_comment); - } else { - verdict_comment = "Pierwszy wiersz jest OK"; - oi::checker_verdict.set_partial_score(20, verdict_comment); - // When checker returns a wrong verdict (by calling `oi::checker_verdict::exit_wrong()` or - // when failing while scanning user output, the user will get 20 points instead of 0. + oi::checker_verdict.exit_wrong("Suma różni się od oczekiwanej"); } - for (int i = 1; i <= n; ++i) { - int x; - user >> oi::Num{x, i, i}; - if (i == n) { - user >> oi::nl; // `oi::nl` in mode `oi::Scanner::Mode::UserOutput` ignores whitespaces before the newline. - } else { - user >> ' '; - } - } user >> oi::eof; // `oi::eof` in mode `oi::Scanner::Mode::UserOutput` ignores newlines and whitespaces before the EOF. - verdict_comment += "; Drugi wiersz jest OK"; - // It ignores `oi::checker_verdict.set_partial_score` and gives the user the specified amount of points. - oi::checker_verdict.exit_ok_with_score(max_score, verdict_comment); + oi::checker_verdict.exit_ok(); + // oi::checker_verdict.exit_ok_with_score(80, "error message"); } int main(int argc, char* argv[]) { @@ -66,22 +43,20 @@ int main(int argc, char* argv[]) { // You can write checker tests in the following way: // (They won't be executed in sio2, they only work locally) -// CHECKER_TEST(TestInput{"0 1\n1\n1\n"}, TestOutput{"does not matter"}, UserOutput{"1\n1\n"}, CheckerOutput{"OK\nPierwszy wiersz jest OK; Drugi wiersz jest OK\n100\n"}) - -// // Or like this: -// CHECKER_TEST(R"( -// @test_in -// 0 1 -// 3 -// 1 2 3 -// @test_out -// does not matter -// @user -// 2 -// 1 2 3 -// @checker -// OK -// Pierwszy wiersz jest niepoprawny; Drugi wiersz jest OK -// 80 -// )") +// If you don't want to write, delete or comment. However, I recommend writing. +CHECKER_TEST(TestInput{"0 1\n"}, TestOutput{"does not matter"}, UserOutput{"1"}, CheckerOutput{"OK\n\n100\n"}) + +// Or like this: +CHECKER_TEST(R"( +@test_in +0 1 +@test_out +does not matter +@user +2 +@checker +WRONG +Suma różni się od oczekiwanej +0 +)") diff --git a/example_package/prog/abcingen.cpp b/example_package/prog/abcingen.cpp index 135448c0..164245d2 100644 --- a/example_package/prog/abcingen.cpp +++ b/example_package/prog/abcingen.cpp @@ -14,6 +14,11 @@ current_test.set_group(group); gen_test_reseed(current_test++, []() -> void { co using namespace std; oi::Random rng; +// Set task id! +const string get_task_id() { + return "abc"; +} + struct TestName { private: string tag; @@ -24,23 +29,17 @@ struct TestName { TestName() { max_group = 0; set_group(0); - tag = [](string path) { - auto end = path.rfind("ingen."); - oi_assert(end != string::npos); - auto beg = path.rfind('/', end); - if (beg == string::npos) { - beg = 0; - } else { - ++beg; - } - return path.substr(beg, end - beg); - }(__FILE__); + tag = get_task_id(); } ~TestName() { // Group 0 and 'ocen' are not required. - for (int i=1; i<= max_group; ++i) { - oi_assert(id.find(i) != id.end(), "there can not be a gap in the groups, you don't have " + to_string(i)); + bool there_was_a_gap = false; + for (int i=1; i<=max_group; ++i) { + if (there_was_a_gap && id.find(i) != id.end()) { + oi::bug("There can not be a gap in the groups, you don't have " + to_string(i) + " group."); + } + if (id.find(i) == id.end()) there_was_a_gap = true; } } @@ -119,105 +118,77 @@ void gen_test_reseed(string test_name, Func&& func, Args&&... args) { /////////////////////////////////////////////////////////////////////////////// -const int MIN_N = 1; -const int MAX_N = 10'000; +const int MIN_N = 0; +const int MAX_N = 1'000'000; +const int MAX_N_2 = 1'000; struct TestData { double a, b; - int n; - vector v; void print() { cout << min(a, b) << ' ' << max(a, b) << '\n'; - cout << n << '\n'; - for (int i = 0; i < n; ++i) { - cout << v[i] << (i == n - 1 ? '\n' : ' '); - } } }; void gen_0() { - cout << "-1 1\n"; - cout << "3\n"; - cout << "3 2 1\n"; + cout << "1 2\n"; } void gen_1ocen() { - cout << "-1000000 1000000\n"; - cout << "1000\n"; - for (int i = 1000; i >= 1; --i) { - cout << i << (i == 1 ? '\n' : ' '); - } + cout << "1.001 2.002\n"; } -void gen_2ocen() { - gen_1ocen(); -} - -void gen_proper_test(pair rn) { +void gen_proper_test(double p, double k) { TestData t; // `rng` also works with double. - t.a = rng(-1e6, 1e6); - t.b = rng(-1e6, 1e6); - t.n = rng(rn.first, rn.second); - vector v(t.n); - iota(v.begin(), v.end(), 1); - rng.shuffle(v); - t.v = v; + t.a = rng(p, k); + t.b = rng(t.a, k); t.print(); } -void gen1() { - double a = rng(-1e6, 1e6); - double b = rng(-1e6, 1e6); - cout << min(a, b) << ' ' << max(a, b) << '\n'; +double gen1(double p, double k) { + return rng(p, k); } -void gen2(int a=MIN_N, int b=MAX_N) { - int n = rng(a, b); - cout << n << '\n'; - vector v(n); - iota(v.begin(), v.end(), 1); - rng.shuffle(v); - for (int i = 0; i < n; ++i) { - cout << v[i] << (i == n - 1 ? '\n' : ' '); - } -} /////////////////////////////////////////////////////////////////////////////// void gen_all_tests() { current_test.set_group(ocen); // Group ocen. - gen_test_reseed("1ocen", gen_1ocen); - current_test.advance_id(); - GEN_TEST_RESEED(gen_2ocen()); + GEN_TEST_RESEED(gen_1ocen()); - current_test.advance_group(); // Group 0. - gen_test_reseed("0", gen_0); + current_test.set_group(0); // Group 0. + GEN_TEST_RESEED(gen_0()); current_test.advance_group(); // Group 1. - gen_test_reseed(current_test++, gen_proper_test, pair{1, 100}); - GEN_TEST_RESEED(gen_proper_test({100, 100})); + GEN_TEST_RESEED(gen_proper_test(1, 10)); + gen_test_reseed(current_test++, gen_proper_test, 1, 10); + gen_test_reseed("1c", gen_proper_test, 1, 10); + current_test.advance_id(); + gen_test_reseed(current_test++, gen_proper_test, 1, 10); + // You can optionally use this method, (it gives you more freedom). current_test.advance_group(); // Group 2. - GEN_TEST_RESEED(cout << "0.001 1.34\n2\n2 1\n"); - GEN_TEST(12345678, gen_proper_test({100, 100})); - GEN_TEST_RESEED( - int x = MAX_N / 5; - gen1(); - gen2(x); + GEN_TEST(12345678, gen_proper_test(1, 1000)); + GEN_TEST( 12348765, + int x = MAX_N_2 / 2; + cout << gen1(1, x) << ' '; + cout << gen1(x, MAX_N) << '\n'; ); - GEN_TEST_RESEED_GROUP(1, gen_0()); - GEN_TEST_RESEED_GROUP(3, gen_0()); - GEN_TEST_RESEED(gen1(); gen2()); // Generates group 3, because last time it was 3. - GEN_TEST_GROUP(0, 12345678, gen_0()); + // A group of my choice + GEN_TEST_RESEED_GROUP(2, gen_proper_test(0, 1000)); + GEN_TEST_GROUP(1, 12345678, gen_proper_test(0, 10)); + GEN_TEST_RESEED_GROUP(3, gen_proper_test(0, 1000000)); + // This does not have a group. So generates group 3, because last time it was 3. + GEN_TEST_RESEED(gen_proper_test(0, 1000000)); return; } void gen_stresstest() { - // Optionally, print a small random test. + // Print a small random test. + gen_proper_test(0, 100); return; } @@ -228,7 +199,7 @@ int main(int argc, char* argv[]) { gen_stresstest(); return 0; } - oi_assert(argc == 1, "Run prog to create proper tests or prog stresstest seed to additionally generate stresstest."); + oi_assert(argc == 1, "Run '[prog]' to create proper tests or '[prog] stresstest [seed]' to generate stresstest."); gen_all_tests(); return 0; } diff --git a/example_package/prog/abcinwer.cpp b/example_package/prog/abcinwer.cpp index 4a5381fd..9669054f 100644 --- a/example_package/prog/abcinwer.cpp +++ b/example_package/prog/abcinwer.cpp @@ -1,81 +1,60 @@ #include #include "oi.h" + using namespace std; -const int MIN_N = 1; -const int MAX_N = 10'000; +const int MIN_N = 0; +const int MAX_N = 1'000'000; void inwer(oi::Scanner in) { // This is an example inwer. // Remove or change the code as needed. - double a, b; + double n, m; - in >> oi::Num{a, -1e6, 1e6} >> ' ' >> oi::Num{b, -1e6, 1e6} >> oi::nl; - // `oi::Num{a, x, y}` reads "a", where "a" is in the range + in >> oi::Num{n, MIN_N, MAX_N} >> ' ' >> oi::Num{m, n, MAX_N} >> oi::nl; + in >> oi::eof; + // `oi::eof` in `oi::Scanner::Mode::TestInput` mode allows only EOF. + // `oi::Num{n, x, y}` reads "n", where "n" is in the range // `oi::nl` in `oi::Scanner::Mode::TestInput` mode allows only a single `\n`. + // The template solution should not print whitespace at the end of the line. - if (false) { - // `oi::Num` works with ints and long longs and double and ... - long long x; - in >> oi::Num{x, 1ll, static_cast(1e12)}; - } - - oi_assert(a <= b, "optional msg"); - if (a > b) { + oi_assert(n <= m, "optional msg"); + if (n > m) { oi::bug("a > b, something is wrong with the generator"); } - int n; - in >> oi::Num{n, MIN_N, MAX_N} >> oi::nl; - vector v(n), vv(n); - for (int i = 0; i < n; ++i) { - in >> oi::Num{v[i], 1, n}; - vv[i] = v[i]; - if (i < n - 1) { - in >> ' '; - } else { - // The template solution should not print whitespace at the end of the line. - in >> oi::nl; - } - } - in >> oi::eof; // `oi::eof` in `oi::Scanner::Mode::TestInput` mode allows only EOF. - - // This checks whether `v` is a permutation of `1, ..., n`. - std::sort(v.begin(), v.end()); - for (int i = 0; i < n; ++i) { - oi_assert(v[i] == i + 1); - } - - //////////////////////////////////////// - // Validation of subtasks and pre-tests. + /////////////////////////////////////////////////////////////////////////// + // This part of the code validates subtasks and pretests. + + // Add more groups and pre-tests. auto is_subtask1 = [&]() -> bool { - return a <= 10 && b <= 10; + return n <= 10 && m <= 10; }; auto is_subtask2 = [&]() -> bool { - return a+b <= 1'000'000; + return n <= 1'000; + }; + auto is_subtask3 = [&]() -> bool { + return n <= 1'000'000; }; - // Add more groups. - auto is_0 = [&]() -> bool { - return abs(a - -1.0) < 1e-6 && abs(b - 1.0) < 1e-6 && n == 3 && vv[0] == 3 && vv[1] == 2 && vv[2] == 1 ; + auto is_0a = [&]() -> bool { + return fabs(n-1) <= 1e-6 && fabs(m-2) <= 1e-6; }; auto is_1ocen = [&]() -> bool { - return abs(a - -1e6) < 1e-6 && abs(b - 1e6) < 1e-6 && n == 1000; + return fabs(n-1.001) <= 1e-6 && fabs(m-2.002) <= 1e-6; }; - // Add more pre-tests. // Set up the subtasks and pre-tests you have. map subtasks = { {1, is_subtask1()}, {2, is_subtask2()}, - // Add more groups. + {3, is_subtask3()}, }; map sample_tests = { - {"0", is_0()}, + {"0a", is_0a()}, {"1ocen", is_1ocen()}, - // Add more pre-tests. }; string subtasks_s; @@ -89,8 +68,8 @@ void inwer(oi::Scanner in) { // You can display various information. oi::inwer_verdict.exit_ok() - << "a = " << setw(8) << a - << ", n = " << setw(5) << n + << "n = " << setw(8) << n + << ", m = " << setw(8) << m << " | subtasks = " << subtasks_s << ", sample test = " << sample_test_s; } diff --git a/example_package/prog/abcs.cpp b/example_package/prog/abcs.cpp deleted file mode 100644 index d0056a4c..00000000 --- a/example_package/prog/abcs.cpp +++ /dev/null @@ -1,42 +0,0 @@ -// Author : st-make -// Task : Zadanie przykładowe -// Memory : O(n) -// Time : O(n*log(n)) -// Solv : Rozwiązanie wolne - sortuje liczby z wejścia - -#include - -using namespace std; - -long double a, b; -int n, x; -vector v; - -int main() { - ios_base::sync_with_stdio(0); - cin.tie(0); - - cin >> a >> b; - cout << fixed << setprecision(8) << a + b << '\n'; - - cin >> n; - for (int i=1; i<=n; ++i) { - cin >> x; - v.push_back(x); - } - sort(v.begin(), v.end()); - - for (int i=0; i 0) cout << ' '; - cout << v[i]; - } - cout << '\n'; - - return 0; -} - -// wzorcówka musi nazywać się abc.* -// pozostałe programy wzorcowe powinny nazywać się abc{}.* -// programy wolne powinny nazywać się abcs{}.* -// programy błędne powinny nazywać się abcb{}.* -// jako {} najlepiej dawać kolejne liczby od 1. Przykład: abcs2.cpp, abc10.py.