Автор lperovskaya, 16 месяцев назад, По-русски
Tutorial is loading...
Tutorial is loading...
Tutorial is loading...
Tutorial is loading...
  • Проголосовать: нравится
  • +38
  • Проголосовать: не нравится

»
16 месяцев назад, # |
  Проголосовать: нравится +10 Проголосовать: не нравится

Очень хорошая задача Д. На самом деле я нашел 26 ответов, кроме одного со значением 24, с помощью гадания.

»
16 месяцев назад, # |
  Проголосовать: нравится +3 Проголосовать: не нравится

Не могли бы вы дать нам право видеть чужой код? Мне очень интересно, как другие решили проблему D.

  • »
    »
    16 месяцев назад, # ^ |
      Проголосовать: нравится +6 Проголосовать: не нравится

    Я дошел от 0 до 30. В начале рандомил раздачу карт. Как только результат рос — сохранял, и менял между игроками одну-две карты от предыдущего максимума. В итоге дошел до ответа. После этого заметил паттерн.

    • »
      »
      »
      16 месяцев назад, # ^ |
        Проголосовать: нравится +6 Проголосовать: не нравится

      Сначала я выполнил несколько случайных действий, а затем использовал 1 час, чтобы найти ответ от 0 до 12. Затем я обнаружил закономерность из ответа 12, хотя она была не очень ясной. После этого я нашел чистый случай с ответом 30, но когда я искал два последних ответа 15 и 24, я догадался, что 15 более вероятен, и после 30 минут поиска я нашел случай с ответом 15.

    • »
      »
      »
      16 месяцев назад, # ^ |
        Проголосовать: нравится +3 Проголосовать: не нравится

      Максим решил вопрос так быстро, и мне интересно, как он это сделал. Но у меня нет права просматривать его код (печально).

      • »
        »
        »
        »
        16 месяцев назад, # ^ |
        Rev. 2   Проголосовать: нравится +10 Проголосовать: не нравится

        Я думаю, что самый быстрый способ это решить задачу D3 математичекски, и потом перепроверить через модифицированную D1. Я это уже после сообразил. Матеметически 30 получается когда например:

        string s1 = "9D 9H TS TC JC JS QC QS KC KS AC AS 8C 8S 7C 7S 6C 6S";
        string s2 = "9C 9S TD TH JD JH QD QH KD KH AD AH 8D 8H 7H 7D 6H 6D";
        

        Если поменять местами TS-TD получается 26, TS-JD = 23, итд до KC-KD = 16. Потом если добавить обмен еще одной-двух пар карт можно дойти до 0. Например (JS-QH) + TS-JD = 15. И (TS-KH + AC-AD) + TS-JD = 7

      • »
        »
        »
        »
        16 месяцев назад, # ^ |
          Проголосовать: нравится +10 Проголосовать: не нравится

        Я, конечно, не Максим, но по времени решил примерно за столько же, поэтому объясню своё решение:
        D1 я решил ровно как в разборе, мой код
        Для D2 я решил генерировать случайные перестановки, совсем не запариваясь на счёт времени выполнения. За полчаса у меня как раз сгенерировались 13 вариантов
        Оставив перебор запущенным, пошёл попить чаю, а когда вернулся, у меня было где-то 15-16 ответов. Достав колоду физических карт, начал примерно вникать в процесс игры и как, собственно, можно получить большую разницу. Разложил на столе ответ с разностью 15 (или 16, сейчас уже не вспомню) и заметил, что в нём такого уникального: фиксируем две масти, у первого только девятка, у второго все остальные карты этой масти, и наоборот для другой масти, третья-четвёртая масть рандомом. Начал перебирать руками варианты, как можно изменить пример на 16, чтобы стало больше. Запуская на придуманных раскладах D1 получил достаточно много значений, но до 26 всё равно было далеко. Понял как добиться 30, я думаю этот случай многие обнаружили руками. А потом меня осенило, что же я руками это всё генерирую, если мы первые 18 карт фиксируем в таком виде

        000100000 111011111  
        111011111 000100000  
        

        то остаётся всего 18 карт, каждая из которых может быть только у одного, то есть перебирать всего С(18, 9) вариантов. Немного хардкода и меньше чем за минуту у меня сгенерировалось всё кроме 24

  • »
    »
    16 месяцев назад, # ^ |
      Проголосовать: нравится +11 Проголосовать: не нравится

    После решения D1 динамикой, описанной в разборе прикрутил перебор раскладов карт и ждал минут 30, пока не получил 13 раскладов. Очевидная мысль, но от этого не менее важная, заключается в том, что расклады надо перебирать не за 36! (как перестановки карт и отдавать первому, например первую половину, а второму — вторую), а за С из 36 по 18, например, рекурсивно, т.к. порядок карт в руке не важен.

    С нахождением 26 раскладов, как многие отметили, всё оказалось не так просто, ибо оставленный на ночь перебор не нашёл даже 14й. Попытавшись придумать несколько стартовых перестановок для перебора самостоятельно, за пару часов я получил буквально 1-2 новых расклада. Но что более важно, заметил, что после 15 минут перебора время на нахождение следующего расклада становится кратно больше предыдущего. Тогда я начал генерировать (условно руками) случайные перестановки, и начинать перебор с них. Одна из таких перестановок дала ещё 5 новых раскладов. В общем, у меня было 19 различных раскладов, когда процесс генерации случайных перестановок и последующего 15-ти минутного перебора был целиком автоматизирован и параллельно запущен на нескольких машинах.

    Кстати, о параллельных вычислениях я задумался как только прочёл задачу (дальше немного тривиальных вычислений для тех, кому интересно). Для начала, посчитаем, что С из 36 по 18 это примерно $$$9*10^9$$$. Одна игра считается за 46мс (если верить CF), для одного расклада надо посчитать 2 игры, округлим до 0.1с. Тогда в одном потоке полный перебор займёт $$$9*10^9*0.1c = 252*10^3ч$$$. На квалификацию давалось 14 дней, поэтому результат хотелось бы получить дней за 10, то есть 240 часов. Следовательно нужно было около 1000 потоков, чтобы успеть перебрать все расклады, что в своё время окончательно убедило меня не надеяться на последовательный перебор.

    А далее за обедом на работе, рассказывая товарищу об этой задаче, я задумался о том, какой расклад может иметь важность первого хода больше 20, и спустя 5 минут мне в голову пришёл расклад, описанный в разборе. Ещё немного подумал, какие карты стоит менять в первую очередь, чтобы получить другую важность первого хода, и запустил перебор, который за всё те же 15 минут выдал 21 различный расклад, из которых 7 у меня как раз не было ранее.

