Determinar el ganador de un juego de guerra

19

El juego de cartas War es interesante porque el resultado final está completamente determinado por la disposición inicial del mazo, siempre que se sigan ciertas reglas para el orden en que las cartas se recogen del campo de juego y se mueven a los mazos. En este desafío, solo habrá 2 jugadores, lo que simplificará enormemente las cosas.

El juego

  1. Cada jugador recibe un mazo de 26 cartas.
  2. Cada jugador coloca la carta superior en su mazo boca arriba. El jugador con la carta de mayor rango ( Ace > King > Queen > Jack > 10 > 9 > 8 > 7 > 6 > 5 > 4 > 3 > 2) gana la ronda, coloca su carta encima de la carta de su oponente, la voltea y la agrega al fondo de su mazo (por lo que su carta ganadora está en la parte inferior del mazo , y la carta perdedora del otro jugador está justo encima de ella). Esto se hace hasta que uno de los jugadores se quede sin cartas.
    • Si las cartas son de igual rango, entonces cada jugador coloca las 2 primeras cartas de su mazo boca arriba sobre su carta anterior (de modo que la carta que estaba encima del mazo es la segunda carta en la pila, y el la tarjeta que estaba en segundo lugar desde arriba está en la parte superior). Luego, los rangos (de la primera carta de cada pila) se comparan nuevamente, y el ganador coloca su pila completa encima de la pila entera del perdedor, la pone boca abajo y la coloca en la parte inferior de su mazo. Si hay otro empate, se juegan más cartas de la misma manera, hasta que se elija un ganador o un jugador se quede sin cartas.

Si en algún momento uno de los jugadores necesita sacar una carta de su mazo, pero su mazo está vacío, inmediatamente pierden el juego.

El reto

Dadas dos listas de cartas en los mazos de los jugadores, en cualquier formato conveniente, generan un valor verdadero si el Jugador 1 gana, y un valor falso si el Jugador 2 gana.

Por conveniencia, una carta de 10 se representará con una T, y las cartas de cara se abreviarán ( Ace -> A, King -> K, Queen -> Q, Jack -> J), de modo que todas las cartas tengan un solo carácter. Alternativamente, los rangos pueden representarse con enteros decimales 2-14 ( Jack -> 11, Queen -> 12, King -> 13, Ace -> 14) o dígitos hexadecimales 2-E ( 10 -> A, Jack -> B, Queen -> C, King -> D, Ace -> E). Como los trajes no importan, la información del traje no se dará.

  • Puede suponer que todos los juegos terminarán en algún momento (aunque puede llevar mucho tiempo), y un jugador siempre se quedará sin cartas antes que el otro.
  • Cada jugador coloca cartas simultáneamente, y una carta a la vez, por lo que nunca hay ambigüedad sobre qué jugador se quedó sin cartas primero.

Casos de prueba

Los casos de prueba se utilizan 23456789ABCDEpara representar los rangos (en orden ascendente).

D58B35926B92C7C4C7E8D3DAA2, 8E47C38A2DEA43467EB9566B95 -> False
669D9D846D4B3BA52452C2EDEB, E747CA988CC76723935A3B8EA5 -> False
5744B95ECDC6D325B28A782A72, 68394D9DA96EBBA8533EE7C6C4 -> True
87DB6C7EBC6C8D722389923DC6, E28435DBEBEA543AA47956594A -> False
589EAB9DCD43E9EC264A5726A8, 48DC2577BD68AB9335263B7EC4 -> True
E3698D7C46A739AE5BE2C49286, BB54B7D78954ED526A83C3CDA2 -> True
32298B5E785DC394467D5C9CB2, 5ED6AAD93E873EA628B6A4BC47 -> True
B4AB985B34756C624C92DE5E97, 3EDD5BA2A68397C26CE837AD48 -> False
9A6D9A5457BB6ACBC5E8D7D4A9, 73E658CE2C3E289B837422D463 -> True
96E64D226BC8B7D6C5974BAE32, 58DC7A8C543E35978AEBA34D29 -> True
C2978A35E74D7652BA9762C458, 9A9BB332BE8C8DD44CE3DE66A5 -> False
BEDB44E947693CD284923CEA82, 8CC3B75756255A683A6AB9E7DD -> False
EEDDCCBBAA8877665544332299, EEDDCCBBAA9988776655443322 -> False
EEDDCCBBAA9988776655443322, DDCCBBAA9988776655443E3E22 -> True

