July 21st, 2020

IPFCP, ой, то есть ICFPC-2020

Ровно 11 часа назад закончился ICFPC 2020. Так как я предусмотрительно взял выходной на остаток дня, готовьтесь, сейчас буду РАССКАЗЫВАТЬ. Отчет за прошлый год тут.

Тэ минус семь дней

За неделю до соревнования организаторы начали выкладывать затравочки. Выглядели они примерно так:

Больше сообщений здесь.

Энтузиасты быстро сообразили, что это закодированные числа и простые операции, типа сложить-умножить-больше-меньше. Делать с этим было особенно нечего, разве что написать парсер-сериализатор. Вдруг пригодится. Я написал (спойлер: не пригодился :). 

Все это сопровождалось довольно милыми инсценировками от лица сотрудников вымышленной уральской обсерватории. Примерно такими:

Сразу видно, ребятам было весело! Да и какой программист не мечтает напялить халат, сунуть в карман перфокарты, перейти на язык международного научного общения — примитивный английский с очень сильным акцентом — и хотя бы на секунду представить, что занимается настоящей наукой, а не этим, прости господи, реактом.

Перечитав свой отчет за прошлый год, я также решил подготовиться инфраструктурно. Чтобы не тратить ценное время на javax.swing.JFrame jframe = new javax.swing.JFrame() во время соревнования. Хоть задание и неизвестно, можно сделать что-то универсальное, типа запускателя задач, загрузки реплеев, и так далее. Как-то так выглядело:

По выравниванию кнопок и дерганью панелек можете оценить, какой из меня Свинг-программист (никакой). Спойлер: тоже не пригодилось :)

Опять же, по следам прошлого года, я решил брать не Кложу, а Джаву. Соображение было такое, что байтики перекладывать в Кложе все равно не особо удобно, скорость программы перевешивает скорость разработки, а Раст я так и не выучил за год. Короче, компромис.

Под это дело я завербовал двух местных единомышленников (@intelliyole и @pdrobushevich, спасибо вам, если вы это читаете!), мы приехали в офис JetBrains в Мюнхене, я нарисовал нашему телеграмчику логотип и мы стали с ужасом ждать пятницы.

Команда называлась Please disable AdBlock
Команда называлась Please disable AdBlock

Тэ ноль

В момент старта соревнования... ничего не произошло. Точнее, выложили еще пачку картинок, и... все! Самое удивительное ощущение от соревнования, что вот оно, началось, а что делать — непонятно! Мы готовы, сидим, на низком старте, все JIT-ты прогреты, а куда программировать — непонятно!

Офигиваем от отсутствия задания.
Офигиваем от отсутствия задания.

Первые пять часов чат сообщества пытался коллективно угадать назначение символов и что же, собственно, нужно делать. Не все давалось легко: например, вот этой функции так и не придумали названия. До самого конца соревнования во всех документах она так и проходила как f38.

А вот это просто милая отсылка к Пионерам, сразу видно, культурные люди соревнование проводят:

Тэ плюс 4:30

Только в 19:30 (!) наконец-то выложили задание. Стало можно запрогать хоть что-то. @Yole написал нам первую версию интерпретатора, которая смогла посчитать функцию 2^N на инопланетном языке и ушел спать. Правда, galaxy.txt она считать отказалась, а почему — непонятно.

Я, как настоящий человек-сова на кокаине, подхватил эстафету, потыкал Джавную версию и сел писать свою версию на Кложе. И это, скажу я вам, совсем другие ощущения. Как будто ты вышел на трек в кирзовых сапогах, и даже какое-то время в них бежал, и вдруг сменил их на удобные спортивные кроссовки. Не то чтобы в Кложе какие-то особенные фичи я заиспользовал, нет: самый обычный код, парсинг строки, тусовка массивов. Просто там все удобнее сделано! Циклы, ифы, функции, коллекции. Даже в сравнении с самой последней 14-й Джавой, со всеми ее рекордами, стримами, ломбуками и стейт-оф-зе-арт ИДЭ от работодателя. Последний раз на Кложе я писал в 2018, с тех пор поработал на Расте, Джаве, Котлине, C++, но за эти три дня ощутил снова, как в первый раз: Кложа — язык, наиболее близкий к форме мыслей программиста. Пишешь как думаешь. И это, ребята, дорогого стоит. И это еще до того, как начнутся по-настоящему продвинутые фичи. Короче, писать можно на чем угодно, но получать удовольствие, по-настоящему, — только от Кложи.

