Advent of Code 2024

· 4 min read

В прошлом году был план затащить на работе 10-15 человек в приватный дашборд, чтобы дошли 2-3 человека до конца. Вы не поверите, но в этом году на работе 18 человек решило хотя бы 3 дня, а до конца дошло 3 человека. Так что иногда достаточно просто подождать…

В этот раз решил, что пост будет чуть длиннее. Хочется рассмотреть разные аспекты: про этот год, про Clojure, про подходы к решению, про глобальное комьюнити и про локальные ячейки. Но традиционно начну с цифр:

private leaderboard

Чуть лучше в среднем, чуть хуже в одиночном и всё ещё очень далеко от @webholt. С другой стороны, в этом году мог начинать решать только через 2 часа после начала (пока дочку собрать, пока в сад отдать), так что наличие прогресса — это хорошо.

В приватном дашборде на работе опустился со второго места на третье, потому что стало больше людей (привет, Никита!):

private leaderboard

Про этот год

В одном меме:

2d grids

Есть несколько хороших и не очень моментов. Хорошее — в этом году было много задач на 2D гриды, и, как следствие, можно было отработать все навыки: BFS, DFS, Дейкстра и A*; всё это рекурсивно и итеративно соединено с пирожком динамического программирования. Если всё в этом абзаце пугает, то смело решайте этот год.

Второе — снова была математика, но после прошлого года ничего зубастого не попалось. Отдельно порадовало, что на 13 день вместо вывода формулы Крамера достаточно было сделать pip install z3.

В целом, в этом году многое решалось если не брутфорсом, то брутфорсом + functools.cache. Это радикально отличается от 2022 года, да и данные показывают, что сложность этого года ниже средней. Или этот график показывает прогресс LLMs. Так, что если хотите вкатиться, то это лучший год для того, чтобы это сделать.

Про Clojure

По аналогии с прошлым годом, первые пять дней было принято решать на новом языке. Выбор стоял между Zig, чем-то из Lisp и Julia. Народным голосованием был выбран Clojure. За плечами не было никакого опыта с ним, поэтому перед стартом проходил http://clojurescriptkoans.com/ и Animated book. Также был найден файл с полезными утилитками.

Всё это помогло мне ровно никак. По сравнению с Rust — среди AoC пользователей Clojure не было достаточно системности: юнит-тесты никто не писал, обвязок тоже не было, так что приходилось решать руками. А руками решать не получалось из-за отсутствия опыта на тренажёрах и в реальных проектах. После перехода задач на 2D гриды становилось совсем худо: хотелось императивщины со стеком, очередью, без рекурсий и с простой мемоизацией.

Поэтому я поплевался пять дней, записал себе в следующий год прохождение курса How to Design Programs на DrRacket и повторное прохождение на Lisp первых 5 дней.

Решение некоторых дней можно почитать:

Полезный опыт был — а именно про упрощение подхода к парсингу входных данных.

Про лайфхаки

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

  • Парсинг:
    • разбить на линии;
    • разбить на блоки (через \n\n);
    • достать все числа из строки (не забыть про знак -).
  • Матрицы (и графы):
    • нахождение расстояния между двумя точками: BFS, DFS, A*;
    • движение вверх-вниз-влево-вправо с учётом границ и стен (#);
    • транспонирование;
    • дебаг (вывод).
  • (Задача со *) скачать свой input, засабмитить ответ по флажку.

Про последнее напишу отдельно — есть хорошая утилита на Rust, называется aoc-cli. Она умеет скачивать пазлы и инпуты в Markdown и TXT, соответственно. Умеет отсылать ответы, а также рисовать приватные лидерборды. Поверх этого использую Makefile, чтобы всё разложить:

.PHONY: help download

download :
	aoc d -i "`date '+%d'`.txt" -p "`date '+%d'`.md"

tmpl:
	cp skeleton.py "`date '+%d'`.clj"

stats :
	aoc p XXXXX

Ещё полезным оказались дополнительные данные для приватных лидербордов с помощью расширения - https://github.com/jeroenheijmans/advent-of-code-charts.

Про глобальное комьюнити

Драма этого года — LLM Cheaters. Первые 12 дней задачи были достаточно простые, чтобы сделать текст задачи + input → OpenAI API → answer → submit. Таким образом в глобальном зачёте висели люди со скоростью в 6 секунд. Плохо ли это? Да, если учесть ежегодный труд Эрика. Что ещё печальнее, никто пока не понимает, как правильно решать эту проблему:

  • отдельный лидерборд — плохо;
  • LLM spoof задачи — плохо;
  • подтверждение задач — плохо;
  • закрыть лидерборд и оставить только приватные — плохо.

Посмотрим, будет ли что-то в следующем году сделано против этого.

Как следствие этой проблемы, задачи после 14-15 дня стали трудночитаемыми. Настолько, что каждые 3 дня появлялись мемы про это.

reading is hard

Если это всё отбросить, то всё как обычно. Каждый день были смешные мемы, каждый день кто-то решал задачку на картриджах Nintendo 64 или программировал уровни в игре “Baba Is You”. Читайте сабреддит, там половина удовольствия от Advent of Code.

Про локальное комьюнити

Хочу здесь написать благодарности всем коллегам, кто участвовал в этом году. Это были не только разработчики, но и DevOps, QA, менеджеры и рекрутеры. Это показатель того, что Advent of Code не про алгоритмы, а про логику и поиск нестандартных вещей в предоставленных данных.


Традиционный топ интересных задач за этот год:

  1. Написать квайн поверх собственного ASM — 17 день;
  2. Починить битовый калькулятор — 24 день;
  3. Симулятор сокобана с широкими ящиками — 15 день.

И спасибо, посмеялся на задаче поиска ёлки с помощью бегающих роботов.