Забей на игру Load, Defend and Shoot

11

Когда я был ребенком, я часто играл в эту игру.

правила

Есть два игрока (назовем их A и B), и каждый игрок использует свои руки в качестве оружия. Есть три возможных хода:

  1. Руки вверх, чтобы загрузить боеприпасы к вашему оружию.

    Каждый пистолет начинается пустым. Загрузка увеличивает боеприпасы на один.

  2. Руки, указывающие на другого игрока, чтобы стрелять.

    Это уменьшает боеприпасы на один. Вы должны иметь хотя бы одну единицу патронов, чтобы стрелять.

  3. Скрещенные руки, чтобы защитить себя от выстрела.

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

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

Попытки обмана не уменьшают боеприпасы, поэтому они никогда не могут быть отрицательными.

Вызов

Учитывая ходы игроков A и B, выведите, какой игрок выиграл игру: 1для игрока A, -1для игрока B и 0для ничьей. Вы можете использовать любую другую тройку возвращаемых значений, но вам нужно указать в своем ответе, какие из них вы используете.

Игра может:

  • конец без необходимости обрабатывать все ходы;
  • не заканчивается данными ходами, и поэтому считается ничьей.

Вход может быть взят:

  • как строки
  • как массивы / списки целых чисел
  • любым другим способом, который не предварительно обрабатывает ввод

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

Контрольные примеры

A: "123331123"
B: "131122332"
    -----^                Player B shoots player A and wins.

Output: -1
A: "111322213312"
B: "131332221133"
    -------^              Player B cheats and loses.

Output: 1
A: "1333211232221"
B: "1213211322221"
    ----------^^          Both players cheat at the same time. The game continues.

Output: 0
A: "12333213112222212"
B: "13122213312232211"
         |       || ^---- Player A shoots player B and wins.
         ^-------^^------ Both players cheat at the same time. The game continues.

Output: 1
удален
источник
1
Связанный KotH (интересно, я никогда не играл в этот вариант игры; я думаю, что связанный вопрос был вдохновлен другом, который имел, но это было достаточно давно, что я не помню больше).
Дверная ручка

Ответы:

6

Желе, 33 32 24 байта

Zæ%1.»0$+¥\>-‘żZḅ3Ff5,7Ḣ

Это печатает 5 вместо -1 и 7 вместо 1 . Попробуйте онлайн! или проверьте все контрольные примеры .

Как это работает

Zæ%1.»0$+¥\>-‘żZḅ3Ff5,7Ḣ  Main link. Argument: A (digit list array)

Z                         Zip; group corresponding digits.
 æ%1.                     Map the digits in (-1.5, 1.5].
                          This replaces [1, 2, 3] with [1, -1, 0].
          \               Cumulatively reduce the pairs by doing the following.
     »0$                    Take the maximum of the left value and 0, i.e., replace
                            a -1 with a 0.
        +¥                  Add the modified left value to the right value.
                          This computes the available ammo after each action. An
                          ammo of -1 indicates a cheating attempt.
           >-             Compare the results with -1.
             ‘            Increment. And unilateral cheating attempt is now [1, 2]
                          or [2, 1], where 1 signals the cheater and 2 the winner.
              żZ          Pair each result with the corr., original digits.
                ḅ3        Convert each pair from base 3 to integer.
                          This maps [1, 2] and [2, 1] to 5 and 7.
                  F       Flatten the resulting, nested list.
                   f5,7   Discard all but 5's and 7's.
                       Ḣ  Grab the first element (5 or 7).
                          If the list is empty, this returns 0.
Деннис
источник
2

Pyth, 48 46 49 47 байт

.xhfT|M.e,-FmgF.b/<dhkY2S2Q?}b_BS2-FbZ.b,NYCQ)0

Попробуй это здесь!

Спасибо @isaacg за сохранение 2 4 байта!

Принимает ввод в виде 2-х кортежей со списком ходов игрока A первым и ходов игрока B вторым. Выход такой же, как в задании.

объяснение

Краткий обзор

  • Сначала мы группируем ходы обоих игроков, чтобы получить список из двух кортежей.
  • Затем мы отображаем каждый из этих кортежей в другой 2-кортеж в форме [cheating win, fair win]с возможными значениями -1, 0, 1для каждого из них, чтобы указать, выиграл ли игрок в этой точке ( -1, 1) или игра продолжается ( 0)
  • Теперь нам просто нужно получить первый кортеж, которого нет [0,0], и взять первый ненулевой элемент, который указывает победителя

Разбивка кода

.xhfT | Me, -FmgF.b / <dhkY2S2Q?} b_BS2-FbZ.b, NYCQ) 0 # Q = список списков перемещений

                                      .b, NYCQ # пара элементов обоих входных списков
       .e # отобразить список пар с 
                                                 # b - пара, а k - индекс
            m Q # отображать каждый список ходов d
               .b 2S2 # map over [1,2], я не могу использовать m, потому что это
                                                 Переменная # lambda конфликтует с переменной из .e
                  <dhk # d [: k + 1]
                 / Y # количество вхождений 1 или 2 в этом списке
          -F # (число 1 с) - (количество 2 с), указывает на обманную победу
                           ?} b_BS2 #, если b равно (1,2) или (2,1)
                                  -Fb # принять разницу, означает честный выигрыш
                                     Z # еще 0, пока нет победителя
         # соединить эти 2 значения
     | M # Для каждой полученной пары возьмите первую, если
                                                 # это не ноль, иначе второй
   fT # отфильтровать все нулевые значения