За ночь с первого дня на второй я этот интерпретатор написал. Это, собственно, субъективно, и была лучшая часть соревнования. Во-первых, пять-восемь часов самозабвенного кодинга под звуки спящих птиц, медленно всходящего солнца, ночных мусоровозов и неврозных автосигнализаций.

Во-вторых, я наконец-то пощупал лямбда-исчисление руками. То есть я про него конечно слышал, но глубоко не вникал. Тут же мы собственно компьютер на нем написали, по пути разобравшись, как люди выкручиваются, чтобы простые и привычные конструкции в него засунуть. Вот это B, C, K, W system и вот это SKI combinator calculus и вот это Logic and predicates и вот это Pairs. Скажем, cons/car/cdr очень остроумно придуманы:

true  := λx.λy.x
false := λx.λy.y
cons  := λx.λy.λf.f x y
car   := λp.p true
cdr   := λp.p false

То есть cons (pair) это такая частично-вычисленная лямбда от трех аргументов, замкнутая на два. Третий аргумент — это функция, которую cons потом к первым двум аргументам и применит. Собственно, чтобы получить первый аргумент из cons (car), мы ему передаем функцию от двух аргументов, которая возвращает первый и игнорирует второй, cons ее вызывает, и вуаля: мы достали голову списка!

Я этого как-то не знал, и было очень интересно узнать. Действительно остроумно же! Жить так нельзя, конечно, но для теории программирования важно все равно.

Наконец, третий счастливый момент связан с тем, во что эта программа выливается. Представьте себе, сижу я всю ночь, ковыряюсь примерно в таком:

и таком:

и вот спустя часов восемь возни с двухбуквенными идентификаторами, ручным декодированием бинарных кодировок, собирания в уме списков из cons-ячеек, программа наконец запускается и СОВЕРШЕННО НЕОЖИДАННО выводит В ТЕРМИНАЛ, одно из самых некрасивых мест на планете, такое:

Более того, спустя еще несколько часов выклянчивания подсказок в чате, исправления багов, приделывания таки свинг-окошка на экране ВНЕЗАПНО рисуется такое:

И это, скажу я вам, офигенный драматургический момент. Как выход из платоновской пещеры практически.

Задокументировано!
Задокументировано!

Тэ плюс 20 часов

На этом хорошие новости, да и соревнование в целом, для меня закончились. Оказалось, что запустить галактику — полдела. Это обязательное условие, но оно не засчитывается никак. Чтобы получить хоть одно очко, нужно что-то с этой галактикой сделать. Только неизвестно что. Помните старые поинт-энд-клик квесты вроде Петьки и Василия Ивановича, где нужно из дамской сумочки, валенка и мясорубки догадаться собрать пулемет?

Тут примерно то же самое, только на инопланетном языке, с пиксельной графикой и без какого-либо feedback loop. Вот я прокликиваю через пару задачек:

Типа, вот так вот. Милая пиксельная графика, да! Но никаких дополнительных пояснений, контекста, намеков, ничего вообще нигде было. Что это? Что это значит? Что с этим можно сделать? Надо ли вообще что-то с этим делать? Продвигаюсь ли я вперед или топчусь на месте? Ситуация осложнялась тем, что интерпретатор написал ты сам. То есть ты никогда не знаешь, где действительно загадка, где просто «фантазия художника», где задание, где тебе пытаются что-то сказать, а где просто оформление, где баг твоей реализации, а где баг организаторов (было и такое).

Например. В левом верхнем углу галактики (важное место, да?) нарисовано:

Что читается как: ap ap mul pwr2 34 ?. Что не очень много смысла имеет, потому что даже по количеству ap неверно. Вот как это понимать? И что с этим делать? И так в каждом квесте в лучшем случае (тут хотя бы прочитать можно).

