Anota un juego de Cargar, defender y disparar


11

Cuando era niño, solía jugar mucho a este juego.

Reglas

Hay dos jugadores (llamémoslos A y B), y cada jugador usa sus manos como pistolas. Hay tres movimientos posibles:

  1. Manos arriba para cargar municiones a tu arma.

    Cada arma comienza vacía. La carga aumenta la munición en uno.

  2. Manos apuntando al otro jugador para disparar.

    Esto disminuye la munición en uno. Debes tener al menos una unidad de munición para disparar.

  3. Brazos cruzados para protegerse de un disparo.

Ambos jugadores se mueven simultáneamente. Si ambos jugadores disparan al mismo tiempo, las balas se golpean entre sí y el juego continúa. El juego termina cuando un jugador dispara mientras el otro carga municiones.

Disparar y arma vacía se considera trampa . Si un jugador hace trampa mientras el otro realiza una acción legal, el tramposo pierde inmediatamente. Si ambos jugadores hacen trampa al mismo tiempo, el juego continúa.

Los intentos de trampa no disminuyen la munición, por lo que nunca puede ser negativa.

Desafío

Dados los movimientos realizados por los jugadores A y B, salida que jugador ganó el juego: 1para el jugador A, -1para el jugador B y 0para un empate. Puede usar cualquier otro triple de valores de retorno, pero debe indicar en su respuesta cuáles usa.

El juego puede:

  • terminar sin tener que procesar todos los movimientos;
  • no termina con los movimientos dados, y por lo tanto se considera un empate.

La entrada se puede tomar:

  • como cuerdas
  • como matrices / listas de enteros
  • de cualquier otra manera que no preprocese la entrada

Programa completo o funciones permitidas. Como se trata de , ¡la respuesta más corta en bytes gana!

Casos de prueba

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 relacionado (curiosamente, nunca he jugado esta variante del juego; creo que la pregunta vinculada fue inspirada por un amigo que sí, pero fue hace bastante tiempo que ya no me acuerdo).
Pomo de la puerta

Respuestas:


6

Jalea, 33 32 24 bytes

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

Esto imprime 5 en lugar de -1 y 7 en lugar de 1 . Pruébalo en línea! o verificar todos los casos de prueba .

Cómo 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.

2

Pyth, 48 46 49 47 bytes

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

Pruébalo aquí!

¡Gracias a @isaacg por guardar 2 4 bytes!

Toma la entrada como una tupla de 2 con la lista de los movimientos del jugador A primero y los movimientos del jugador B segundo. La salida es la misma que en el desafío.

Explicación

Breve resumen

  • Primero agrupamos los movimientos de ambos jugadores para obtener una lista de 2 tuplas.
  • Luego asignamos cada una de esas tuplas a otras 2 tuplas en el formulario [cheating win, fair win]con los valores posibles -1, 0, 1para cada una de ellas, para indicar si un jugador ganó en este punto ( -1, 1) o si el juego continúa ( 0)
  • Ahora solo necesitamos obtener la primera tupla que no es [0,0], y tomar el primer elemento distinto de cero que indica el ganador

Desglose de código

.xhfT | Me, -FmgF.b / <dhkY2S2Q?} b_BS2-FbZ.b, NYCQ) 0 # Q = lista de las listas de movimientos

                                      .b, NYCQ # empareja los elementos de ambas listas de entrada
       .e # mapa sobre la lista de pares con 
                                                 # b es el par yk es índice
            m Q # asigna cada lista de movimientos d
               .b mapa 2S2 # sobre [1,2], no puedo usar m porque es
                                                 La variable # lambda entra en conflicto con la de .e
                  <dhk # d [: k + 1]
                 / Y # cuenta las ocurrencias de 1 o 2 en esta lista
          -F # (recuento de 1s) - (recuento de 2s), indica victoria de trampa
                           ?} b_BS2 # si b es (1,2) o (2,1)
                                  -Fb # toma la diferencia, indica victoria justa
                                     Z # más 0, todavía no hay ganador
         , # emparejar esos 2 valores
     | M # Para cada par resultante, tome el primero si
                                                 # no es cero, de lo contrario el segundo
   fT # filtra todos los valores cero
.xh # intenta tomar el primer valor que indica el ganador
                                             ) 0 # si eso no es posible porque la lista está vacía
                                                 # salida cero para indicar un empate

m|Fdes el mismo que |M.
isaacg

@isaacg ¡Gracias! Siempre olvido que Meso también salpica. Por cierto: el problema sobre las variables lambda en conflicto que discutimos en el chat me está costando varios bytes aquí: P
Denker

,1 2es lo mismo queS2
isaacg

He agregado otro caso de prueba;)
eliminado el

@isaacg Gracias de nuevo! No sé cómo me perdí eso.
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

Explicación : Toma A y B como listas de enteros. Simplemente pasa por cada par de movimientos, suma o resta 1 si es necesario y regresa cuando alguien hace trampa o gana. Hace lo mismo dos veces usando otro bucle for, uno para el movimiento de A y otro para el movimiento de B. Agrega 1 si x va por debajo de 0 a -1.


1

Java, 226 212 200 196 194 bytes

-14 bytes reordenando la lógica

-12 bytes gracias al Sr. Public que señala cómo utilizar una operación ternaria para la lógica de disparo

-4 bytes agrupando la lógica de carga en un cortocircuito si

-2 bytes porque ==1=== <2cuando la entrada sólo puede 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 y versión sangrada:

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

Ya no es tan sencilla la implementación de las reglas del juego, sino simple. Cada ciclo, realiza estas operaciones:

  • La carga se mueve a variables temporales
  • Si el jugador disparó
    • sin munición: sesgo engaño rhacia perder
    • con munición: decremento de munición
  • Si el engaño rno lo es 0, devuelve el valor porque alguien hizo trampa
  • Si el jugador recargado
    • incremento de munición
    • si otro jugador disparó, devuelve la pérdida

x es una variable ficticia utilizada para hacer que el compilador me permita usar una expresión ternaria.

Espera, ¿Java es MÁS CORTO que Python?


He agregado otro caso de prueba;)
eliminado el

1
@WashingtonGuedes ¡Y el mío funciona en este caso gracias a mi reordenamiento lógico!
CAD97

¿Se pueden convertir los if en ternarys? egw==2&&m<1?r--:m++
Downgoat

@Downgoat lo demás va con lo interno si, así como lo has escrito, el terciario no funcionaría. Sin embargo, probablemente pueda hacerlo con el if interno. Lo probaré cuando tenga la oportunidad.
CAD97

1
@ CAD97 @Downgoat En realidad, puede usar operadores ternarios para las declaraciones if. Para el primer ternario, int x=w==2?m<1?r--:r:m--;luego continúe usando la x (ya que esta es solo una variable ficticia para hacer que el ternario opere) comox=v==2?n<1?r++:r:n--;
Mr Public
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.