Конкурс по программированию: Торговля

Компания Hola вновь объявляет конкурс по программированию! Победителей ожидают призы:

  1. Первое место: 3000 USD.
  2. Второе место: 2000 USD.
  3. Третье место: 1000 USD.
  4. Жюри может присудить по своему усмотрению специальный приз в 400 USD.
  5. Если Вы отправите кому-то ссылку на этот конкурс, поставив наш адрес в CC, и этот человек займёт призовое место, Вы получите половину суммы приза (разумеется, не в ущерб награде победителя). За одного победителя такую награду может получить только один человек — тот, кто отправил ссылку первым.
Авторы интересных решений будут приглашены на собеседования.

UPDATE: Канал в Telegram для обсуждения конкурса: @hola_challenge_haggling

Правила

Условия конкурса на английском языке размещены на GitHub. Ниже — перевод на русский язык.
  • Отправляйте решения с помощью этой формы. По электронной почте решения не принимаются.
  • Решения принимаются до 20 июля 2018, 23:59:59 UTC.
  • Предварительные результаты будут опубликованы 27 июля 2018, а окончательное объявление победителей — 3 августа 2018.
  • Можно отправлять решения многократно, но от каждого участника будет рассмотрено только самое последнее решение, отправленное до окончания срока приёма работ.
  • Для тестирования мы будем использовать Node.js v10.4.1 (текущая версия на момент публикации). Можно использовать любые возможности языка, поддерживаемые интерпретатором в стандартной конфигурации.
  • Весь код решения должен находиться в единственном файле на JS.
  • Решение должно быть на JS. Если Вы предпочитаете CoffeeScript или подобные языки, необходимо оттранслировать решение в JS перед отправкой.
  • Если Ваш JS-файл — продукт генерации, минификации и/или компиляции с других языков вроде CoffeeScript, пожалуйста, приложите архив с исходниками, а также, желательно, описанием подхода. Содержимое этого архива будет опубликовано, но мы не будем его тестировать.
  • Нельзя загружать никаких модулей, даже тех, что входят в стандартный комплект Node.js.
  • Один участник может использовать для отправки решения только один адрес электронной почты. Отправка множества решений, находящихся в «сговоре», с разных адресов запрещена; все решения, участвующие в такой схеме, будут дисквалифицированы.
  • Нам нужно знать Ваше полное имя, но если Вы хотите, мы опубликуем вместо него псевдоним. Мы сохраним Ваш адрес электронной почты в тайне.
  • Нынешние и бывшие сотрудники Hola и их ближайшие родственники могут принимать участие лишь вне конкурса, не претендуя на призы.
  • Задавайте вопросы по условию задачи в комментариях к этой публикации или по электронной почте.

Торговля

Допустим, у нас есть книга, две шляпы и три мяча. Вы и ещё один участник должны решить, как разделить это добро между вами двоими. Для вас книга имеет ценность $4, каждый мяч — $2, а шляпы ценности не имеют. Для партнёра эти же объекты могут иметь другую ценность, но вам известно, что все объекты вместе для него ценны настолько же, насколько и для вас — в данном случае это $10.

Вы и партнёр по очереди предлагаете варианты раздела предметов. В свою очередь один из вас может либо принять предыдущее предложение (если только это не самая первая очередь), либо сделать встречное предложение. Переговоры ограничены 5 раундами, то в сумме оба участника могут выдвинуть до 10 предложений. Если за это время будет достигнуто соглашение, то каждый из вас получит суммарную ценность отходящих ему предметов (каждый в соответствии со своими коэффициентами ценности). Если же соглашение не достигнуто, то есть последнее слово в последнем раунде — встречное предложение, а не согласие, — то никто не получает ничего. То же самое происходит, если один из партнёров прерывает переговоры.

Вот пример того, как могут пройти переговоры:

  1. Вы: Я хочу книгу и два мяча; ты получишь один мяч и обе шляпы.
  2. Партнёр: Не согласен. Я хочу все мячи и одну шляпу; ты получишь книгу и одну шляпу.
  3. Вы: Не согласен. Я хочу книгу и один мяч; ты получишь два мяча и обе шляпы.
  4. Партнёр: Согласен.