Насколько это сложно? Из двухсот начавших соревнование команд только одна (!) сообразила, что нужно было делать, и только через 11 часов после начала соревнования. Вторая подтянулась на T+20, всего к моменту окончания лайтинг раунда «что-то» сделали 5 команд. Всего ПЯТЬ команд смогли сделать ПЕРВЫЙ шаг (и тольк две из них — второй и далее). Кто-то из них в чате писал, что не знает, что именно они сделали. Даже спустя все три дня я до сих пор не знаю, что конкретно требовалось сделать и за что давались очки.

Тэ плюс 24 часа

Вторые сутки я отходил от ночного марш-броска и ничего не делал. Ребята что-то поковыряли, но особо мы никуда, кажется не продвинулись.

Тэ плюс 48 часов

Первые несколько часов ушли на то, чтобы просто разобраться в происходящем. Паша пытался сделать сабмишн, который бы проходил минимальный тест (отправлял команды JOIN и START), но из-за отсутствия репортинга ошибок (любого, вообще) это оказалось сложнее, чем кажется.

Если перепрыгнуть сразу к выводам (а дойти до них было непросто), нужно было управлять кораблем, но правила сражений неизвестны, формат команд неизвестен, вообще ничего неизвестно, кроме докер-образа, в котором надо сдавать задание. Причем это не временное ограничение, а именно принципиальная позиция, суть соревнования. Это соревнование не алгоритмов, и не программирования вообще, а квестовой смекалочки.

Примерно так выглядят те крупицы знаний, которые сбросили нам организаторы:

И это, собственно, момент, где я из соревнования по большому счету выбыл. То ли я тупой, то ли мой мозг как-то по-другому устроен, но с самого начала соревнования я не разгадал НИ ОДНОЙ загадки и ни до чего сам не догадался. И это не преувеличение, я не скромничаю и не имею в виду «очень мало догадался». Нет, буквально НИ-ЧЕ-ГО. ВСЁ происходящее я понимал или из дискорд-чата, где другие такие же бедолаги делились крупицами знаний, либо из подсказок организаторов, которые обычно выдавались на сутки позже для совсем тупых вроде меня.

А вот один из организаторов сжалился надо мной и подписал стрелочками для тупых, что один зеленый квадрат — это туториалы, а другой идентичный квадрат — «мультиплеер»:

В общем я очень хотел, но не смог играть. Я запустил корабль и он полетал по орбите, но это все, что я смог сделать за сутки. Дальше просто стена, что делать — непонятно. Все более успешные команды сбежали из чата, и дух коллективной разгадки тайн и научной коллаборации быстро выдохся.

Я, конечно, не могу оценить, как игра происходила на высших уровнях, может быть, там открывалась какая-то глубина происходящего, но из того, что было доступно мне — корабль мог летать, мог стрелять и мог взрываться. При этом взрыв приводил к немедленному проигрышу, то есть не очень понятно зачем нужен. Стрельба не приносила никакого эффекта — все игры, которые я видел, даже у топовых команд, если и пытались стрелять, это никак на результат не влияло. Игры всегда завершались либо по истечении лимита ходов, либо падением одного из участников на планету. Повлиять на орбиту противника никак нельзя, столкновений нет, то есть, буквально, единственная действенная стратегия — ждать и надеяться, чтобы противник упал первым.

Я бы хотел искать алгоритмы получше, обдумывать стратегии, сравнивать варианты, писать код, оптимизировать код — да на любую осмысленную деятельность я был готов, жаждал даже, да даже зашиваться от количества работы или от сложности проблемы был бы рад, но увы, видимо, не в этот год.

Что понравилось

Принудительный ликбез по лямбда-исчислению.

Душевные театральные постановки.

Отличная пиксельная графика и стильные интерфейсы настолько минимальными средствами.

Красивая виртуальная машина и написанная на ней программа. Я не устаю поражаться, насколько много всего (целую интерактивную галактику, квесты, туториалы, реплеи и мультиплеер) удалось запрограммировать и запаковать в такой примитивный формат как голое лямбда-исчисление и что оно очень даже сносно работало. Чувствую себя прикоснувшимся к самым основам компьютер сайнса.