Implementación de referencia

Esta implementación de referencia está escrita en Python 3 y toma la entrada en el mismo formato que los casos de prueba (excepto separados por una nueva línea en lugar de una coma y un espacio).

#!/usr/bin/env python3

from collections import deque

p1, p2 = [deque(s) for s in (input(),input())]
print(''.join(p1))
print(''.join(p2))

try:
    while p1 and p2:
        p1s = [p1.popleft()]
        p2s = [p2.popleft()]
        while p1s[-1] == p2s[-1]:
            p1s.append(p1.popleft())
            p2s.append(p2.popleft())
            p1s.append(p1.popleft())
            p2s.append(p2.popleft())
        if p1s[-1] > p2s[-1]:
            p1.extend(p2s+p1s)
        else:
            p2.extend(p1s+p2s)
except IndexError:
    pass
finally:
    print(len(p1) > 0)
Mego
fuente
2
Relacionado
Bassdrop Cumberwubwubwub
1
Para una baraja de cartas, 1, 2, 3el juego no tiene fin ya que sigues ganando a tu oponente 1. ¿Es una peculiaridad tener un número impar de cartas?
Neil
@Neil ¿Qué mazo de cartas tiene un 1?
Suever
@Suever Lo siento, no pensé demasiado, solo elegí los primeros tres números diferentes que se me ocurrieron. Simplemente elija tres cartas donde la primera sea la más baja.
Neil
@Neil Solo te estoy haciendo pasar un mal momento :) ¡Punto tomado!
Suever

Respuestas:

3

JavaScript (ES6), 134 bytes

f=([p,...r],[q,...s],t=[],u=[],v)=>!q||p&&(v|p==q?f(r,s,[...t,p],[...u,q],!v):p>q?f([...r,...u,q,...t,p],s):f(r,[...s,...t,p,...u,q]))
<div oninput=o.checked=f(p.value,q.value)>
Player 1's cards: <input id=p><br>
Player 2's cards: <input id=q><br>
<input id=o type="checkbox"> Player 2 loses

Regresa undefinedsi el jugador 2 gana, de lo truecontrario. Acepta iteradores comparables, generalmente conjuntos de enteros o cadenas de caracteres hexadecimales. La respuesta está compuesta por más del 22% de los .caracteres, lo que creo que debe ser un récord para mí.

Neil
fuente
Parece que no obtengo los resultados correctos cuando intento esto con los casos de prueba. Ver jsfiddle.net/xbq5xzco
Chuck Morris
@ChuckMorris Lo siento, había pasado por alto una de las reglas. Debería arreglarse ahora.
Neil
@Mego Inténtalo de nuevo, lo acabo de actualizar.
Neil
Todo parece salir ahora.
Mego
OK, ahora estoy impresionado!
Chuck Morris
4

Python, 160 (155?) Bytes

f=lambda x,y,z=1:f(*((x,y,z+2),(x[z:]+y[:z]+x[:z],y[z:]),(x[z:],y[z:]+x[:z]+y[:z]))[(x[z-1]>y[z-1])+(x[z-1]<y[z-1])*2])if len(y)>z<len(x)else len(x)>len(y)

Esta solución es teóricamente válida, pero requiere que se aumente la profundidad de recursión máxima predeterminada de Python para algunos de los casos de prueba.

La segunda solución es 5 bytes más larga, pero funciona para todos los casos de prueba.

