Русский
Русский
English
Статистика
Реклама

Тинькофф

Уязвимость в Тинькофф Инвестиции увеличиваем размер плеча в 100 раз и выводим маржинальные средства на карту

10.04.2021 16:09:58 | Автор: admin

Введение

На этой неделе Тинькофф брокер устранил серию уязвимостей, которые в совокупности позволяли выводить на счёт карты суммы, в десятки раз превышающие размер депозита.

В этой статье поговорим о некоторых лайфхаках и исправленных уязвимостях, а также попытаемся понять, как устроена маржинальная торговля у Тинькофф брокера.

Вся информация предоставлена исключительно в ознакомительных целях и не является инвестиционной рекомендацией. Автор не несёт ответственности за любой возможный вред, причиненный этим материалом. Уязвимости, позволяющие нанести ущерб брокеру, на момент публикации статьи исправлены.

Основные определения

Торговля в лонг это ставка на повышение цены. Когда трейдеры хотят заработать прибыль на росте цены актива, они торгуют в лонг.

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

Маржинальная торговля

Маржинальная торговля торговля с использованием заёмных денег, предоставляемых брокером спекулянту в кредит под залог определённой суммы маржи.

Брокер сам определяет список ликвидных бумаг и ставки риска по ним.
Список ликвидных инструментов у Тинькофф брокера можно посмотреть здесь.

Ставка риска, например, в 20% показывает процент собственных средств в размере позиции.
То есть, если есть сумма 10000, то максимальная сумма с учётом заёмных средств, на которую можно купить текущую бумагу будет 10000 / 20% = 50000.
Также можно сказать, что кредитное плечо по текущей бумаге 1 : 5.

У Тинькофф брокера ставки риска бумаг по лонговым операциям не меньше, чем по шортовым.

Не баг, а фича: увеличиваем размер шорта в два раза

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

На моем депозите около 3200.
Рассмотрим лайфхак на примере акций компании ПИК.

Алгоритм

  1. Покупаем максимальное количество акций в лонг

    До покупкиДо покупки



    Как можно заметить, на собственные средства я могу купить только 3 бумаги. Ставки риска по бумаге 22.56% в лонг и 25.44% в шорт, что соответствует тому, что с учётом заёмных средств можно купить 14 и продать 12 акций.

    После покупкиПосле покупки







    Пока всё правильно: теперь можно продать 14 своих плюс те же 12 заемных акции. В сумме 26 штук.

  2. Выставляем лимитную заявку на продажу на то количество бумаг, которое доступно продать без учёта плеча. В моём случае это 14 акций. Заявку нужно выставить по цене немного выше текущей. В моём случае цена акции 914, я выставил заявку по 915.

    Система неправильно рассчитала размер плеча для продажиСистема неправильно рассчитала размер плеча для продажи

    Как можно заметить, теперь система предлагает выставить заявку ещё на 26 акций.

  3. Выставляем на продажу то количество акций, которое доступно с плечом

    После того, как заявки будут исполнены, наши 14 акций продадутся и 26 бумаг пойдут в шорт.
    На первом скриншоте видно, что изначально система разрешала нам продать в шорт только 12 акций, но после нехитрых манипуляций мы увеличили размер шорта более чем в два раза, и теперь ставка риска по этой бумаге составляет чуть больше 10%

    Если же теперь отменить заявку на продажу 14 акций, то система не разрешит выставить такую заявку снова, нужно проделывать манипуляции заново.

Исправленная уязвимость: как увеличить плечо в десятки раз и зачислить заёмные средства на брокерский счёт

Данный кейс я поймал случайно и потом ещё день пытался воспроизвести. Стало интересно, что будет, если выставить две встречные заявки на покупку и продажу по единой цене. Если следовать логике, я должен купить акцию сам у себя, что странно.

Как работает сейчас?

Выставляем заявку на покупку одной акции по 916,4 и сразу же пытаемся продать себе по той же цене с плечом 13 акций.

Результат вполне ожидаемый: заявка на продажу 13 акций сервер отклонил:

Как работало раньше?

Рассмотрим тот же кейс: выставляем заявку на покупку одной акции, а также заявку на продажу 13 акций.

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

