ICFPC 2020: итоги и выводы
Это шестая, заключительная часть моей серии отчётов об ICFPC 2020. Остальные части ищите здесь:
- предисловие;
- день первый;
- день второй;
- день третий;
- день четвёртый;
- итоги и выводы (это то, что вы сейчас читаете).
Мы заняли 38-е место из 95-и, при этом 30 команд не заработали ни единого балла. Я удивлён, что мы не оказались среди их числа.
О задании
Делать тизеры частью задания нельзя. ICFPC длится 72 часа, а не две недели. Те, кто вникал в тизеры, в час T просто нажали F5 на ReadTheDocs и продолжили то, что делали предыдущие 14 дней. Формально это давало некоторым командам преимущество.
Дальше. Правила соревнования1, пункт 2, гласят (выделение моё):
[…] Teams may not divide, merge, or collaborate after the start of the contest.
Вопреки этому соревнование началось именно с призыва собраться в Discord и сообща разгадывать сообщения. Первые сутки мы не могли делать ничего другого, кроме как коллаборироваться. Соревнование как таковое началось только спустя 24 часа 45 минут.
«Космолисп» и galaxy.txt оказались просто большим сайд-квестом. Да, там были туториалы, способные помочь с основной задачей, но с тем же успехом мы, наверное, могли проспать первые 46 часов, а после публикации описания команд зависнуть в Discord и таким образом выяснить всё, чего не знали.
За «космолисп» обидно вдвойне: вещь красивая, но программировать на нём довелось только при написании тестов.
Задание было, фактически, «матрёшкой» из загадок, а ядром её оказалось довольно скучная задача по управлению космофлотом. Да, там была неожиданная метрика расстояний и странная гравитация, но интереса задаче придавали исключительно загадки, в которые она была спрятана.
Я думаю, что понимаю исходные организаторов: сеттинг, загадки, «матрёшечность» задания, финальное видео — всё это складывается во вполне стройный набор идей и предпосылок. Озвученные выше огрехи допущены вовсе не по расхлябанности; они являются прямым следствием попытки сделать уникальный контест.
Как я уже писал, ICFPC похож на жизнь, но у него есть одно ключевое отличие: какая бы ни творилась дичь, насколько плохо не шли бы дела команды, я абсолютно точно знаю дату и время, когда всё это закончится. Это даёт организаторам некоторый карт-бланш, и в этом году им воспользовались по максимуму.
«Контур», не знаю, читает ли кто-то из вас этот отчёт, но: вы провели действительно выдающийся ICFPC, и я снимаю перед вами шляпу. ❤️
Об организации соревнования
Вместо финального зачёта было восемь мини-контестов длиной от двух до восемнадцати часов. Чтобы выиграть, нужно было хорошо выступить во всех. Фактически это гарантирует, что команды выкатят в продакшен первый работающий прототип, и в дальнейшем будут допиливать его, а не исследовать альтернативы. Мне это кажется бессмысленным ограничением, я не понимаю, зачем так сделано.
Созданный организаторами антураж — бесподобен. Для приостановки неверия достаточно было не читать никаких новостей, кроме блога Ивана Зайцева.
Техническая часть также была сделана отменно. Самое страшное, с чем я столкнулся — это периодически отваливающиеся websocket-ы. Всё остальное работало просто превосходно: билды за разумное время, нормально обновляющийся лидерборд, никаких проблем с визуализатором и прочей инфраструктурой. Не исключаю, что в конце соревнования мне только казалось, что билды стали чуть медленнее.
О командной работе
Чтобы решить много загадок и проверить много идей, нужно много светлых голов и вдвое больше рук. Пожалуй, моим основным вкладом в нынешний результат было приглашение IngvarJackal-а и pink-snow к нам в команду: именно они написали львиную долю того кода, что завоевал нам 38-е место.
Даже самым светлым головам нужна организация труда, будь то менеджер, вики знаний, или же расписание статус-митингов. Для команды из восьми человек чат уже не может использоваться для хранения знаний — слишком большой объём и слишком мало структуры. Без должной координации часть потенциала участников останется неиспользованной; так, мне кажется, случилось в этом году с mr146, unclechu и Akon32 — любые поставленные задачи они решали быстро, да вот списка задач у нас не было, и часть времени была потеряна впустую.
Когда программист переключается с «не-своего» на «свой» язык, разница в производительности поражает. Из-за этого Форневер подумывает в будущих контестах объединять языки через IPC, чтобы каждый писал на чём ему удобно. Также напрашивается идея разделиться на мелкие «одноязыковые» команды, но я так не хочу.
Самоуверенность убивает. Я пресёк две попытки превратить функцию reduce
в полноценную «вычислялку» «космолиспа» и, таким образом, задержал прогресс
команды на целые сутки.
Самоуверенность убивает, часть вторая: если сокомандник что-то пишет в чат — прислушайся! При перечитывании лога мне в глаза постоянно бросались «голоса разума»: «пора делать это», «нужно сконцентрироваться на том». В пылу контеста эти сообщения легко воспринять просто как очередной TODO, коих и так десяток на человека, но с этим импульсом необходимо бороться.
Когда мы играли впятером, разного рода «вспомогательные программы» и «прототипы», не находя поддержки команды, отмирали сами собой. В этом же году у нас оказалось достаточно рук, чтобы выполнить одну и ту же работу трижды, на трёх разных языках. Результат неоднозначен: с одной стороны, только благодаря такой свободе мы попали в лидерборд; с другой, обилие несовместимых реализаций демотивирует команду и создаёт трения. Я хочу продолжать играть с этими людьми, поэтому в будущих контестах буду сопротивляться повторению этой ошибки даже в ущерб производительности.
Приглашаешь людей — подумай, как будешь координировать их работу. Взялся координировать — считай это своей основной деятельностью, а не «так-то я программист, просто пару раз в день ещё и переклички делаю».
О Python
Что произошло: IngvarJackal написал прототип на Python; к началу оценивания у нас не было работающего бота на Haskell; прототип на Python ушёл в продакшен; система оценивания заставила меня допиливать то, что уже работает, а не то, что я хочу. Отсюда ирония и картинки с Гарольдом.
Сам я надеюсь больше никогда не повторять этот опыт, но хотел бы записать одну мысль для команд, использующих Python в качестве основного языка на ICFPC. Вероятно, мысль можно расширить на любой интерпретируемый язык.
В этом году задача подразумевала отправку кода на сервер организаторов, где он проходил тестирование и отправлялся в бой с сабмишенами других команд. Это очень важный момент: он напрямую влияет на длительность цикла отладки. Опечатки и ошибки типов, не пойманные локально, будут стоить вам около пяти минут каждая: примерно столько времени в этом году проходило между моим пушем и появлением на сайте лога с тестовым прогоном кода.
Если бы мы решали какую-то оффлайновую задачу (например, про оригами), расклад был бы совершенно другим: опечатки можно было бы поймать за считанные секунды, и Python (по этому критерию) оказался бы наравне с компилируемыми языками. Но в этом году расклад был неудачным, и мы потеряли много времени и нервов. Да что там: оба кандидата на финальный сабмишен были забракованы именно из-за банальной ошибки с именами.
Урок (как мне кажется) в том, что Python нужно либо плотненько обкладывать тестами, либо же ограничивать его применение вещами, которые можно полностью проверить локально. Вместо тестов могут сгодиться type hints, mypy и ещё какие-нибудь чекеры и линтеры, но в этом я уверен чуть меньше.
На этом всё. Наш код можно найти на GitHub. Команда в этом году была настолько большой, что за всеми не уследишь, так что в дополнение к моему отчёту поглядите ещё и на мысли Форневера. Надеюсь, позже в README репозитория появятся ссылки и на другие отчёты.
Надеюсь увидеть тебя, дорогой читатель, и твою команду в лидерборде ICFPC 2021 ;)
Your thoughts are welcome by email
(here’s why my blog doesn’t have a comments form)