f=lambda x,y,z=1:(f(x,y,z+2)if x[z-1]==y[z-1]else f(x[z:]+y[:z]+x[:z],y[z:])if x[z-1]>y[z-1]else f(x[z:],y[z:]+x[:z]+y[:z]))if len(y)>z<len(x)else len(x)>len(y)

Editar: Solución 1 sin golf:

def f(x,y,z=1):
    if len(y)<z>len(x):
        return len(x)>len(y)
    else:
        return f(*(
            (x,y,z+2),
            (x[z:],y[z:]+x[:z]+y[:z]),
            (x[z:]+y[:z]+x[:z],y[z:])
        )[(x[z-1]>y[z-1])+(x[z-1]<y[z-1])*2])
Lulhum
fuente
Como IronPython ejecutará bien la primera solución (la profundidad de recursión predeterminada es ilimitada), voy a decir que la primera solución es válida.
Mego
2

Python, 261 a 265 bytes

def f(a,b):
 if a==""or b=="":return b==""
 p=a[0];q=b[0];a=a[1:];b=b[1:]
 if p>q:a+=q+p
 if p<q:b+=p+q
 while p[-1]==q[-1]:
  if len(a)<2 or len(b)<2:return len(b)<2
  v=a[1];w=b[1];p+=a[0:2];q+=b[0:2];a=a[2:];b=b[2:]
  if v>w:a+=q+p
  if v<w:b+=p+q
 return f(a,b)

Según lo publicado, esto es 265 bytes y funciona tanto en Python 2 como en Python 3. Puede guardar 4 bytes en Python 2 reemplazando los espacios con una sola pestaña en el bucle while.

Pruébalo en línea

Chuck Morris
fuente
2

Haskell, 372

Mi primer programa Haskell

(También es mi primera programación funcional ...)

w[]_=False
w _[]=True
w a b=if length j==0 then a>b else w (drop(d$head j)a++fst(head j))(drop(d$head j)b++snd(head j))where j=p a b
d(a,b)=quot(maximum[length a,length b])2
f (Just a)=a
p a b=map f$filter(/=Nothing)[t(a!!x,take(x+1)a,b!!x,take(x+1)b)|x<-[0,2..minimum[length a,length b]-1]]
t(a,b,c,d)=if a==c then Nothing else if a>c then Just(d++b,[])else Just([],b++d)

Me encantaría tener consejos sobre cómo mejorar.

Uso:

w "D58B35926B92C7C4C7E8D3DAA2" "8E47C38A2DEA43467EB9566B95"
w "669D9D846D4B3BA52452C2EDEB" "E747CA988CC76723935A3B8EA5"
w "5744B95ECDC6D325B28A782A72" "68394D9DA96EBBA8533EE7C6C4"
w "87DB6C7EBC6C8D722389923DC6" "E28435DBEBEA543AA47956594A"
w "589EAB9DCD43E9EC264A5726A8" "48DC2577BD68AB9335263B7EC4"
w "E3698D7C46A739AE5BE2C49286" "BB54B7D78954ED526A83C3CDA2"
w "32298B5E785DC394467D5C9CB2" "5ED6AAD93E873EA628B6A4BC47"
w "B4AB985B34756C624C92DE5E97" "3EDD5BA2A68397C26CE837AD48"
w "9A6D9A5457BB6ACBC5E8D7D4A9" "73E658CE2C3E289B837422D463"
w "96E64D226BC8B7D6C5974BAE32" "58DC7A8C543E35978AEBA34D29"
w "C2978A35E74D7652BA9762C458" "9A9BB332BE8C8DD44CE3DE66A5"
w "BEDB44E947693CD284923CEA82" "8CC3B75756255A683A6AB9E7DD"
w "EEDDCCBBAA8877665544332299" "EEDDCCBBAA9988776655443322"
w "EEDDCCBBAA9988776655443322" "DDCCBBAA9988776655443E3E22"

Haskell es rápido ... :)

real    0m0.039s
user    0m0.022s
sys     0m0.005s
Zylviij
fuente