»
16 месяцев назад, # |
  Проголосовать: нравится +10 Проголосовать: не нравится

Кто-нибудь смог решить D3 с помощью перебора случайных игр и подсчёта стоимости для них слегка модифицированным алгоритмом из D1? У меня получилось найти 13 различных стоимостей за ~190 секунд, 26 так и не получилось найти, хотя программа работала примерно часов 6.

  • »
    »
    16 месяцев назад, # ^ |
      Проголосовать: нравится +5 Проголосовать: не нравится

    Здравствуйте. Я занял 8 место в конкурсе, и хочу сказать, что практически невозможно найти все 26 ответов с помощью рандомизации, потому что 30-й ответ уникален в очень многих случаях. Я потратил час на поиск ответов от 0 до 12, и когда я заметил, что 12-й ответ был найден только один раз в течение часа поиска, я понял, что я должен найти какой-то особый случай вместо того, чтобы продолжать рандомизацию.

  • »
    »
    16 месяцев назад, # ^ |
      Проголосовать: нравится +16 Проголосовать: не нравится

    Это можно сделать, соптимизировав вычисление важности расклада альфа-бета отсечением с нулевым окном поиска и мемоизацией (локальной для одного расклада), и отбрасыванием раскладов, которые даже при неоптимальной игре не могут дать интересную важность. Полный перебор возможных раскладов (с точностью до перестановки мастей) занимает 8 минут в один поток, если сразу искать важность $$$\geq25$$$ -- 80 секунд.