Но до конца торгового дня система считала, что я нахожусь в шорте на 13 бумаг, поэтому она давала мне более большое плечо по этой акции на покупку в лонг, чтобы я мог покрыть эти 13 акций и купить ещё 14 акций на свои деньги (см. первый скрин).

Итого я в сумме мог бы купить не 14, а 27 акций.
Ночью система снимает фейковые -13 акций, но в портфеле остаются все те же настоящие 27 бумаг.

Чтобы было понятно наглядно, покажу некоторые скриншоты, которые остались у меня с тестирований, на момент которого в моем портфеле было 4790$.













Можем видеть, что таким образом получилось купить 2211 акций Vipshop на сумму 62151$. То есть плечо здесь уже более, чем 1 : 12




Размер плеча, в теории, можно было увеличить насколько угодно: если мы выставим заявку на покупку одной акции и по этой же цене продадим ещё 13 акций из примера выше, то система уже будет думать, что у нас -26 акций, соответственно, она даст плечо на покупку этих 26 бумаг плюс 14 акций на собственные средства. Итого уже 40 акций.

С большим плечом дела пошли в гору, мой баланс на спекуляциях удалось увеличить до 6384$.

На скриншоте видно, как с помощью тех же манипуляций получилось увеличить плечо по Амазону почти до 200 000$. Таким образом оно уже стало более чем 1 : 30. Напомню, максимальное плечо у Тинькофф колеблется от 1 : 4 до 1 : 5.

Но вспоминаем, что ночью Тинькофф после пересчёта уберёт такое плечо и вполне вероятно, что на утро нас будет ждать маржин колл.

Маржин колл такое состояние портфеля, при котором баланс становится меньше начальной маржи. При этом, если не пополнить счёт, брокер автоматически начинает продавать бумаги.

Что интересно: Тинькофф прислал маржинколл, хотя позиция прибыльная.

Зачисляем заёмные средства на брокерский счёт

Для того, чтобы заёмные средства зачислились на брокерский счёт, достаточно было самому вызвать маржин колл: очевидно, что никакой маржи не хватит, если, имея 6500$ купить бумаг на 300 000$.

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

Поэтому, сделав -30 фейковых акций Амазона способом выше, я купил 40 акций на сумму более 120 000$. Сразу после покупки сработал маржин колл, и система моментально продала купленные 40 акций. Вместе с этим система сразу же отменила заявку на продажу 30 акций (помним, что до ночи система не знает, что заявка фейковая) и зачислила их мне на счёт. Вместе с 30 акциями на счёт зачислилось и 6 947 118 и стоимость ликвидного портфеля увеличилась до 7 337 776

АналитикаАналитикаПортфельПортфельВывод средствВывод средств


Таким образом, получилось увеличить депозит в 10 раз. Конечно, если вывести эту сумму, то на утро, когда отменятся все сделки, которые не были выведены на биржу, образуется отрицательный баланс на брокерском счёте. Однако, для злоумышленников это не было бы проблемой.

Все сделки, кроме фейковых, были выведены на биржу, что подтверждается в брокерском отчёте.

Заключение

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

Удобная система Тинькофф брокера с выводом средств с брокерского счёта в любое время суток показала, какой побочный эффект может быть достигнут.

Подробнее..

Как создают и поддерживают веб-страницы tinkoff.ru

22.04.2021 14:23:53 | Автор: admin

Всем привет! Меня зовут Сергей Михайлов, в Тинькофф я работаю руководителем интерфейсов: занимаюсь внутренними сервисами, а также отвечаю за дизайн-составляющую Отдела привлечения клиента. Расскажу, как мы быстро собираем страницы с помощью нашего конструктора.

Как это работает сейчас

В Тинькофф около 2000 страниц с разным дизайном и за все эти страницы отвечает отдел привлечения. Он состоит из подразделений, которые отвечают за карточные продукты, депозиты, инвестиции, страхование, мобайл, путешествия и так далее.

Все наши страницы состоят из блоков. Например, на главной странице есть шапка, блоки с главным баннером, с заголовком и с карточкой продуктов.

Макет блока в FigmaМакет блока в Figma

Страницы собираются из блоков в нашем Конструкторе.

Конструктор страницКонструктор страниц