Вам это не было известно, но для партнёра ценность предметов была такой: по $2 за мяч, по $2 за шляпу, книга не имеет ценности. Соглашение принесло $6 вам и $8 партнёру.

В общем случае есть два или более типов объектов и целое положительное число объектов каждого типа. Ценность каждого типа объектов для каждого из партнёров — целое неотрицательное число. Суммарная ценность всех объектов для обоих партнёров одинакова, хотя ценности отдельных предметов разнятся. Предложение о разделе должно распределять между партнёрами все объекты без остатка; отдельные объекты не дробятся.

Ваша задача — написать скрипт, стремящийся заключить сделку с максимально возможной ценностью (для себя).

Решения

Решение представляет собой модуль Node.js без зависимостей. Экспорт модуля должен представлять собой класс:
module.exports = class {
    constructor(me, counts, values, max_rounds, log){
        ..
    }
    offer(o){
        ...
    }
}
Экземпляр этого класса будет создан один раз и использован в течение сеанса переговоров. Конструктору передаются следующие аргументы:
  • me — 0, если ваша очередь первая, или 1, если вторая.
  • counts — массив целых чисел, содержащий количество объектов каждого типа. Он содержит от 2 до 10 элементов.
  • values — массив целых чисел такой же длины, что и counts, описывающий ценность объекта каждого из типов для вас.
  • max_rounds — число раундов переговоров (каждый раунд состоит из двух реплик).
  • log — функция, которую можно вызывать для отладочного вывода (console.log работать не будет).
Метод offer вызывается каждый раз, когда наступает ваша очередь. Его аргумент o — это массив целых чисел такой же длины, как counts. Аргумент описывает, сколько объектов каждого из типов вам предлагает партнёр. Если ваша очередь первая, и это самый первый раунд, то o равно undefined.

Метод offer должен вернуть undefined, если вы принимаете предложение (кроме случая, когда o равно undefined). В противном случае он должен вернуть массив целых чисел такой же длины, как counts, описывающий, сколько объектов каждого типа вы хотите оставить себе. Обратите внимание, что и аргумент o, и возвращаемое значение offer описывают раздел предметов с вашей точки зрения.

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

Окружение, в котором запускается скрипт, не предоставляет возможности накопления информации между сеансами.

В файле example.js приведён простой пример скрипта, удовлетворяющего правилам. Он принимает любое предложение, по которому ему отходит не менее половины суммарной ценности всех объектов; в противном случае он просто требует для себя все объекты, имеющие ненулевую ценность. Скрипт также демонстрирует применение функции log.

Тестирование

Скрипт haggle.js позволяет организовать переговоры между двумя участниками-людьми, между человеком и скриптом или между двумя скриптами. Запустите его с параметром --help, чтобы узнать обо всех его возможностях. (Чтобы установить все необходимые модули, запустите npm install в директории src.)

Мы будем устраивать попарные переговоры между скриптами, присланными участниками конкурса. Мы надеемся, что сможем провести не менее двух сеансов для каждой возможной пары, однако, если решений окажется слишком много, то нам, возможно, придётся выбрать другую систему проведения чемпионата. О конкретной системе будет объявлено позже. В любом случае, значение будут иметь не «победы» и «поражения», а сумма вознаграждений, полученных каждым скриптом во всех сеансах.

Для окончательного тестирования мы будем использовать параметры тестовой системы по умолчанию: 3 типа объектов, в сумме до 6 объектов, суммарная ценность всех объектов для каждого из партнёров $10, лимит в 5 раундов. Мы рекомендуем писать решения так, чтобы они поддерживали любую комбинацию параметров, которую поддерживает тестовая система.

Тестирование будет происходить на виртуальном сервере c3.large (см. аппаратные характеристики по ссылке) на Amazon AWS под управлением Ubuntu 14.04 (amd64). Решения будут тестироваться одна пара за другой при отсутствии прочей нагрузки на машине.

