Opener 2020: Самый сок
Введение
На протяжении всего апреля мы с командой после учёбы и работы решали увлекательные задачи в рамках конкурса Opener от компании Itransition. Вместе с конкурсом закончился наш лучший месяц на самоизоляции. Теперь, отдохнув, я готов спокойно поделиться этим опытом с вами.
Opener — это ежегодный открытый интеллектуальный конкурс для студентов, аспирантов и магистрантов Республики Беларусь (по крайней мере на призы претендовать могут только они), а участвовать — все, кто захочет. Данный конкурс проходит уже 8 лет. В этом году был добавлен командный зачёт со своими дополнительными задачами.
Призовой фонд конкурса составил 12 Apple Ipad Pro для личного и $4000 для командного зачётов. Наша команда, состоящая из Артура (petuhovskiy), Вячеслава, Игоря (lodthe), Кирилла и меня выиграла 4 Ipad«a.
Мы добрались практически до самого конца конкурса, и я бы хотел показать вам, какие задачи показались нам самыми интересными. Надеюсь, что прочитав ход решения, посмотрев на командную работу в Google таблицах, увидев скриншоты, вы осознаете уровень проработки задач и не сможете не сказать: «Вау!»
В конце статьи вас ждёт задача — попробуйте её решить!
Основная часть
Как всё начиналось
Стоит заметить, что я уже принимал участие в данном конкурсе в 2019 году. Узнал о нём я совершенно случайно и решил первых задач 10 на парах. Спустя год мне на почту пришло письмо-приглашение. Теперь я знал чего ожидать и меня это не заинтересовало, ведь конкурс — самый настоящий марафон на месяц. Я просто поделился письмом и ссылкой на регистрацию с подписчиками своего канала в Telegram.
Спустя несколько дней мой друг Слава пересылает в общий с Игорем чат данный пост и спрашивает: «Что по этому?». Игорь интересуется про род задач, которые там будут, а я ему подробно отвечаю. Слово за слово, приходим к тому, что никто не против порешать чего-нибудь просто так, а зарегистрировавшись, мы точно ничего не потеряем.
Команды от трёх человек, максимум пять. Мы поставили в чат себе уведомление на день начала конкурса и успешно про всё забыли. В последний день регистрации хотелось укомплектовать команду полностью, но на примете никого не было. Игорь написал своим знакомым с предложением поучаствовать, не надеясь на положительный ответ, однако, именно так к команде присоединился Артур и Кирилл. Примечательно то, что последний участник зарегистрировался за минуту до окончания формирования команд.
Артур, Игорь, Кирилл и Слава учатся в Высшей Школе Экономики, в школьные годы увлекались спортивным программированием в Республике Беларусь.
Организационные моменты
Официальная группа конкурса находится в ВК. Именно там, в обсуждениях, можно было попросить помощи от организаторов, если совсем был ступор. Подсказки были совершенно разными. Это и музыкальные отрывки, и четверостишия, и просто какие-то намёки, отсылки. Все конкретные и важные подсказки переносились в отдельную тему, а на стене мелькали полезные ссылки. Только погрузившись в общение с другими участниками и организаторами в этой группе, можно было получить максимальное количество полезной информации. Этим я и занимался, сидя с фейка и максимально прикалываясь. Я рофлил, добавляя креатива в сообщения, команда рофлила с моих сообщений и сама их иногда не понимала, организаторы награждали меня подсказками. Родились мемные фразы, которые мы употребляем до сих пор. Вот некоторые из них:
- «Опять таблетки забыли принять?»
- «Последовательность бык»
- «Где???»
- «Вы вопрос задайте»
- «Подумать, нет?»
Telegram бот, координирование команды
В нашей команде уже давно все перешли исключительно на Telegram, следовательно, в первые же дни Артуром был написал бот, который дублирует все сообщения участников, а также подсказки из обновляемых организаторами сообщений в приватный канал.
Мало того, что это очень удобно (ведь мы получали уведомления и были в курсе всего), так ещё и получилась система логирования всех исправлений как участников, так и организаторов. Это помогало получить дополнительную информацию, так как организаторы затирали в вопросах участников слова, которые могли хоть как-то намекнуть куда копать. Подсказки вообще могли молча обновляться, а бот всегда держал нас в курсе.
Общение команды шло через чат. К тому времени я написал бота для интеграции Zoom в Telegram, он был на хайпе и мы им активно пользовались, но где-то в середине месяца они опять вернули своё ограничение на 40 минут конференции и мы перешли в Discord, так как любили засесть ночью на часика четыре.
Все записи, касающиеся задач, были представлены отдельными страницами в таблице Notion. Это было удобно: когда кто-то уходил спать, утром он смотрел, что другие решили ночью. Так же без этих заметок не получилось бы написать эту статью.
Задачи
Как я уже упомянул во введении, задачи делятся на два типа: командные и личные. Одновременно можно было решать задачи обоих типов, но командные задачи были заблокированы для просмотра, пока не решены предыдущие из личного или командного зачётов. Удивительно то, что организаторы не запрещали, а даже открыто заявляли, что задачи личного зачёта можно решать вместе с командой (при её наличии, конечно же). Ими было введено ограничение, которое не позволяло забрать больше четырёх айпадов на одну команду. Мы посчитали, что решать всем вместе будет рациональнее. Так и поступили.
Конечно, выходило и так, что мы застревали на командных задачах, но продолжали решать их из личного зачёта. Чаще всего выходило, что они были более интерактивными и многоэтапными. Все задачи, описанные ниже, с выездом на локацию в Минске, как раз и являются командными. Олимпиадникам больше понравились личные задачи, тогда как я просто тащился от командных. На протяжении всего конкурса я ждал реквизит, про который говорилось в правилах конкурса, но эти задачи были заменены на примитивные из-за пандемии, которые решались за несколько минут. Поняли мы это благодаря открытой корневой папки CloudFront«a, получив все приложения задач ещё в самом начале конкурса. Так же это дало нам понимание о количестве задач, что предстоит решить. После конкурса я узнал, что никто не справился с абсолютно всеми задачами, а именно на последней и нужен был реквизит.
Ниже я описываю ход решения четырёх интересных задач, которые состоят только из изображений без дополнительного текстового сопровождения. А в конце статьи вас ждёт увлекательная и несложная задачка, на которую мы потратили около суток, несмотря на то, что Python является моим основным языком. При должных знаниях, решение придумывается сразу. По крайней мере понятно, что и как будет, но вот до конца довести сложнее.
Задача с 104 гифками
Исходными данными к задаче является архив, содержащий в себе 104 GIF файла с разными названиями. Название каждого файла имеет префикс — part_. Название архива — by8_128×128 px_2layers.zip. Сразу замечаем, что это никакие не гифки, а просто изображения. Перегоняем в другой формат:
Самое сложное в этой задаче это понять условие. Исходя из названия файла понимаем, что имеем делом с изображениями размера 128×128, которые имеют по 2 слоя, то есть картинка разбита на две непересекающиеся по чёрным пикселям, которые при объединении дают исходное изображение, как показано на иллюстрации:
Выходит, изображение разбито на 8 (by8 из имени файла) частей. Следовательно, картинка разбита на 4 квадрата одного размера (8 / 2). Доказывается это тем, что каждый файл из архива имеет размер 64×64. Так как дано 104 изображения, а каждый квадрат собирается из 8 изображений, всего есть 13 (104 / 8) квадратов 128×128. Объединяем слои с помощью скрипта на Python с использованием PIL.
Отказываемся от идеи пытаться склеить это автоматически и рейдим всей командой Google таблицу. Слава загружает все эти изображения, а мы их распределениям на 4 группы в зависимости от типа угла, которому соответствует картинка (это определяем по наличию рамки). Далее пытаемся объединить эти углы, чтобы получилось что-то читабельное.
Подсказка: «Если вы дошли до слов, то нужно найти одинокие буквы по столбикам»
Из этой подсказки понимаем, что в каждом квадрате из каждого столбца надо выписать ту букву, которая повторяемся в этом столбце. Для каждого квадрата получается 5 символов, а так как квадратов 13, получаем 13 таких строк.
Пробуем поменять местами эти строки так, чтобы получилась читабельная фраза:
Получаем: «самое малое положительное с количеством разных делителей более десяти млрд», находим в интернете замечательную табличку:
Собираем число, вставляем в любимый Python и получаем ответ!
2**9 * 3**5 * 5**3 * 7**2 * 11**2 * 13**2 * 17**2 * 19**1 * 23**1 * 29**1 * 31**1 * 37**1 * 41**1 * 43**1 * 47**1 * 53**1 * 59**1 * 61**1 * 67 * 71 * 73 * 79 * 83 * 89 * 97 * 101
Ответ: 2054221614063184107682218077003539824552559296000
Задача с девочками
Подсказка: «Цвета какие-то ненатуральные, явно отфотошопил девчонок кто-то»
Отличная подсказка, с неё мы и начали решать эту задачу, сами незаметив. Я начал со стеганографии, усердно пытаясь достать хоть что-то, но все попытки были тщетны. Была идея поиграться с ползунками в фотошопе, как-то выровнять баланс цветов, приблизить к натуральным, но нет. Заметили, конечно, и пятна из разных цветов. Выделили их более яркими — не помогло.
Спустя некоторое время получаем подсказку в качестве кода на Ruby:
def h(a);
a.reduce(Hash.new(0)) {|h,e|h[e]+=1;h};
end
Наш лучик надежды. Разбираемся в коде, понимаем, что это ничто иное, как функция, которая возвращает словарь с количеством вхождений чисел в массиве. Недолго думая, понимаем — в картинке считать нечего, кроме как пиксели, но продолжаем сидеть без малейшего понятия как это делать правильно.
Подсказка: «А что это за такое? А такое есть у картинки? Три? А имя файла?»
Получив эти вопросы после кода выше, стараемся дать на них вразумительные ответы. Под тем, что это за такое, подразумеваем количественную характеристику. У картинки, как мы и думали, есть пиксели, а три — это три канала: red, green, blue. На имена файлов мы всегда обращали внимание, в данной задаче оно «λφz.png», однако это нам абсолютно ничего не дало, кроме как трёх букв. Только потом мы осознали, что это отсылка к координатам… Когда ты в тупике — иди в Google. Слава так и поступил: начал вбивать поисковые запросы наподобие: «количественная характеристика» и как-то связывать это с изображением. Так он пришёл на сайт с генератором гистограммы по изображению. Загрузив наше исходное изображение он заметил интересную картину и поделился сразу с нами:
Это правда выглядит очень необычно. Вооружившись Python с PIL заводим три словаря под каждый канал, проходимся по каждому пикселю изображения, получая RGB и в каждый словарь инкрементим значение, ключ которого — наш канал. Например, для словаря red вы возьмём от RGB R за ключ, а в значение добавим +1. Прям как тот код, что дали нам на Ruby. Так проделаем с остальными двумя каналами и — «О чудо!, Вы только взгляните на это!»
Практически везде идеальная картина, количество цветов в каждом канале совпадает!
Весь полученный файл доступен тут. Меньше, чем в пяти местах, значения отличались, но мы посчитали, что, возможно, у авторов задачи не получилось сделать идеальное совпадение. Ведь то, что мы увидели, уже величие! Не останавливаясь, видим отсутствие цветов, ведь не все идут по порядку. А почему бы не выписать: какие есть, а каких нет? Так и делаем, дописав к нашему прошлому коду цикл! Для трёх каналов получаем три бинарные строки длиной в 255, где цвет отсутствует — 0, а где есть — 1:
Red0000111100000000000000000000000000001111000000001111000011110000111111111111111100001111000011111111000011110000111111110000000000001111111111110000000000001111000000000000000011111111000000001111000011111111000000001111000011110000000011110000111111110000
Green0000111100000000000000000000000000000000111111111111000011111111111100000000111100001111000011110000111100001111000011110000111100000000000011111111111100001111000011111111000011110000000000001111111100000000000011111111000011110000000011110000000011111111
Blue0000111100000000000000000000000000001111111100001111111100000000000011111111000000000000000000000000000000000000000011110000000000000000000011111111000000000000111100000000111100000000111111110000111111111111000011110000000011110000111111111111111100000000
Выглядит страшно и непонятно, но вы ведь тоже видите, что везде количество единиц кратно 4? А ведь с нулями такая же картина — сжимаем!
Red0100000001001010111101011010110001110001000011001011001010010110
Green0100000000111011100101010101010100011101011010001100011010010011
Blue0100000001101100011000000000010000011000100100110111010010111100
Вот… Уже и не так страшно, легко влезает в поле зрения. Нужно думать дальше, чем это может быть, но тут олимпиадное предположение играет нам на руку: «А что, если это double?». И правда, а ведь что «если»? Пробуем перевести двоичные последовательности в тип double (делаем reinterpret_cast в даблы), получаем следующие значения:
53.919325
27.58333
227.0005
Посещая уроки географии в школе, понимаем, что наше первое число: плюс-минус наша широта, а в целом, три числа как раз и обозначают координаты. Тут и должна была сыграть подсказка в имени файла, но мы уже пулей летим в Google карты:
Получилось! Координаты соответствуют углу офиса компании-организатора конкурса. Понимаем, что скорее всего придется туда приехать. Первый этап прошли.
Мы не торопимся на локацию, так как в тот момент участник другой команды активно написывал в обсуждение, что он на месте, спрашивает у охранников, которые ничего не знают, бродит, ходит и не понимает что надо найти. Спустя некоторое время мы активно начали подыгрывать ему в общении с организаторами и делать вид, что тоже пришли туда:
— Жарко стоять уже:(
— Только что прошел кашляющий человек (он был без маски
Ответ организаторов не заставил долго ждать:
— Там видео секунд на 30, не больше
— Никуда заходить не нужно, можно приехать/прийти одному и повтыкать. Там три координаты, три, Карл, не две (как и две первые, третья отсчитывается от некого выбранного «начала», а не от подошв кед). Не ходите, не спрашивайте, нужно рассмотреть со стороны.
Эти ответы перевернули всё. Проверяем высоту над уровнем моря, на которой находится офис, это где-то ~200. Предполагаем, что координата 227 плюс-минус может быть на крыше офиса. В это же время один из нас находился неподалёку — он и отправился на локацию. Достигнув угла здания, как на Google карте, поднимаем глаза. Анимированный логотип — это не то, что на аватарке в группе у компании. Вместо логотипа — тетрис:
Для уточнения, то ли это, что нам надо, задаём следующий вопрос: «Фигурки, падающие с небес, связаны с блоками, которые закрывают девочек?» Во-первых: получаем положительный ответ, а во-вторых: редактирование нашего вопроса со стороны организаторов на «о-ла-ла, падающие с тру-ла-ла, связаны с блоками, которые закрывают облади-облада?».
Мы на правильном пути. Дело Google таблиц! Покадрово разбираем отснятый материал, восстанавливаем блоки, цвета, записываем порядок появления блоков на видео. За счёт равной задержки между появлением фигур узнаём о наличии других, внутри отсутствующей части логотипа.
Учитывая текущий пазл, понимаем, что это пентамино, т.е. все фигуры состоят из пяти отдельных квадратов (пикселей). Находим буквенное обозначение данных фигур, пытаемся, опираясь на цвета, заполнить клетки на исходном изображении с девочками — ничего не выходит. От организаторов приходят подсказки с количеством уникальных фигур в пентамино — решаем задачку, заполнив весь прямоугольник уникальными блоками:
В очередной раз пытаемся вписать буквы в клетки, уже сомневаемся в правильности данного подхода, пытаемся найти что-то ещё. По цветам очень сложно понять: что куда, поэтому, во-первых: улучшаем нашу палитру в таблице, получив фотографию лучшего качества;, а во-вторых: начинаем выписывать множество подходящих букв под каждую клетку.
Я получаю 3 читабельных слова из 4, но считаю это за совпадение, ухожу делать перестановку букв по словарю, с учётом тех, в которых был уверен по цветам. Таким цветом являлся синий и обозначал букву «Т». Засылаю огромную пачку различных комбинаций в чатик. Почитав их все вместе, забываем про эту идею. Спустя некоторое время я со Славой возвращаюсь к расстановке букв, имея справа на экране свой первый вариант. Присоединяется Артур, который чутка отсутствовал на задаче, разбирается в том, чем мы тут занимаемся. Спустя некоторое время Артур обращает внимание на мой прошлый вариант, где найденные три слова выделены зелёным цветом, а под последним написано слово «input». Это то слово, что очень хотелось собрать, но не сходилось по одной букве. Артур просто читает строку полностью: «Input fifty pi int».
Умножаем число Пи на 50 в целочисленном типе, отсылаем в систему… Получаем положительный вердикт: задача длинною в дней 5 решена!
Задача с ответами и вопросами
Подсказка: «Где же поблизости найти вопросы, ответы на которые нужно вписать в матрицы?»
Вспомним тот факт, что всё общение с организаторами проходит через обсуждения в группе ВК, следовательно, сейчас мы в обсуждениях, а максимальное близкое к нам место с вопросами — или другая страница текущей темы, или другой раздел.
Так как первое является невозможным, то мы поднимаемся на уровень выше и смотрим на список обсуждений. Их не много, всего 4: обсуждение задач, подсказки, обсуждение конкурса, правила. Первые два откидываем сразу, к остальным присматриваемся. Зайдя в правила конкурса, видим вторым сообщением секцию с часто задаваемыми вопросами. Вот они, вопросы! Ответы у нас даны в задаче (подписи к матрицам) — по ключевым словам ищем их и выписываем!
Подсказка: «Зеленые — начало укладки»
Отлично, выходит что-то надо куда-то уложить. «Куда» — это очевидно, так как знаем начало. Под «Что», — принимаем вопросы, которые нашли на первом шаге. Проверим свою догадку: все матрицы 10×10 (что даёт нам 100 клеток для символов). Посмотрим на длину строк ответов: все они больше 100. Попробуем откинуть знаки пунктуации и символ пробела, посчитаем просто количество букв — у всех вопросов по 100 букв!
Остаётся последний шаг: узнать как укладывать. Там уже посмотрим на буквы в жёлтых клетках и может, что понятнее станет. Ломаем голову, от меня проскальзывает предложение: «Давайте рассматривать, как граф», которое успешно игнорируется всеми остальными. Через некоторое время предлагается загуглить по изображению: вырезаем первую матрицу, скармливаем Google — ничего, идём в Яндекс — что-то есть!
Вчитываемся в найденное условие, понимаем, что необходимо найти гамильтонов цикл, даже не пытаемся сделать это руками, думаем об автоматизации, прикидываем сложность и … сложно. Олимпиадники говорят, что решать задачу самым наивным перебором смысла нет. А использовать оптимизации лень, но есть надежда на то, что можно решить задачу проще. Для подтверждения того, что наивное решение будет отрабатывать слишком долго, пишем его. Убеждаемся, что работает долго.
Идём в Google, находим программу для решения оригинальной головоломки поиска цикла, а не путей, как в статье, которую мы нашли. Программа оказалась только для Windows, ни у кого её не оказалось под рукой, пошли поднимать виртуалку. Подняли, запустили, программа моментально находила решения.
Решение представляет собой обход поля:
Заходим всей командой в Google таблицу, накладываем скриншоты полученных решений на наши, перенесённые с задания, матрицы. В инструментах для разработчиков браузера задаём элементам с скриншотами прозрачность и заполняем матрицы буквами из ранее найденных вопросов.
Через некоторое время коллективного труда, получаем 8 матриц, так как у каждого решения есть два направления, и мы без понятия — какое правильное. Во время этого процесса мы были в зуме. У каждого двигаться по матрице получалось с разной скоростью и разным количеством опечаток, было очень весело. Осталось дело за малым — составляем слова из букв, которые находятся в желтых клетках.
Получив с каждой матрицы по кусочку фразы, читаем: «Самое большое белла в лонге джавы минус сто». Понимаем, что от нас хотят самое большое число Белла, которое помещается в тип Long из Java.
Это в точности 4638590332229999253 и является ответом к задаче.
Задача с монетой
Самая сложная для меня задача для объяснения. Не представляю просто, как можно передать все те дней 10, что мы над ней сидели. Поэтому, давайте считать краткость и отсутствие подробностей — за фишку. В задании, как и в прошлых, у нас только изображение:
В какие дебри мы только не зашли без подсказок. Это — и деноминация в Беларуси, и состав монеты, и её размеры. Не оставили без внимания и словое opener с опечаткой. Я сразу же перевёл орёл и решка на английский несколькими способами, гуглил, пришёл к компании Open Retail, которая в 2009 году что-то там, а владеет она торговой сетью монетка. Смотрели на конкурсы прошлых лет. В общем дошли до тупика и пошли заваливать вопросами организаторов:
— В 19 надо учитывать номинал?
— да, и слово там — не опечатка— монета или монета Республики Беларусь?
— вопрос непонятен, скорее это не важно (слово «монета» не важно), важно то, что нарисовано— В 19ой есть что-то связанное с английской розницей?
— только на втором этапе, на первом важны только буквы и числа на монетах— можно еще что-нибудь по 19, цифры буквы деньги, ничего не складывается?
— деньги — на втором этапе, на первом нужно соотнести числа и последовательности букв— Как в 19ой понять, что первый «этап» пройден? Должна получиться какая-то фраза? Если должны получиться числа, то как можно понять, что они правильные?
— получится место. Нет, не числа должны получиться. Но этот в Минске, так можно понять, что он правильный.— мафия причастна к 19 задаче или просто тихий?
— вероятно, ни первое, ни второе. Для определения места там числа и последовательности букв.— А можете как-то направить? А то вообще непонятно, как подходить к 19-ой задаче (ещё в первом этапе). Что делать с этими буквами и цифрами)
— число связано с тем, как написано слово. на левой — аналогичная связь
Получив просто тонну различной информации, стало понятно, что есть некая функция, которая принимает в себя строку и число и как-то переставляет в ней буквы. Реализовываем различные сдвиги, вводим слово openre и выводим каждую итерацию в консоль, смотрим примерно на 20 позицию, потому что без понятия что там по ±1. При определённом алгоритме встречаем opener на 21 позиции, а это 20 если с нуля.
Меняем входное значение на то, что находится на другой стороне монеты — u9pgezed6. Повторяем тоже самое, но уже знаем про +1 и смотрим на 2010 итерацию, вместо 2009 — приходим к u9edez6gp (файл с сгенерированными строками).
Из подсказок знаем, что конец первого этапа — место. Ищем способы задать точное место строкой, натыкаемся на Plus коды Google, но формат не тот. Ищем альтернативные варианты и находим — GeoHash! Для эксперимента вбиваем на этом сайте город Минск и сравниваем две строки. Похожи! Вводим нашу полученную строку с монет:
Место выглядит абы-где, как будто не туда, куда надо, указано, но я был там летом (проходил тестирование) и знаю, что там есть офис Itransition. Это точно то, что нам надо! По приходу на место бросается эта красота:
Первым делом я гуглю картинку, выхожу на ask девушки, потом на её instagram, интересуюсь в директе, откуда у неё эта фотография, как она с ней связана и прочее (объяснив ситуацию с конкурсом, конечно же). Оказывается, что девушка просто неподалеку отдыхала в каком-то заведении, а на улице была эта стена, которую она сфотографировала и опубликовала.
Присмотревшись к стене, находим ссылки на авторов — ими оказались две девушки. Одна ссылка на Instagram профиль — там, как раз, процесс создания этого шедевра. Вторая ссылка — пользователь Telegram. Перейдя по второй, похвалив за проделанную работу (правда ведь красиво), спрашиваю: «Связано ли это с конкурсом как-то?», на что получаю положительный ответ: «Да ребята мы рисовали по строгому задания там нужно найти закономерность в этих чудовищных больше ничего сказать не могу. Нас не трогать».
Продолжаем залипать на стену, рассматривать монстров. Думаю, что-то в сторону конечностей. Не помню, кто именно, но точно не я, замечает, что это матрица 8×8, где каждый элемент — монстр. Теперь и скобки [] в условии задачи выглядят для нас не как целая часть числа, а как обозначение матрицы.
Возвращаемся к переводу орёл и решка на английский язык (к этому подстегнула музыкальная подсказка с песней Лепса «Уходи по-английски»), закидываю идею посчитать heads и tails каждого монстра в отдельных матрицах. Долго сопротивляемся, но решаем попробовать. Сопротивляемся по той причине, что чёрт ногу сломит тут понять — что хвост, а что голова и сколько их. Матрицы перемножаем:
Замечаем подозрительное количество четвёрок (да и в знаменателе она же). Игорь заменяет все ненулевые элементы на 4, так как могли ошибиться при подсчёте и получает следующую картину:
Игорь ничего не разглядел на этой матрице и начал циклически сдвигать вправо — авось, что проявится. Отчаявшись, скинул в чатик:
Заключение
Всего было полсотни задач и рассказывать красочно о каждой, в рамках одной статьи, просто нецелесообразно. Мы отобрали те, где есть, что показать и рассказать. К сожалению, сюда не вошли алгоритмические задачи, коих было достаточное количество.
Чего мы только не вытворяли, чтобы достигнуть решения. Писали код на двух языках в одном файле, который будет без проблем выполняться в разных компиляторах. Коллизии MD5 хэш трёх разных файлов с кодом, игрались с RFC 2898 + AES, изучили флаги стран по цветам, выучили Ruby, пописали на asme, подеобфусцировали кучу раз код и многое-многое другое…
Это был незабываемый месяц! Рекомендуем принять участие в следующем году! А вот и обещанная задача про Python (без решения):
Написать скрипт на языке Python 3, который: состоит не более чем из 4000 латинских букв и круглых или угловых скобок; при запуске печатает на консоль переданные в скрипт аргументы в обратном порядке (каждый на отдельной строке).
Дополню, что пробелы использовать запрещено. Исключительно то, что написано в условии. Жду вас в комментариях!
Спасибо, что дочитали аж до сюда! Всем МурмурХеша.