Вот пример такого блока с карточками:

Блок Продуктовые карточкиБлок Продуктовые карточки

В него уже вшита логика с отступами, возможность выключить заголовок или изменить стиль кнопки. Также в блок уже вшита логика растягивания. На примере блок для экрана 1024, а при разрешении 1360 блок растянется. Так у нас работают все блоки.

Конструктор, в котором собираются страницы, это часть нашей CMS. Главное преимущество админки возможность быстро и безрелизно вносить правки на страницу, настраивать аналитику и персонализацию.

Экран собранных страниц и черновиковЭкран собранных страниц и черновиков

Мы тестируем много страниц и иногда для теста создаём новые блоки. Раньше создание нового блока занимало у команды разработки до 2 недель. При этом если если тест не проходит, то от блока отказываемся.

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

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

Десктоп и мобильная версия страницы Тинькофф ПлатинумДесктоп и мобильная версия страницы Тинькофф Платинум

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

Как было раньше

Вернемся на пять лет назад и посмотрим, как у нас был выстроен процесс создания страниц.

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

Тогда придумали систему, назовем ее версия 0. К сожалению, ее скриншоты не сохранились. Вся страница выглядела как один большой блок с формой. Даже такой подход всех устроил, его стали активно использовать и сделали админку с Конструктором версии 1.0.

Конструктор версии 1.0Конструктор версии 1.0

У старой админки еще не было интерфейса, в котором можно было собирать лайв-превью страниц, не было превью блоков, но она уже обладала рядом функций, которые всех устраивали. Функционала становилось все больше, добавилась, например, возможность просматривать историю публикаций и изменений, появилась сложная настройка блоков. Админка превратилась в версию 2.0.

Конструктор версии 2.0.Конструктор версии 2.0.

Дизайнеров у нас в команде конструкторов тогда не было, админку собрали на Material Design. Большим минусом стало то, что из-за сложности системой могли пользоваться только наши контент-менеджеры, которые умели собирать страницы и настраивать сложные блоки. Было бы неплохо сделать нормальную систему, с которой смогли бы работать все пользователи.

Сформулировали цели для новой админки:

  • Уменьшить порог вхождения новых пользователей. Нам было важно, чтобы не только контент-менеджеры могли собирать страницы, но и дизайнеры, заказчики и менеджеры.

  • Сделать понятный процесс сборки страниц, а процесс подготовки пользователя не занимал больше одного дня. Важно, что человек, более или менее знакомый с любым конструктором типа Тильды, мог сразу же собирать страницы и в нашей админке.

  • Сократить время выпуска новых страниц.

Собрали команду из аналитика, дизайнера, контент-менеджера и разработчика. У нас не было привычного флоу, когда дизайнеры и аналитики придумывают интерфейс и отдают разработчикам. Вместо этого мы с самого начала собирались всей командой, проводили дважды в неделю встречи, на которых составляли разные фреймворки, писали сценарии по User Story Mapping. То есть все участники процесса имели слово и вместе собирали админку.

Результатом стала админка версии 3.0.

Конструктор версии 3.0.Конструктор версии 3.0.

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

Проблема с блоками

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

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

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

Какие у этого минусы::

  • Затраты на разработку. Разные команды делают одно и то же.

  • Много одинаковых блоков.

  • Один и тот же блок выглядит по-разному на разных страницах, из-за этого у нас нет консистентности.

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

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

Проблема с процессом сборки страниц

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

Давайте посмотрим на средний состав участников процесса создания страниц:

  • Заказчик человек, которому нужна страница, чаще всего это product owner.

  • Копирайтер пишет текстовый прототип страницы.

  • Дизайнер собирает макет.

  • Разработчики подключаются, когда нужна разработка нового блока.

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

  • Аналитики вносят свои настройки в страницу.

Например, заказчик мог пойти в админку, собрать и опубликовать страницу. Либо он мог отдать задачу на создание текстового прототипа копирайтеру. Копирайтер все это передает контент-менеджеру, а контент-менеджер в админке собирает страницу. Либо заказчик ставит задачу дизайнеру, дизайнер в Figma собирает макет, контент-менеджер по макету из Figma собирает в админке страницу. Таких процессов у нас было очень много, но усредненно процесс выглядел так:

Заказчик ставит задачу копирайтеру, копирайтер отдает текстовый прототип дизайнеру, дизайнер собирает в Figma макет, контент-менеджер по figma-макету собирает в админке страницу, все ребята его согласовывают. Если нужен блок, ставят задачу разработчикам и затем передают аналитику для окончательной настройки, после чего страница запускается.

Минусы такого подхода:

  • Планирование времени участниками. Случались ситуации, когда новый участник процесса узнавал о задаче за неделю до выпуска.

  • Блоки в макетах не соответствуют реальности. Помимо сторибука, где хранятся все наши блоки, эти же блоки есть и в Figma, откуда их берут дизайнеры. Бывало так, что дизайнер собирая страницу может добавить новый элемент в блок, не зная, как он на самом деле работает. Впоследствии, когда контент-менеджер начинал собирать страницу по figma-макетам, ставил блок из админки и понимал, что блок так не работает. В итоге много времени уходило на разбирательство, как поступить в этой ситуации.

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

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

  • Нет понимания зон ответственности и результатов работы.

  • Увеличивается срок выпуска страниц.

Решение

Столкнувшись с вышеописанными проблемами, мы решили:

  • Описать правильный и понятный процесс выпуска страниц, потому что у ребят уже были свои чек-листы, гайды и так далее.

  • Описать зоны ответственности. Собрать все вместе и превратить в нормальный процесс.

  • Дизайнеры собирают страницы в Конструкторе. Перевести всех дизайнеров со сборки страниц в Figma в наш Конструктор, чтобы они понимали, как работают блоки, и из них составляли страницы.

  • Все команды подключаются на старте.

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

Копирайтер может использовать артефакты: он может пойти в сторибук, посмотреть, как работают блоки, если ему так проще составлять прототип; может пойти в Figma либо в Конструктор. Результатом его работы будет текстовый прототип (на самом деле не только текстовый прототип может быть собран в PDF или в Figma, и это будет результатом работы).

Затем этот прототип передается дизайнеру. Дизайнер может по-прежнему использовать сторибук, Figma, гайд по сборке страниц, который у нас есть, но все равно результатом его работы будет ссылка на десктопную и мобильную версии страницы.

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

Как создают новые блоки?

Дизайнер рисует мобильную версию страницы и в процессе понимает, что ему нужен блок (карточка с иконкой), которого у нас еще нет. Согласно процессу, он идет в команду дизайна и говорит: Нам нужен новый блок. Ребята понимают, что это многофункциональный блок, который может понадобиться всем, его можно встраивать и на другие страницы. Тогда задача передается в команду админки, у которой есть два варианта:

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

  2. Нужного блока нет, и похожего тоже нет. Тогда дизайнер идет в Figma и там собирает макет для разработчиков, отрисовывает все состояния и, когда макет собран, он передается в команду админки, которая создает схемы и UI блока. То есть команда админки решает, какие опции должны быть в настройках карточки. Команда блоков верстает и тестирует этот блок.

Макет блока для вёрсткиМакет блока для вёрстки

При разработке блоков используют инструмент Multistory, который разработала команда блоков.

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

MultiStoryMultiStory

Когда блок уже сделан, он попадает в библиотеку блоков нашего Конструктора, где его могут все использовать.

Библиотека блоков в КонструктореБиблиотека блоков в Конструкторе

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

RealStoryRealStory

Вернемся к процессу

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

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

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

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

Процесс в NotionПроцесс в Notion

Что будет дальше?

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

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

Подробнее..

Стратегия выбрать самую нелогичную стратегию, или как мы заняли второе место в Математической регате Тинькофф

14.08.2020 16:23:02 | Автор: admin
Всем привет! Мы студенты четвертого курса Прикладной математики и информатики Питерской Вышки. В июле мы поучаствовали в Математической регате Тинькофф, и в этом посте расскажем о том, что это за соревнование, о том, какова была наша стратегия, и покажем примеры задач.


Картинка с официального сайта Математической регаты

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

Итак, 18 июля пятеро студентов-программистов, которые вошли в состав команды Just4Fun, собрались участвовать в первом туре соревнования. С нами соперничала 391 команда, в каждой было по 35 человек. Всего 1628 участников из 131 города мира.

