Marque um jogo de Load, Defend and Shoot

11

Quando eu era criança, costumava jogar muito esse jogo.

Regras

Existem dois jogadores (vamos chamá-los de A e B), e cada jogador usa as mãos como armas. Existem três movimentos possíveis:

  1. Mãos para carregar munição na sua arma.

    Cada arma começa vazia. O carregamento aumenta a munição em um.

  2. Mãos apontando para o outro jogador a atirar.

    Isso diminui a munição em um. Você deve ter pelo menos uma unidade de munição para disparar.

  3. Braços cruzados para se proteger de um tiro.

Ambos os jogadores se movem simultaneamente. Se os dois jogadores atirarem ao mesmo tempo, as balas se acertam e o jogo continua. O jogo termina quando um jogador atira enquanto o outro está carregando munição.

Tiro e arma vazia são considerados trapaça . Se um jogador trapaceia enquanto o outro executa uma ação legal, o trapaceiro perde imediatamente. Se os dois jogadores trapacearem ao mesmo tempo, o jogo continua.

As tentativas de trapaça não diminuem a munição, portanto nunca pode ser negativa.

Desafio

Dados os movimentos feitos pelos jogadores A e B, calcule qual jogador venceu o jogo: 1para o jogador A, -1para o jogador B e 0para um empate. Você pode usar qualquer outro triplo de valores de retorno, mas precisa indicar na sua resposta quais você usa.

O jogo pode:

  • terminar sem ter que processar todos os movimentos;
  • não termina com os movimentos dados e, portanto, é considerado um empate.

A entrada pode ser obtida:

  • como cordas
  • como matrizes / listas de números inteiros
  • de qualquer outra maneira que não pré-processe a entrada

Programa completo ou funções permitidas. Como se trata de , a resposta mais curta em bytes vence!

Casos de teste

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
removido
fonte
1
KotH relacionado (curiosamente, nunca joguei essa variante do jogo; acho que a pergunta vinculada foi inspirada por um amigo que tinha, mas já faz tempo que não me lembro mais).
Maçaneta

Respostas:

6

Geléia, 33 32 24 bytes

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

Isso imprime 5 em vez de -1 e 7 em vez de 1 . Experimente online! ou verifique todos os casos de teste .

Como funciona

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.
Dennis
fonte
2

Pitão, 48 46 49 47 bytes

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

Experimente aqui!

Obrigado a @isaacg por salvar 2 4 bytes!

Faz a entrada como uma tupla de 2 com a lista dos movimentos do jogador A primeiro e os movimentos do jogador B segundo. A saída é a mesma do desafio.

Explicação

Breve visão geral

  • Primeiro, agrupamos os movimentos de ambos os jogadores, para obter uma lista de duas tuplas.
  • Em seguida, mapeamos cada uma dessas tuplas para outra de 2 tuplas no formulário [cheating win, fair win]com os valores possíveis -1, 0, 1para cada uma delas, para indicar se um jogador venceu neste momento ( -1, 1) ou se o jogo continua ( 0)
  • Agora só precisamos obter a primeira tupla que não é [0,0]e pegar o primeiro elemento diferente de zero que indica o vencedor

Repartição do código

.xhfT | Me, -FmgF.b / <dhkY2S2Q?} b_BS2-FbZ.b, NYCQ) 0 # Q = lista das listas de movimentação

                                      .b, NYCQ # emparelham os elementos de ambas as listas de entrada
       .e # mapeie a lista de pares com 
                                                 # b sendo o par ek é índice
            m Q # mapeia cada lista de movimento d
               .b 2S2 # map over [1,2], não posso usar m porque é
                                                 A variável # lambda entra em conflito com a variável .e
                  <dhk # d [: k + 1]
                 / Y # conta ocorrências de 1 ou 2 nesta lista
          -F # (contagem de 1s) - (contagem de 2s), indica vitória fraudulenta
                           ?} b_BS2 # se b for (1,2) ou (2,1)
                                  -Fb # leva a diferença, indica vitória justa
                                     Z # else 0, nenhum vencedor ainda
         , # emparelhe esses 2 valores
     | M # Para cada par resultante, pegue o primeiro se
                                                 # não é zero, caso contrário, o segundo
   fT # filtra todos os valores zero
.xh # tente usar o primeiro valor que indica o vencedor
                                             ) 0 # se isso não for possível porque a lista está vazia
                                                 # saída zero para indicar um empate
Denker
fonte
m|Fdé o mesmo que |M.
Isaacg
@isaacg Thanks! Eu sempre esqueço que Misso também respinga. Btw: A questão sobre variáveis ​​lambda conflitantes que discutimos no chat está me custando vários bytes aqui: P
Denker
,1 2é o mesmo queS2
isaacg 23/03
Eu adicionei outro caso de teste;)
removido
@isaacg Obrigado novamente! Não sei como eu perdi isso.
Denker
1

Python, 217 bytes

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

Explicação : Leva A e B como listas de números inteiros. Simplesmente passa por cada par de movimentos, adiciona ou subtrai 1, se necessário, e retorna quando alguém trapaceia ou ganha. Faz a mesma coisa duas vezes usando outro loop for, uma vez para a jogada de A e uma vez para a jogada de B. Adiciona 1 se x for menor que 0 a -1.

Melão Fricativo
fonte
1

Java, 226 212 200 196 194 bytes

-14 bytes reordenando a lógica

-12 bytes, graças ao Sr. Public, mostrando como usar uma operação ternária para a lógica de tiro

-4 bytes colocando a lógica de carga em um curto-circuito se

-2 bytes porque ==1=== <2quando a entrada só podem ser 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;}

Uso e versão recuada:

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}));
}

Implementação não tão direta das regras do jogo, mas simples. Cada ciclo, realiza estas operações:

  • Load move para variáveis ​​temporárias
  • Se o jogador atirou
    • sem munição: viés barato rpara perder
    • com munição: decrementar munição
  • Se o preço baixo rnão for 0, retorne o valor porque alguém trapaceou
  • Se o jogador recarregou
    • aumentar munição
    • se outro jogador atirar, retorne a perda

x é uma variável fictícia usada para fazer o compilador, deixe-me usar uma expressão ternária.

Espere, Java é mais CURTO que Python?

CAD97
fonte
Eu adicionei outro caso de teste;)
removido
1
@WashingtonGuedes E o meu funciona neste caso, graças à minha reordenação lógica!
CAD97
Os ifs podem ser transformados em ternários? por exemplow==2&&m<1?r--:m++
Downgoat 24/03/16
@Downgoat, o resto vai para o interior, se sim, como você escreveu, o terciário não funcionaria. No entanto, provavelmente posso fazê-lo com o if interno. Vou testá-lo quando tiver uma chance.
CAD97
1
@ CAD97 @Downgoat Você pode realmente usar operadores ternários para as instruções if. Pela primeira ternário, int x=w==2?m<1?r--:r:m--;em seguida, continuar a usar o x (como esta é apenas uma variável dummy para fazer o ternário operar) comox=v==2?n<1?r++:r:n--;
Sr. Pública