Мы исправлем баги в тестовой системе, о которых нам сообщают участники; следите за обновлениями (история). Сообщая о багах, передавайте нам, пожалуйста, протокол сеанса переговоров (его можно записать с помощью опции --log).

Переговоры онлайн

Мы предоставляем сервер, который позволяет вашему скрипту вести переговоры с другими участниками. Он устроен наподобие серверов онлайн-игр: можно подключиться к «арене», и сервер организует сеанс между вами и другим участником.

Изначально мы создали одну арену с настройками по умолчанию (3 типа объектов, в сумме до 6 объектов, суммарная ценность всех объектов для каждого из партнёров $10, лимит в 5 раундов). Эта арена не контролирует предел времени в 1 секунду, чтобы дать возможность и людям участвовать вручную. Вот адрес арены:

wss://hola.org/challenges/haggling/arena/standard
Используйте haggle.js, чтобы подключаться к серверу как участник-человек или же со своим скриптом. В этом режиме нужно также передавать параметр командной строки --id: это уникальный идентификатор, по которому система будет отслеживать успехи вашего скрипта. Мы рекомендуем использовать в качестве идентификатора ваш адрес электронной почты плюс постоянную случайную строку. Мы не будем публиковать идентификаторы. Позже мы запустим «живую» таблицу лучших результатов, где будут приведены средние исходы сделок и хэши идентификаторов.

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

Если ваш скрипт работает, мы рекомендуем, чтобы он постоянно участвовал в онлайн-сеансах, например, с помощью такой команды UNIX shell:

while true; do node haggle.js --id [email protected]:1234abcd myscript.js wss://hola.org/challenges/haggling/arena/standard; done

Отправка решений

Для отправки решений пользуйтесь формой на нашем сайте. По электронной почте решения не принимаются!

Поскольку код решений часто бывает сгенерированным, минимизированным или оттранслированным с другого языка, форма содержит также поле для отправки архива с исходными тестами. Если код сгенерирован, включите туда генератор; если он минимизирован, включите исходную версию; если код переведён с CoffeeScript или другого языка, включите код на том языке, на котором он написан. Желательно также включить в архив файл README с кратким описанием подхода к решению (по-английски). Архив должен быть в формате tar.gz, tar.bz2 или zip. Содержимое архива будет опубликовано, но не будет протестировано (мы тестируем только JS-файл, который вы отправляете вне архива).

Максимальный размер JS-файла установлен в 64 МиБ. Это произвольно выбранная цифра, которая существует в основном для того, чтобы чьё-нибудь «решение» одномоментно не заполнило нам диск. Если ваше решение правда больше 64 МиБ, напишите нам, и мы увеличим ограничение.

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

Желаем удачи всем участникам!

👍ПодобаєтьсяСподобалось0
До обраногоВ обраному0
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Объявления для участников конкурса по программированию.

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

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

Поэтому мы приняли решение проводить окончательное тестирование в два этапа. На квалификационном этапе для N случайно выбранных затравочных значений (seeds) будет проведён турнир «каждый с каждым», причём пара (A, B) считается отличной от (B, A). Таким образом, каждая пара (и в каждом порядке) будет запущена на каждом затравочном значении. Итогом квалификационного этапа станет список участников, расположенных по убыванию суммы набранных очков (именно суммы очков, а не числа «побед»).

Затем K лучших участников из списка выйдут в финал, где между ними будет проведён дополнительный турнир на M других случайно выбранных затравочных значениях. Финальные позиции между этими K участниками будут определены исключительно суммой очков, набранных ими в сеансах на N+M затравочных значениях между собой, без учёта сеансов с участием решений, не прошедших в финал.

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

Конкретные значения N, M и K будут объявлены позже, так как они зависят от числа решений, которые отправят нам участники.

Арены для онлайн-переговоров
Мы создали несколько новых арен: standard_1s подобна standard, но следит за соблюдением лимита в 1 секунду на ход (эта арена в точности соответствует условиям окончательного тестирования); large и large_1s — арены с «увеличенными» настройками на случай, если кто-нибудь захочет попробовать на них свои силы.