.xh # попробуйте принять первое значение, которое указывает победителя
                                             ) 0 #, если это невозможно, потому что список пуст
                                                 # вывести ноль для обозначения ничьей
Denker
источник
m|Fdтак же, как |M.
Исаак
@isaacg Спасибо! Я всегда забываю, что Mделает брызги, а также. Кстати: вопрос о конфликтующих лямбда-переменных, которые мы обсуждали в чате, стоит мне несколько байт здесь: P
Денкер
,1 2так же, какS2
Исаак
Я добавил еще один тестовый пример;)
убрал
@isaacg Еще раз спасибо! Не знаю, как я это пропустил.
Денкер
1

Python, 217 байт

def f(A,B):
 x=y=0;c=[-1,1,0]
 for i in range(len(A)):
  a=A[i];b=B[i]
  for s in[0,1]:
   if(a,b)==(2,1):return c[s]*c[x<1]
   if(a,b)==(2,3)and x<1:return-c[s]
   x-=c[a-1];x+=x<0;a,b,x,y=b,a,y,x
 return 0

Объяснение : Принимает A и B как списки целых чисел. Просто проходит каждую пару ходов, добавляет или вычитает 1, если необходимо, и возвращается, когда кто-то обманывает или выигрывает. Делает то же самое дважды, используя другой цикл for, один раз для хода A и один раз для хода B. Добавляет 1, если x опускается ниже 0 до -1.

Фрикативная дыня
источник
1

Ява, 226 212 200 196 194 байта

-14 байтов при переупорядочении логики

-12 байт благодаря мистеру Public, указывающему, как использовать троичную операцию для логики стрельбы

-4 байта, запихивая логику нагрузки в одно короткое замыкание, если

-2 байт , так как ==1=== , <2когда входные данные могут быть только 1, 2,3

(a,b)->{for(int m=0,n=0,w,v,r=0,i=0,x;i<a.length;){w=a[i];v=b[i++];x=w==2?m<1?r--:m--:0;x=v==2?n<1?r++:n--:0;if(r!=0)return r;if(w<2&&++m>0&v==2)return -1;if(v<2&&++n>0&w==2)return 1;}return 0;}

Использование и версия с отступом:

static BiFunction<Integer[], Integer[], Integer> game = (a,b) -> {
    for(int m=0,n=0,w,v,r=0,i=0,x;i<a.length;) {
        w=a[i];v=b[i++];
        // shoot
        x=w==2?m<1?r--:m--:0;
        x=v==2?n<1?r++:n--:0;
        if(r!=0)return r;
        // load
        if(w<2&&++m>0&v==2)return -1;
        if(v<2&&++n>0&w==2)return 1;
    }
    return 0;
};

public static void main(String[] args) {
    System.out.println(game.apply(new Integer[] {1,2,3,3,3,1,1,2,3}, new Integer[] {1,3,1,1,2,2,3,3,2}));
    System.out.println(game.apply(new Integer[] {1,1,1,3,2,2,2,1,3,3,1,2}, new Integer[] {1,3,1,3,3,2,2,2,1,1,3,3}));
    System.out.println(game.apply(new Integer[] {1,3,3,3,2,1,1,2,3,2,2,2,1}, new Integer[] {1,2,1,3,2,1,1,3,2,2,2,2,1}));
}

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

  • Загрузка перемещается во временные переменные
  • Если игрок выстрелил
    • без патронов: смещения cheate rк проигрышу
    • с боеприпасами: уменьшить боеприпасы
  • Если обмана rнет 0, верните значение, потому что кто-то обманул
  • Если игрок перезагружен
    • прирост боеприпасов
    • если другой игрок выстрелил, вернуть убыток

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

Подождите, Java короче, чем Python?

CAD97
источник
Я добавил еще один тестовый пример;)
убрал
1
@WashingtonGuedes И мое работает над этим делом благодаря моей логической переупорядоченности!
CAD97
Можно ли превратить ifs в тернары? напримерw==2&&m<1?r--:m++
Downgoat
@ Downgoat остальное идет с внутренним, если так, как вы написали, третичный не будет работать. Тем не менее, я, вероятно, могу сделать это с внутренним, если. Я проверю это, когда у меня будет шанс.
CAD97
1
@ CAD97 @Downgoat Вы можете использовать троичные операторы для операторов if. Для первой троицы, int x=w==2?m<1?r--:r:m--;затем продолжайте использовать x (так как это всего лишь фиктивная переменная, чтобы заставить троичную работать), какx=v==2?n<1?r++:r:n--;
Mr Public