กำหนดผู้ชนะของเกมแห่งสงคราม


19

เกมไพ่สงครามเป็นที่น่าสนใจว่าผลลัพธ์สุดท้ายจะถูกกำหนดโดยการเริ่มต้นของเด็คตราบใดที่กฎบางอย่างมีการปฏิบัติตามลำดับที่ไพ่ถูกหยิบขึ้นมาจากสนามเด็กเล่นและย้ายไปที่เด็ค ในความท้าทายนี้จะมีผู้เล่นเพียง 2 คนทำให้สิ่งต่าง ๆ ง่ายขึ้นอย่างมาก

เกม

  1. ผู้เล่นแต่ละคนจะได้รับไพ่ 26 ใบ
  2. ผู้เล่นแต่ละคนวางไพ่บนสุดในหน้าหงายหน้า ผู้เล่นที่มีไพ่อันดับสูงกว่า ( Ace > King > Queen > Jack > 10 > 9 > 8 > 7 > 6 > 5 > 4 > 3 > 2) ชนะรอบและวางไพ่ไว้ที่ด้านบนของการ์ดของคู่ต่อสู้พลิกพวกเขาและเพิ่มพวกเขาที่ด้านล่างของสำรับ (ดังนั้นไพ่ที่ชนะจะอยู่ที่ด้านล่างของสำรับ และการ์ดที่แพ้ของผู้เล่นคนอื่นจะอยู่เหนือการ์ดนั้น) สิ่งนี้จะทำจนกว่าผู้เล่นคนหนึ่งจะหมดไพ่
    • หากไพ่อยู่ในอันดับที่เท่ากันผู้เล่นแต่ละคนจะวางไพ่ 2 ใบบนสุดของไพ่หงายหน้าขึ้นด้านบนของไพ่ใบที่แล้ว (เพื่อให้ไพ่ที่อยู่ด้านบนของสำรับเป็นไพ่ใบที่สองในกองซ้อนและ การ์ดที่ถูกรองจากด้านบนอยู่ด้านบน) จากนั้นอันดับ (ของการ์ดอันดับสูงสุดของแต่ละสแต็ค) จะถูกนำมาเปรียบเทียบอีกครั้งและผู้ชนะจะวางสแต็คทั้งหมดไว้ที่ด้านบนของสแต็กทั้งหมดของผู้แพ้เปลี่ยนสแต็กคว่ำลงและวางไว้ที่ด้านล่าง หากมีการเสมอกันจะมีการเล่นไพ่เพิ่มในลักษณะเดียวกันจนกว่าจะมีการเลือกผู้ชนะหรือผู้เล่นคนหนึ่งหมดไพ่

หาก ณ จุดใดจุดหนึ่งผู้เล่นจำเป็นต้องจั่วไพ่จากเด็คของตน แต่เด็คว่างเปล่าพวกเขาแพ้เกมทันที

ความท้าทาย

รับไพ่สองใบในเด็คของผู้เล่นในรูปแบบที่สะดวกใด ๆ เอาท์พุทค่าความจริงหากผู้เล่น 1 ชนะและมูลค่าที่ไม่ถูกต้องหากผู้เล่น 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)


1
สำหรับไพ่สำรับ1, 2, 3เกมไม่มีที่สิ้นสุดในขณะที่คุณชนะคู่ต่อสู้ของ1คุณ นั่นเป็นเรื่องแปลกที่มีจำนวนไพ่แปลก ๆ ไหม?
Neil

@Neil การ์ดสำรับใดบ้างที่มี1?
Suever

@Suever ขออภัยฉันไม่ได้คิดหนักเกินไปฉันเพิ่งเลือกตัวเลขสามตัวแรกที่เข้ามาในหัวของฉัน เพียงแค่เลือกไพ่สามใบที่ไพ่ใบแรกสุดต่ำที่สุด
Neil

@ 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
Chuck Morris

@ChuckMorris ขออภัยที่ฉันมองข้ามหนึ่งในกฎ ควรได้รับการแก้ไขแล้ว
Neil

@Mego ลองอีกครั้งฉันเพิ่งจะอัพเดท
Neil

ทุกอย่างดูเหมือนจะเช็คเอาท์ตอนนี้
Mego

ตกลงตอนนี้ฉันประทับใจ!
Chuck Morris

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])

เนื่องจากIronPythonจะเรียกใช้การแก้ปัญหาแรกได้ดี (ความลึกการเรียกซ้ำเริ่มต้นไม่ จำกัด ) ฉันจะบอกว่าวิธีแก้ปัญหาแรกนั้นใช้ได้
Mego

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 โดยแทนที่ช่องว่างด้วยแท็บเดียวในขณะวนซ้ำ

ลองออนไลน์


2

Haskell, 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"

Haskell เร็วมาก ... :)

real    0m0.039s
user    0m0.022s
sys     0m0.005s
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.