Смотрите список арен на странице проекта на GitHub.

Для каждой арены теперь доступна «живая» статистика по каждому выступавшему на ней решению (ссылки в первом столбце таблицы). Статистика приведена в машинно-читаемом формате JSON, из которого участникам конкурса не составит труда получить то представление данных, которое их интересует. Ключом в этих данных является хэш идентификатора клиента, указанного с помощью параметра --id. Этот хэш тестовая система показывает вам при каждом подключении к серверу. Для каждого участника приводятся общее число завершённых сеансов (sessions), число достигнутых соглашений (agreements) и сумма набранных очков (score) за всё время (all) и за каждые отдельные сутки (UTC).

Обновления тестовой системы
Следите за историей обновлений на GitHub: мы регулярно исправляем найденные участниками недостатки в тестовой системе. Регулярно делайте git pull!

Официальный чат
Для обсуждения конкурса создан канал в Telegram: @hola_challenge_haggling.

Hello, sorry for using English.

A spoiler script could employ a knocking code by permuting its offered quantities to alert the cheating opponent bot that it is dealing with its designated spoiler. The knocking sequences may be hidden inside the weights of a neural network and be opaque to source code analysis. Both bots, the spoiler and its designated friend, would employ such opaque models.

Since the size of the script is limited to 64MB, any such knocking code has plenty of space to hide itself and deceive its detection by analysis.

I’d suggest to either forbid the use of opaque models, or to thoroughly test each of the prize—winning bots by pairing it in competition against any other bot in the tournament, and check if any pair of bots consistently grants a good profit for one party, on multiple seeds and starting orders.

Тот случай, когда знаешь теорию игр, но ни в зуб ногой по Node.js

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

Как я понял, игра двух лиц с ненулевой суммой. Решение — множество Парето, на котором нет устойчивого состояния. Поскольку каких-либо рекомендаций по выбору точки на этом множестве нет, то тут чистый эксплойт стратегий оппонентов. Которые нам неизвестны. Получаем рандом. Возможно посможет MCTS + какая-то эвристика для rollout. Думаю, что для нейросети мощности Node.js будет недостаточно.

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

Тот, у кого будет больше промоутеров, будет победителем :)

Два чаю этому господину!

Истинная суть Hola — это огромная бот-сеть планетарного масштаба, работающая от имени всех кто её себе поставил. Отсюда истинная цель этого конкурса — найти звёзд этого «бизнеса». Разумеется Hola приветствует блокировки интернета в разных странах, это их золотое днище.

Решение — множество Парето, на котором нет устойчивого состояния.

Одна проблемка — нам не известна функция выигрыша оппонента...

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

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

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

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

А что мешается сговориться участникам? Или передать свои исходники сестре, брату, коту?

Статистический анализ, выявляющий сговор, и чтение исходников призёров.

Это очень субъективно и переводит соревнование в другую плоскость — как обмануть жюри.

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

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

Этот момент вызывает недопонимание. Заливая решение хоть сегодня, вы не сообщаете никакой информации никому кроме, разве что, организаторов. Другие смогут его «пощупать» и получить о нём какую-либо информацию, только если вы запускаете своё решение у себя дома в режиме онлайн-торговли. Соответственно, нет никакой разницы, заливать ли решение в первый день или в последний.

Отправка решения и запуск его в онлайн-режиме — два независимых действия. Можно отправлять и ни разу не запускать онлайн. Можно и наоборот (но тогда шансов на приз не будет). Можно отправлять одну программу, а онлайн запускать другую, или запускать онлайн несколько версий. Весь этот онлайн-сервер — just for fun.

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

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

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

> Почему костыльное решение должно снижать результаты более правильных?

Оно не снизит. Просто принесёт всем по нулям, как если бы его и не было.

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

Две кинокамеры заграничных, два портсигара отечественных, чаю... два чаю.

Підписатись на коментарі