Правила первого тура


Первый тур длился два с половиной часа. Было предложено 25 задач, разбитых по 5 уровням сложности и 5 темам: комбинаторика, числовые задачи, алгебра, теория вероятностей, геометрия.

Начальный капитал команды 1000 очков. Каждая задача стоит от 100 до 500 очков: чем выше стоимость, тем сложнее задача. Если команда покупает задачу, ее стоимость вычитается из начального капитала (при этом нельзя уходить в минус). За верное решение с первой попытки начисляется $inline$2x$inline$ от стоимости задачи, со второй $inline$1.5x$inline$, с третьей $inline$1x$inline$.

Каждая задача имеет ответ в виде числа, которое нужно ввести в соответствующее поле на сайте. Покупать и сдавать задачи может только капитан.

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



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

Одновременно разрешалось открыть не более трех задач серьезное ограничение для команд из пяти человек.

Первый тур


Так как все участники нашей команды находились в разных уголках России от Уфы до Санкт-Петербурга, у нас, к сожалению, не получилось собраться вживую ни на один из туров. Мы создали несколько комнат в видеоконференции и обсуждали решения в них.

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

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

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



Отдельно хочется остановиться на процессе решения задач. Все-таки мы скорее программисты, чем математики, и во время соревнования мы активно пользовались компьютером (это было разрешено правилами). Более половины задач мы решили при помощи Wolfram, Python и, неожиданно, C++ (для действительно быстрых переборов). С одной стороны, это не математично, но с другой позволило решить задачи в максимально короткие сроки.

Правила второго тура


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



Каждой задаче соответствовала доминошка (0:1, 0:2, ..., 6:6 всего 27 штук). В первые 2,5 часа команды решали задачи и собирали себе снаряды в виде доминошек.

Затем состоялась битва. Она продолжалась три раунда, в каждом из которых нужно было выбрать 7 доминошек по одной на каждую команду соперников и определить, какое из чисел доминошки будет соответствовать атаке, а какое защите. Затем команды отправляли организаторам ответы на задачи, соответствующие доминошкам. Если ответ неправильный, то и атака, и защита становились равны нулю. В течение боя можно было дорешивать задачи, ответ на которые еще не был найден.

Допустим, наша команда поставила доминошку [2:5] против команды N и решила, что число 5 будет соответствовать атаке, а 2 защите. Команда N поставила против нас доминошку с защитой 3 и атакой 4. Тогда наша команда получит урон, равный 2 $inline$(4-2=2)$inline$, и команда N тоже $inline$(5-3=2)$inline$. Каждое из этих чисел вычитается из очков команды, которая защищалась, и прибавляется к очкам нападающей команды. Побеждает команда с наибольшим количеством очков по итогам трех раундов.

Второй тур


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

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

По результатам финального тура мы заняли второе место, сильно отстав от первой команды и прилично обогнав третью. У нас 25 очков, у первой 55 и у третьей 14.

Общие впечатления


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

Задачки с турнира


Задача из первого тура


Тема: Вероятность.
Стоимость: 500.
У Вани есть два доллара. Он подбрасывает монетку. Если выпадает орел, Ваня получает 2 доллара; если решка, он теряет половину своих денег. Если решка выпала два раза подряд, то игра заканчивается, при этом в последнем раунде Ваня не теряет деньги. Найти матожидание количества денег у Вани после окончания игры.

Решение:
Найдем количество последовательностей длины $inline$n$inline$ из орлов и решек с фиксированным последним элементом, в которых нет двух решек, идущих подряд.

Число последовательностей длины $inline$n$inline$ с последней решкой обозначим как $inline$h(n)$inline$, с последним орлом $inline$F(n)$inline$.
$inline$h(n) = F(n 1)$inline$ (нельзя, чтобы предпоследний элемент тоже был решкой).
$inline$F(n) = F(n 1) + h(n - 1) = F(n - 1) + F(n - 2)$inline$ (предпоследний элемент любой)

Получили последовательность Фибоначчи c начальными данными $inline$F(0) = F(1) = 1$inline$.

Допустим, Ваня сделал $inline$n$inline$ бросков и игра не закончилась. Зафиксируем последнюю выпавшую сторону монетки (орел или решка) и обозначим сумму Ваниных выигрышей по всем последовательностям, удовлетворяющим условиям (последняя сторона зафиксирована и нет двух решек подряд), как $inline$f(n)$inline$ (последний орел) и $inline$g(n)$inline$ (последняя решка).

Осталось написать рекуррентные соотношения на $inline$f$inline$ и $inline$g$inline$.

Для начала разберемся с $inline$g$inline$. Заметим, что если последовательность оканчивается на решку, то предпоследним должен идти орел (т. к. двух последовательных решек быть не может), следовательно, $inline$g(n) = \frac{f(n 1)}{2}$inline$, при выпадении решки Ванина сумма уменьшилась в два раза.

Теперь с $inline$f$inline$. В этом варианте предпоследним может быть как орел, так и решка. По условию, выпадения орла просто добавляет 2 к сумме,т. е. $inline$f(n) = f(n 1) + g(n - 1) + 2F(n)$inline$ (вот для этого $inline$F$inline$ были посчитаны заранее).

Все промежуточные вычисления сделаны, осталось только посчитать ответ.

Игра заканчивается тогда, когда Ваня выбрасывает вторую решку подряд. Заметим, что вероятность в итоге получить конкретную последовательность длины $inline$n > 1$inline$ (с двумя решками в конце) это $inline$\frac{1}{2^n}$inline$ (случайно равновероятно выбираем каждый элемент). Тогда осталось найти $inline$\sum\limits_{i = 2}^{+\infty} \frac{g(i 1)}{2^i} = \frac{f(i - 2)}{2^{i + 1}}$inline$.

Это некоторое техническое упражнение, далее идут соответствующие выкладки. Опустим корректность перестановки слагаемых в суммах.

Сперва вспомогательная сумма:

$$display$$S_1 = \sum_{n = 1}^{\infty} \frac{F(n)}{2^n} = F(1) + \sum_{n=2}^{\infty} \frac {F(n 1) + F(n - 2)} {2 ^ n} = \\ = F(1) + \frac{3}{4} \sum_{n = 1}^{\infty} \frac{F(n)}{2 ^ n} = F(1) + \frac{3}{4} S_1 \implies S_1 = 4$$display$$



И аналогичные действия уже для нашей рекурренты:

$$display$$S_2 = \sum \frac{f(n)}{ 2 ^ {n + 3}} = \sum \frac {F(n)} {2 ^ {n + 2}} + \sum \frac {f(n 1) + f(n - 2) / 2} {2 ^ {n + 3}} = \\ = S_1 / 4 + \frac{5}{8} S_2 \implies S_2 = \frac{8}{3}$$display$$



Ответ: $inline$\frac{8}{3}$inline$

Задача из второго тура


Соответствовала доминошке [2:3].

Больше всего запомнилась одна простая задачка из второго тура. В ней требовалось посчитать, сколько раз нужно проделать операцию $inline$DF$inline$ с кубиком Рубика, чтобы он вернулся в исходное состояние (операция $inline$DF$inline$: сначала по часовой стрелке повернуть фронтальную часть, затем по часовой стрелке повернуть нижнюю часть).

Математическое решение:
Заметим, что повороты кубика рубика можно описать с помощью некоторой подгруппы симметрической группы S_48.

Обозначим поворот фронтальной части как $inline$F$inline$, а нижней как $inline$D$inline$. В таких обозначениях мы с кубиком сначала совершаем операцию $inline$F$inline$, а затем операцию $inline$D$inline$. Таким образом, если кубик находился в состоянии $inline$x$inline$, то он после одного хода перейдет в состояние $inline$DFx$inline$. Мы хотим найти минимальное количество шагов, которое нужно, чтобы перевести кубик в исходное состояние. Т. е. нужно посчитать порядок элемента $inline$DF$inline$. И $inline$D$inline$, и $inline$F$inline$ описываются перемножением перестановок. Давайте перемножим их все и обозначим результат как некоторую перестановку p. Чтобы посчитать ее порядок, достаточно найти НОК длин ее циклов.

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

Ответ: 105.
Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru