Определить победителя игры войны

19

Карточная игра War интересна тем, что окончательный результат полностью определяется первоначальным расположением колоды, если соблюдаются определенные правила для порядка, в котором карты поднимаются с игрового поля и перемещаются в колоды. В этом соревновании будет только 2 игрока, что значительно упростит ситуацию.

Игра

  1. Каждому игроку сдается колода из 26 карт.
  2. Каждый игрок кладет верхнюю карту в колоду лицом вверх. Игрок с картой более высокого ранга ( Ace > King > Queen > Jack > 10 > 9 > 8 > 7 > 6 > 5 > 4 > 3 > 2) выигрывает раунд и кладет свою карту поверх карты своего оппонента, переворачивает их и добавляет их в нижнюю часть своей колоды (поэтому их выигрышная карта находится в нижней части колоды) и проигрышная карта другого игрока чуть выше нее). Это делается до тех пор, пока у одного из игроков не закончатся карты.
    • Если карты равного ранга, то каждый игрок кладет верхние 2 карты своей колоды лицевой стороной вверх на свою предыдущую карту (так, чтобы карта, находящаяся сверху колоды, была второй картой в колоде, и карта, которая была второй сверху, сверху). Затем ранги (верхней карты каждой колоды) сравниваются снова, и победитель помещает весь свой стек поверх всей стопки проигравшего, переворачивает стопку вверх дном и помещает ее на дно своей колоды. Если есть еще одна ничья, больше карт разыгрывается таким же образом, пока не будет выбран победитель или у одного из игроков закончились карты.

Если в какой-то момент одному из игроков нужно взять карту из своей колоды, но их колода пуста, они немедленно проигрывают игру.

Соревнование

При наличии двух списков карт в колодах игроков в любом удобном формате выведите истинное значение, если выиграл Игрок 1, и значение Falsey, если Игрок 2 выиграл.

Для удобства 10 карт будут обозначены символом a T, а лицевые карты будут сокращены ( Ace -> A, King -> K, Queen -> Q, Jack -> J), поэтому все карты имеют длину одного символа. Альтернативно, ранги могут быть представлены десятичными целыми числами 2-14 ( Jack -> 11, Queen -> 12, King -> 13, Ace -> 14) или шестнадцатеричными цифрами 2-E ( 10 -> A, Jack -> B, Queen -> C, King -> D, Ace -> E). Поскольку иски не имеют значения, информация о иске не будет предоставлена.

  • Вы можете предположить, что все игры прекратятся в какой-то момент (хотя это может занять очень много времени), и у одного игрока всегда останутся карты раньше, чем у другого.
  • Каждый игрок кладет карты одновременно и по одной карте за раз, поэтому никогда не возникает двусмысленности относительно того, у кого из игроков закончились карты в первую очередь.

Тестовые случаи

Тестовые случаи используют 23456789ABCDEдля представления рангов (в порядке возрастания).

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

Реализация эталона

Эта эталонная реализация написана на Python 3 и принимает входные данные в том же формате, что и тестовые случаи (за исключением разделенных новой строкой вместо запятой и пробела).

#!/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
источник
2
Связанный
Bassdrop Cumberwubwubwub
1
Для колоды карт 1, 2, 3игра не имеет конца, так как вы продолжаете выигрывать у противника 1. Это причуды иметь нечетное количество карт?
Нил
@Neil Какая колода карт есть 1?
Suever
@Suever Извините, я не особо задумывался, я просто выбрал первые три разных числа, которые пришли мне в голову. Просто выберите любые три карты, где первая является самой низкой.
Нил
@Neil Просто даю тебе трудное время :) Точка занята!
Suever

Ответы:

3

JavaScript (ES6), 134 байта

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

Вернитесь, undefinedесли игрок 2 выиграет, в trueпротивном случае. Принимает сопоставимые итераторы, обычно массивы целых чисел или строки шестнадцатеричных символов. Ответ состоит из более чем 22% .персонажей, которые, я думаю, должны быть для меня рекордными.

Нил
источник
Кажется, я не получаю правильных результатов, когда пытаюсь сделать это с помощью контрольных примеров. См. Jsfiddle.net/xbq5xzco
Чак Моррис
@ChuckMorris Извините, я упустил одно из правил. Должно быть исправлено сейчас.
Нил
@Mego Попробуйте еще раз, я только что обновил его.
Нил
Кажется, сейчас все проверено.
Мего
Хорошо, теперь я впечатлен!
Чак Моррис
4

Python, 160 (155?) Байтов

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)

Это решение теоретически верно, но оно требует увеличения максимальной глубины рекурсии по умолчанию для некоторых тестовых случаев.

Второе решение на 5 байт длиннее, но работает для всех тестовых случаев.

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)

Редактировать: Ungolfed решение 1:

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
источник
Поскольку IronPython прекрасно выполнит первое решение (глубина рекурсии по умолчанию не ограничена), я скажу, что первое решение является действительным.
Мего
2

Python, от 261 до 265 байт

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)

Как сообщалось, это 265 байт, и он работает как в Python 2, так и в Python 3. Вы можете сохранить 4 байта в Python 2, заменив пробелы одной вкладкой в ​​цикле while.

Попробуйте онлайн

Чак Моррис
источник
2

Хаскелл, 372

Моя первая программа на Haskell

(Это тоже мое первое функциональное программирование ...)

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)

Я хотел бы получить советы о том, как улучшить.

Использование:

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"

Хаскель быстр ... :)

real    0m0.039s
user    0m0.022s
sys     0m0.005s
Zylviij
источник