Ostatnie posty

na qoj.ac są już zadanka z tej edycji potyczek: https://qoj.ac/category/704
i zeszłoroczne też (w przeciwieństwie do szkopul.edu.pl)
https://sio2.mimuw.edu.pl/c/pa-2026-1/ranking/
It seems the leaderboards here aren't being updated. This appears to be preventing CLIST from fetching data.
Wygląda na to, że tabele wyników nie są aktualizowane. To prawdopodobnie uniemożliwia CLIST pobieranie danych.
W tym roku z dużą przyjemnością pisałem w Ruście. Używałem Cargo, chociażby żeby nie musieć pisać pliczków konfiguracyjnych dla rust-analyzera. Normalnie odpalałem swój program przez `cargo run --release --bin pkn` (w skryptach dodając `--quiet`). W idealnym świecie przekazałbym tę samą komendę do `run.py` i po prostu by to zadziałało. `run.py -- $(which cargo) run --release --bin pkn` też byłoby ok.

`run.py target/release/pkn` nie działa, bo przez brak rozszerzenia `.e` podlega procesowi szukania pliku (swoją drogą `.e` to chyba jakieś rzadkie rozszerzenie, spodziewałbym się raczej `.bin`, ewentualnie `.out` z analogii do `a.out`). Zrobienie symlinku nazwanego `pkn.e` nie pomaga, bo symlink jest rozwiązywany. Finalnie miałem skrypt, który woła Cargo, kopiuje binarkę do nazwy z `.e` i dopiero odpala `run.py`. Nie jest to jakieś straszne, ale musiałem się troszkę wgłębić w to, jak działa skrypt.

Jeszcze jedna sugestia, choć potencjalnie bardzo trudna do spełnienia, jest taka, żeby interaktor i `run.py` były w jednym języku i zlinkowane razem (lub w jednym interpreterze Pythona). To chyba rozwiązałoby wiele problemów ze środowiskiem, w tym mój, o który się jednak mocno postarałem (tworząc sobie z pomocą Niksa środowisko z odpowiednią wersją Rusta, jakoś wrzuciłem sobie przez przypadek do PATHa też GCCa, który był jakoś wybrakowany i nie był w stanie zbudować interaktora; nie inwestygowałem tego za długo, tylko przerobiłem skrypt by korzystał z `/usr/bin/gcc`), ale też mogłoby na przykład pomóc z Windowsem.
Hi,

This was my first time participating in Potyczki Algorytmiczne. Thank you for the contest, absolutely amazing problems, I'll think for a while until I upsolve them!

I really enjoyed problems: MUL, KOD, KOS, PKN.

Thanks!

To everyone who used AI for problem solving during the contest (and not to just translate statements):

https://ibb.co/W7qVZ3Q
Chciałem docenić fenomenalny wynik Wojtka Raczuka w tegorocznych potyczkach! Naprawdę niewiele brakło, aby zakwalifikować się do finału! Gratuluję i dziękuję za DARK MODE, którego używam teraz codziennie!
ad.1 A skąd niby run.py miałby wiedzieć jak nazywa się flaga do lokalnej kompilacji której używasz. Wystarczyło dodać ją we flagach w run.py / dopisać sobie #define LOCAL na samej górze swojego kodu i było ok. Alternatywnie można było otworzyć std::ofstream do lokalnego pliku i używać jego zamiast cerr. Trzeba uważać by tego nie zasubmitować, ale nie przesadzajmy z trudnością.

Ale oczywiście też mam coś od siebie do dodania.
8) Kod błędu przekazany do funkcji wa(string) w kodsoc.cpp nie jest wyświetlany przez kodrun.py. wa() można dostac za przekazanie inputu, który ma za dużo testów (xd). Nasze programy nie dostają wtedy inputu, co w większości przypadków doprowadzi po prostu do crasha. W efekcie mamy na terminalu informację informację o crashu i lakoniczne "WA (punkty: 0)". Nie zgodzę się z Wojtkiem, kodrun.py nie jest zaawansowany, on jest po prostu bloated funkcjonalnością która nie była nikomu potrzebna/ nie była użyta, np. był werdykt SE który idealnie nadałby się na błąd w testach, ale kodsoc.cpp go nie używał bo po co.

To powiedziawszy oba zadanka interaktywne były fajne i liczę na powtórkę za rok, tylko z lepszym interaktorem :)
Ad ad 1: nie zgadzam się, ja podawałem plik wykonywalny, a run.py zgadywał sobie z niego prawdopodobną nazwę mojego kodu źródłowego i kompilował takowy. Więc dlatego to było takie zaskakujące. Gdybym podawał ścieżkę do kodu to w istocie kompilacja byłaby w pełni spodziewana. Nie mam teraz jak sprawdzić tego zachowania, aczkolwiek wierzę że jakby mój plik wykonywalny miał jakieś rozszerzenie typu .e czy .exe to może zachowanie byłoby inne, ale moje binarki (jak i chyba większości ludzi) nie mają zwyczaju specyfikowac rozszerzenia
ad1 - interaktor kompilował program tylko jeśli podałeś ścieżkę do pliku cpp. Jeśli podałeś ścieżkę do exe - tylko wykonywał. Choć zgoda - to zachowanie nie było nigdzie udokumentowane, a plik exe trzeba było samemu znaleźć.

ja od siebie dodam:
7) problemy z działaniem pod Windowsem. (Może po drodze gdzieś to naprawili; po pierwszych zadaniach zniechęciłem się i napisałem własny komunikator, więc przestałem śledzić zmiany). Jeśli program działa tylko pod jednym systemem, to wypadałoby o tym jasno poinformować. A już idealnie - dostarczyć gotowe rozwiązanie dla osób nielinuxowych typu działające środowisko albo chociaż gotowy obraz dockera, do którego wystarczy wrzucić swój kod i odpalić.
W tym roku mieliśmy przyjemność lub nieprzyjemność mierzyć się z zadaniami typu double run/komunikacyjnymi/zwał jak zwał. Same w sobie zadania były bardzo fajne i miałem sporą frajdę w ich rozkminianiu, pochwała dla Adama za wymyślenie takich ciekawych zadań. Jednak obraz wrażeń z pracy nad tymi zadaniami bardzo mocno popsuł interaktor/*run.py, który jest jakimś niedopracowanym półproduktem i przygotowanie zadań pod kątem technicznym kulało i mi osobiście sprawiło dużo cierpienia i spróbuję tu wymienić opisać szereg owych cierpień i wskazać wady, które mam nadzieję, że zostaną poprawione na przyszłość.

Zwrócę uwagę, że ten skrypt run.py ma jakieś 400 linii i jest niezbyt przejrzysty. Jak chce się mieć jakiś czas na robienie zadań, to trochę nie ma jak go dogłębnie analizować i zawodnicy powinni móc go traktować jako czarną skrzynkę, do której nie powinni i nie potrzebują zaglądać, aby móc w pełni wygody pracować nad zadaniem i umieć robić podstawowe rzeczy w stylu normalnie debugować swój kod lub mierzyć czas wykonania (i to samo też się tyczy interaktorów soc.cpp, choć ich problem o tyle mniejszy, że są one przejrzystsze)

1) run.py kompiluje za każdym razem nasz program od zera ... czemu :|?
Wyjątkowo dziwny pomysł nastręczający szeregu problemów. U mnie się objawił tak, że nie widziałem stderr swojego programu (bo jak każdy rozsądny człowiek stderr wypisuję tylko jeżeli program jest skompilowany z flagą LOCAL, której run.py oczywiście nie dodawał), co de facto sprawiało, że nie za bardzo jestem w stanie jakkolwiek debugować swój program i widzę jedynie OK/WA (debugowanie przez couty oczywiście nie wchodziło w grę, a jakby ktoś umiał jakieś czary w stylu używanie debuggerów do podglądania wartości zmiennych, to zakładam, że też jest skazany na niepowodzenie z tym całym setupem). Na szczęście się ogarnąłem, że mogę chociaż widzieć zgłaszane znaki poprzez modyfikację pknsoc.cpp, ale to trochę mało, bo wolałbym mieć dostęp do pośrednich danych swojego algorytmu. Założyłem, że w tych 400 linii stawiania pipów gdzieś mój stderr jest zjadany i ignorowany, a się właśnie końcowo okazało, że ktoś wpadł na cudowny pomysł kompilowania mojego programu bez moich domyślnych flag. Moim zdaniem należy to jak najszybciej wywalić z tego interaktora, albo at the very least informować caps lockiem w treści zadania, że ten interaktor robi takie bardzo dziwne coś. No i poza jasną wadą o innych flagach jest też inna jasna wada w postaci, że z każdym uruchomieniem trzeba czekać parę sekund na kompilacje naszego programu.

2) Niewidoczny cout interaktorów.
Interaktory na koniec interakcji miały napisane wypisywanie na stdout, że wyszło w iluśtam zapytaniach albo że WA z jakiegośtam powodu albo że format ina zły itd. No właśnie, ale nie przekładało się to jakkolwiek na rzeczywistość, bo nie wiem co się z tym stdoutem interaktora dzieje, ale na pewno nie wypisywał się nigdzie w widocznym dla mnie miejscu i liczbę zużytych zapytań widziałem jedynie w podpisie zgłoszenia po submitnięciu na SIO. Ciężko mi uwierzyć, że to nie jest po prostu bug w run.py, bo dość oczywistym intended zachowaniem jest to, że te komunikaty powinne być widoczne dla zawodników przy uruchamianiu lokalnym? Było to jeszcze o tyle nieprzyjemne, że gdy coś z interakcji szło nie tak i interaktor przestawał z nami gadać, to nie było widać od niego tego komunikatu i zaczynały się wyświetlać bardzo mylące błędy sugerujące, że mamy bugi w programie, a był to np. zły format ina. Widać, że jurorzy sami nie za bardzo wiedzieli co się gdzie wypisuje, bo komenda do uruchamiania interaktora w treści miała "> [wyjscie]" sugerujące jakby coś się miało na ten stdout wypisywać, mimo że nic się nie wypisywało. Co więcej, zwróciłem na to dość szybko uwagę w pytaniu i została mi w odpowiedzi przyznana racja, ale zamiast być poprawione w 5 minut, to nie zostało to w ogóle poprawione do końca rundy?

3) Brak uruchomienia próbnego w PKN.
Nie rozumiem czemu go nie było. Skoro da się submitnąć to zadanie, to czemu postawienie uruchomienia próbnego było problematyczne? W KOD się już jakoś udało, więc chyba nie była to jakaś przeszkoda w SIO niezależna od jurorów PA? Mocno bolało biorąc pod uwagę, że to jasne, że ze wszystkich zadań to właśnie w tym byłoby najprzydatniejsze. Ale nawet będąc już postawionym przed faktem dokonanym, że owych uruchomień nie ma, to aby temu jakoś zaradzić powinny być właśnie chociaż zwiększone limity submitów. Prosiłem o to w pytaniach i owa prośba została odrzucona pomimo tego, że wydaje mi się zupełnie jasne, że jurorzy powinni się wykazać świadomością sytuacji jakim bałaganem od strony technicznej jest to zadanie i że w obliczu braku uruchomień próbnych zwiększenie limitu submitów jest dość oczywistym częściowym zamiennikiem (następnego dnia owy limit został zwiększony, ale z jakichś mniej istotnych powodów no i dla mnie too little too late). Brak uwzględnienia tej prośby oceniam bardzo negatywnie i niewątpliwie był to jeden z czynników, przez które moje cierpienia z PKN się wydłużyły o kilka godzin.

4) Niejasne liczenie czasu.
Z wielu różnych śmiesznych powodów jak kompilowanie od zera naszego kodu przez run.py czy inne śmiesznostki, czas działania komendy z treści jest jedynie luźno powiązany z faktycznym czasem działania naszego programu. W treści zadania jest jakoś zdefiniowane co się jako ten czas liczy, ale to za mało i powinien być dostarczony namacalny sposób jak go zmierzyć. Ja lokalnie na małym samplu miałem czas działania całości 3s, a na dużym samplu 4s, zatem faktyczny czas działania mojego programu wynosił 1s, a na sprawdzarce miałem mały sample 0.1s, a duży sample TLE przy 5s, co było dla mnie wybitnie zadziwiające. No i sformułowanie w treści faktycznie wskazywało, że te śmiesznostki skryptu run.py nie mają znaczenia na faktyczny mierzony czas, ale nadal ten skrypt powinien wyświetlać jakiś "oficjalnie" zmierzony czas. Teoretycznie mogłem sobie sam dodać jakiegoś clocka do pknsoc.cpp, ale po pierwsze zadanie powinno moim zdaniem zostać tak przygotowane, aby do dostarczonych kodów nie musieć zaglądać i ich modyfikować aby mieć dostępne takie podstawowe funkcjonalności, a po drugie miło by było być pewnym, że dobrze rozumiemy co faktycznie jest mierzone (widząc czas, który raportuje nam nasz czas działania), bo w przypadku wszelakich fuckupów (jak ten, którego ja doświadczyłem) zaczyna się kwestionować, że 2+2=4. Przez brak uruchomień próbnych i niski limit submitów nie mogłem sobie pozwolić na żadne binserczowanie ile razy mój program jest wolniejszy na sprawdarce i jakieś "interaktywne debugowanie" i jedyne z czym mogłem operować to informacja, że "u mnie działa, na sprawdzarce nie i nawet nie mogę sprawdzać działania na tej sprawdzarce", co było mocno frustrujące

5) A owym powodem, dla którego miałem taki rozjazd między czasem lokalnym, a czasem na sprawdzarce było to, że lokalnie odpalałem używając python3 (aka CPython), a na sprawdzarce jest używany pypy i używałem standardowej biblioteki, która w pypy działa 50-100 razy wolniej niż w CPythonie. Jest to oczywiście coś co _idealny zawodnik_ ogarnie, ale nie wszyscy uczestnicy są idealni i są oni tutaj bezpośrednio przez jurorów wsadzani na minę, bo w treści run.py jest uruchamiany przez właśnie python3, podczas gdy na sprawdzarce jest pypy, które jak widać zachowuje się zupełnie inaczej. W treści zdecydowanie powinien się znaleźć pypy, aby wiarygodnie lokalnie symulować to co dzieje się na sprawdzarce. (Tłumacząc dokładniej, komenda w treści wpływa niby tylko na to czego użyjemy do odpalenia run.py, ale potem przez magię run.py nasze rozwiązanie, jeżeli jest w Pythonie, jest odpalane z użyciem tego samego interpretera i gdyby w treści była komenda z pypy, to nie straciłbym kilku godzin życia).

6) Przeglądając pobieżnie run.py zauważyłem, że implementuje on jakieś opcje flag uruchomienia, które robią jakieś rzeczy. Środek bardzo długiego kodu to nie jest miejsce na dokumentację. Miejscem na dokumentację jest dokumentacja. Zawodnicy powinni być poinformowani o takich możliwościach, a nie dowiadywać się o nich przeglądając ten bardzo długi i zaawansowany skrypt. Aczkolwiek zauważyłem, że w treści KOD już zaszła poprawa i było wspomnienie, że takie opcje istnieją i jak się o nich dokładniej dowiedzieć.

Być może były jeszcze jakieś inne problemy, ale na chwilę obecną pamiętam tyle, a i tak się już dużo rozpisałem.

Dodajmy jeszcze do tego, że na kluczowe dla mnie pytanie, od odpowiedzi na które dla mnie dużo zależało, zadane o godzinie 19:00 dostałem odpowiedź dopiero o 23:00. Co prawda odpowiedzi nie były dla mnie szczególnie pomocne, ale na tamten czas wierzyłem, że mierzę się z jakimiś bliżej niezidentyfikowanymi problemami technicznymi, które nie są zależne ode mnie i czekam na zbadanie sprawy przez jurorów, a nawet jeżeli jednak zależą to może jurorzy wykażą się rigczem i zwiększą limit submitów, więc nawet takie mało pomocne odpowiedzi istotnie zmieniły moje podejście (że twierdzą, że wszystko w porządku i nie mam co się łudzić na zwiększony limit submitów i nie mam na co czekać i muszę sobie radzić sam), a po odpowiedzi raczej wnioskuję, że pomiędzy zadaniem mojego pytania a otrzymaniem odpowiedzi nie działy się po stronie jurorów żadne szczególne przemyślenia i równie dobrze mogłem dostać taką samą w minutę.
> W tej kategorii możnaby było dać więcej progów punktowych - z myślą o najmłodszych a bez straty dla wyjadaczy.

Ogólnie obecność w treści informacji o subtaskach i punktacji zdaje się przez lata fluktuować pomiędzy "jest dużo" i (jak w tym roku) "nie ma prawie wcale", zakładam że każde jury podejmuje tę decyzję inaczej? W trudnych zadaniach to też bardzo pomocne, bo jak się pisze bruta, to trzeba zgadywać czy jest coś warty. Na przykład nie było dla mnie jasne czy w SPL warto pisać bruta który w pełni rozkompresowuje ciąg.
To ja też dodam, że mi się podobało i się dobrze bawiłem, pomimo że nie zdobyłem tylu punktów ile bym chciał :)

Kilka troszkę dokładniejszych uwag ode mnie:
- Zadania C moim zdaniem były dobrane bardzo dobrze - myślę, że były interesujące dla początkujących, a bardziej zaawansowanym nie sprawiały większego problemu.
- Zadania B w większości przypadków zajęły mi więcej czasu niż zakładałem. W szczególności 4B i 5B KOD nie zdążyłem zrobić (na dowolną dodatnią liczbę punktów) pomimo, że trochę nad nimi siedziałem.
- Odnośnie zadań 2A i 3A to słychać dużo opinii, że były dość proste. Jednakże patrząc na ranking, to liczba rozwiązań za 10 punktów nie jest jakaś ogromna, wręcz powiedziałbym, że w sam raz.
- To co mi by się bardziej spodobało, to większa liczba jawnych podzadań. Przykładowo, w zadaniu 4B umiałbym napisać dość szybko program, który dostałby 2-3 punkty, ale zakładałem, że nie będzie takich grup testów.
- W zadaniu 5B KOD, które było trudne, ale zarazem bardzo fajne, zabrakło mi trochę prostszych podzadań. Na przykład jest fajne rozwiązanie działające dla n do binomial(20, 10) (około 180'000), ale nie miałem motywacji, żeby je pisać, bo nie dawało punktów. Ostatecznie wymyśliłem rozwiązanie, które (chyba) działałoby dla n do 10^9, ale też nie miałem motywacji, żeby je spisać. Gdyby było za to 1-2 punkty, to bym się chętnie pobawił :)
- Te zadania interaktywne to super sprawa :). Były mocno wciągające, mniej konwencjonalne i dawały dużo satysfakcji jak już coś zaczęło działać.

Także podsumowując, to dziękuję :)
Niee, ale trochę bałem się czasowo, najgorszy test Świstaka działał mi lokalnie ~6s (nie sprawdzałem na sio ale w innych zadaniach czasy lokalne i na sio miałem podobne), a na oficjalnych testach max czas był ~4.3s.
Z punktu widzenia zawodnika bardzo nie podobałoby mi się aby układanie testów miało zostać częścią konkursu i abym po zrobieniu wszystkich zadań nie mógł sobie dać spokoju tylko myśleć w tyle głowy "a może powinienem przygotować jakieś mocne testy aby poubijać innych". W tym roku faktycznie były dwie wtopy ze słabymi testami, ale historycznie chyba zdarzało się to bardzo rzadko. Rozleniwiałoby też jury i skutkowało tym, że oficjalne testy będą słabsze. Poza tym wyklucza łagodne ucinanie za bugi. Mi się wydaje, że ułożenie testów tak aby "za nieogarniecie x=0 w GRM" stracić coś w stylu 2 pkt miałoby sens, ale przecież nie będzie się definiować subtasku z takim warunkiem. Mogą być też pułapki których w ogóle nie powinno się definiować w treści bo jak się ją zdefiniuje to przestanie być pułapką.
Moje opinie na szybko (nie wiem, czy w przyszłym roku też będę w jury PA, ale może tak):
- pomysł jest fajny :)
- technicznie trzeba by naklepać to w SIO.
- na poziomie jury pojawiłaby się niepewność co robić, jak wzorcówka nie przejdzie któregoś z tych testów, np. na czasie. Wiem, że nie powinno to się zdarzyć, ale wciąż może.
- "za dużo testów" - szacując od góry, za zadanie KON 10 punktów wzięło około 400 osób. Pesymistycznie, jest to około 1200 testów (w praktyce dużo mniej), razy jakieś 500 submitów, nawet z limitem 1s (który KON miało) to daje jakiś tydzień pracy jednej sprawdzaczki (w praktyce więcej, bo jest narzut na scheduling). Obstawiam, że jednak dałbym K = 1, przynajmniej na początek, żeby zobaczyć, ile ludzi w praktyce by takie testy zgłaszało.
- do której paczki wchodzi - to jest praktyczny problem. W praktyce, jeśli definiujemy formalnie subtaski, to jako układacz testów czuję się w obowiązku wrzucić wszystkie special-case'y do wszystkich paczek. Zwłaszcza w dywizji B daje to niepożądany efekt, że za bugi polegające na nie łapaniu jakiegoś corner case'a tniemy do zera. A nie możemy opublikować definicji subtaska zawierającego "special case x = y = 0 znajduje się tylko w paczkach 7, 8, i 10", bo to super-hintowe.
Moglibyśmy definiować formalnie subtaski, ale nie publikować tych definicji (albo tylko część z nich).
- Jest też element dodatkowej pracy jury, że te limity na subtaski musielibyśmy formalnie wyspecyfikować (tzn. w jakimś kodzie, pewnie w weryfikatorze testów), i musiałby być jakiś system sprawdzający, czy przychodzący test spełnia te limity.

Ogólnie moim zdaniem to fajny pomysł, ale martwi mnie ilość pracy, którą trzeba by w niego włożyć.

Rozważyłbym też opcję super-taniego w przygotowaniu konkursu, gdzie w ogóle jury nie przygotowuje testów, tylko je crowd-source'ujemy w ten sposób :)
Sortowanie pseudonimów po nazwiskach w końcu naprawili.

PRÓG KOSZULEK TOP 32 dzieli osoby o równiej punktacji, czyli poniżej są licealiści i dorośli, a powyżej wszyscy nieletni i niektórzy starsi; w szczególności ostatni nad progiem uczęszcza do SP.

Ale za to znowu nie było przypomnienia mejlem o potyczkach, bo [RODO](https://sio2.mimuw.edu.pl/c/pa-2022-1/forum/188/36761/)