Что не понравилось

Высокий, рискну даже сказать, неприступный порог входа, фактически лишивший возможности участвовать в соревновании.

Туториалы, блокирующие тебе саму возможность участия в ладдере. К счастью, кто-то в чате хакнул образ программы и нашел способ их пропустить.

К смеху, даже после всех обсуждений и после окончания соревнования у меня до сих пор нет идей, как некоторые из них проходить. Напоминаю, что по официальной версии они являются обязательными.

Излишняя завязанность на сервер даже там, где это не нужно. Скажем, локальные туториалы и локальный сингл-плеер требуют наличия сервера, хотя логически он ни за чем не нужен. Это печально, потому что в прошлом году после окончания соревнования я еще несколько недель с ним ковырялся, переписывал на расте, в общем, всячески взаимодействовал.

Смешно, что хотя локальные игры и требуют сервера, против сервера нельзя поиграть тестовую игру. Нужно самому городить два локальных инстанса, соединять их, и т.п. Хотя казалось бы.

Другая очевидная проблема завязанности на сервер: ошибки 400, таймауты, сброс стейта игры, внезапное возрождение предыдущего стейта и полное отсуствие контроля над всем этим. Когда ты не уверен в том, насколько хорошо работает твой эмулятор, твой прокотол общения, твой бот, добавление в этот микс случайных не зависящих от тебя ошибок не очень помогает понимать происходящее.

Отладки и ошибок нет от слова совсем. Что-то не так? Пошел нахуй. Вот тебе, список из нуля: (0). Нет, серьезно. Так выглядят ошибки. Список из нуля. Не просто ноль. Список. (cons 0 nil). На любой чих или это, или 400 иди нахуй, без сообщения.

Излишняя, как мне показалось, запутанность схем отправки/взаимодействия с сервером организаторов. Из-за этого я не могу, например, показать вам код программы, а человек с улицы не может уже попробовать в игру поиграть (нужен ключ, выдававшийся при регистрации).

Слишком большое количество ресурсов, информация по которым была размазана примерно равномерно и все из которых регулярно обновлялись:

Очень большая задержка в обновлении ладдера. После отправки своей версии требовалось несколько часов (!), чтобы узнать, как выступила одна из твоих версий.

Шрифт JebBrains Mono вместо Fira Code на сайте 😘

Что удивило

Очень неожиданный формат, заставший врасплох. Чувство новизны оно такое, может не из самых приятных, зато позволяет почуствовать себя живым.

Что у меня что-то не влезло в монитор :)

Внезапно, меня поблагодарили в титрах. Мама, я теперь медиа!

С большой вероятностью меня прочитают организаторы, так что во-первых привет-привет!, а во вторых спасибо и вам тоже за такие крутые американсие горки!

Себе на будущее

Надо таки делать свой визуализатор. Второй год подряд мне кажется, что предоставленного организаторами окажется достаточно, тем более что в обоих случаях они неплохи. Но потом в какой-то момент ты вдруг понимаешь, что уже четыре часа как накликиваешь одни и те же тривиальные операции, стартуешь по два параллельных процесса в консоли, копируешь айдишку из одного в другой, что это ужас-ужас, но ты вроде как бы уже и привык. Особенно не помогает, что четкого перехода из «я ничего не понимаю что надо делать вообще» в «я все понял, тестирую гипотезы и мне нужна максимальная эффективность в их запуске» нет, поймать этот момент крайне трудно.

Нет, свою жизнь надо автоматизировать, и чем раньше, тем лучше. Конкретно в этом случае мне потребовалось некоторе время, чтобы понять, что вся та сложная виртуальная машина на 320 кб лямбд для отображения стейта, да и для игры вообще, не нужна. То есть она как бы нужна, но не нужна. Это сложно объяснить, короче. Мораль такая, что свой визуализатор будет нужен.

Напоследок вот вам глаза «Ивана Зайцева, астронома», которые смотрели на нас из каждой ссылки на его гитхаб. Пусть и на вас смотрят, прямо в душу: