หินกระดาษกรรไกรจิ้งจกสป็อคทัวร์นาเมนต์


13

การให้ความท้าทายที่เกี่ยวข้องกับการอ้างอิงของ Star Trek หลังจากวันที่ 4 พฤษภาคมอาจจะขมวดคิ้วได้

คุณลุคอนาคินพัลพาทีนโยดาและฮันโซโลมีส่วนร่วมในการแข่งขันบ้าของร็อค, กระดาษ, กรรไกร, จิ้งจก, สป็อค

การจับที่นี่คือคุณได้รับอนุญาตให้ใช้ลำดับการเคลื่อนที่ที่แน่นอนเท่านั้น หากคำสั่งซื้อของคุณคือ "R" คุณต้องใช้ Rock จนกว่าคุณจะแพ้หรือชนะกับทุกคน หากคำสั่งซื้อของคุณคือ RRV คุณต้องใช้ 2 Rocks ตามด้วย Spock และทำซ้ำจนกว่าคุณจะชนะหรือแพ้

Luke, Anakin, Palpatine, Yoda และ Han Solo ได้ส่งคำสั่งซื้อตามลำดับและคุณเป็นแฮ็กเกอร์มืออาชีพที่ได้รับคำสั่งจากคุณในแต่ละครั้ง!

ด้วยความรู้นี้คุณจะต้องออกแบบการสั่งซื้อสำหรับการแข่งขัน เนื่องจากทุกคนต้องการที่จะชนะคุณต้องการสร้างการสั่งซื้อแบบที่คุณชนะการแข่งขันโดยการตีทุกคน แต่สิ่งนี้อาจเป็นไปไม่ได้ในทุกสถานการณ์

ในกรณีที่มีคำสั่งซื้อที่เป็นไปได้ให้พิมพ์ออกมา หากไม่มีทางเป็นไปได้ที่คุณจะชนะให้พิมพ์ -1 (หรือ 0 หรือเท็จหรือ "เป็นไปไม่ได้")

ป้อนข้อมูล : รายการ 5 คำสั่งซื้อ

ผลลัพธ์ : คำสั่งเดียวหรือ -1

ตัวอย่างอินพุต 1

R
P
S
L
V

ตัวอย่างผลลัพธ์ 1

-1

คำอธิบาย 1

ไม่ว่าคุณจะเล่นอะไรในการย้ายครั้งแรกจะมีอย่างน้อยหนึ่งคนที่ชนะคุณดังนั้นจึงเป็นไปไม่ได้ที่คุณจะชนะ

ตัวอย่างอินพุต 2

RPS
RPP
R
SRR
L

ตัวอย่างผลลัพธ์ 2

RPSP

คำอธิบาย 2

เมื่อคุณเล่นร็อคในการย้ายครั้งแรกของคุณคุณจะเต้น "L" และ "SRR" และผูกกับส่วนที่เหลือ นี่เป็นเพราะ Lizard and Scissors พ่ายแพ้ต่อ Rock เมื่อคุณเล่น Paper ถัดไปคุณจะชนะ "R" และผูกกับ 2 ที่เหลือเนื่องจาก Rock สูญเสียกระดาษ เมื่อคุณเล่นกรรไกรต่อไปคุณจะชนะกับ "RPP" ในฐานะ Scissor beats Paper

ในที่สุดคุณจะเอาชนะ "RPS" ด้วยกระดาษของคุณเป็นกระดาษเต้นร็อค

นี่คือรายการของสัญลักษณ์ (คุณสามารถใช้ 5 ตัวอักษรใดก็ได้ แต่โปรดระบุในคำตอบของคุณ):

R : Rock
P : Paper
S : Scissor
L : Lizard
V : Spock

นี่คือรายการของผลลัพธ์ที่เป็นไปได้ทั้งหมด:

winner('S', 'P') -> 'S'
winner('S', 'R') -> 'R'
winner('S', 'V') -> 'V'
winner('S', 'L') -> 'S'
winner('S', 'S') -> Tie
winner('P', 'R') -> 'P'
winner('P', 'V') -> 'P'
winner('P', 'L') -> 'L'
winner('P', 'S') -> 'S'
winner('P', 'P') -> Tie
winner('R', 'V') -> 'V'
winner('R', 'L') -> 'R'
winner('R', 'S') -> 'R'
winner('R', 'P') -> 'P'
winner('R', 'R') -> Tie
winner('L', 'R') -> 'R'
winner('L', 'V') -> 'L'
winner('L', 'S') -> 'S'
winner('L', 'P') -> 'L'
winner('L', 'L') -> Tie
winner('V', 'R') -> 'V'
winner('V', 'L') -> 'L'
winner('V', 'S') -> 'V'
winner('V', 'P') -> 'P'
winner('V', 'V') -> Tie

นี่คือซึ่งมีจำนวนน้อยที่สุดที่ไบต์จะชนะ

PS: แจ้งให้เราทราบหากคุณต้องการกรณีทดสอบเพิ่มเติม


4
โปรดเปลี่ยน "Star Trek " เป็น "Star Wars " ในช่วงแนะนำของคุณ;)
movatica

1
นี่เป็นปัญหาที่ค่อนข้างยาก ดีหรือฉันไม่ดีในการเขียนโปรแกรมประเภทนี้
CrabMan

@ CrabMan นี่เป็นปัญหาที่ยากสำหรับกอล์ฟ โดยเฉพาะอย่างยิ่งในภาษาที่ใช้งานได้จริง
Koishore Roy

1
หลายงาน แต่มีอยู่ในทฤษฏีกลยุทธ์ที่ไม่มีที่สิ้นสุดดังนั้นโปรดระลึกไว้เสมอ
Koishore Roy

คำตอบ:


2

เยลลี่ 29 ไบต์

_%5ḟ0ḢḂ¬
ṁ€ZLḤƊçþ`Ạ€Tị;‘%5Ɗ$€

ลิงก์ monadic ที่รับรายการของจำนวนเต็ม (แต่ละอันคือกลยุทธ์ของคู่ต่อสู้) ซึ่งให้รายการของรายการจำนวนเต็ม - ซึ่งแต่ละรายการเป็นกลยุทธ์ที่ชนะ (เป็นรายการที่ว่างเปล่าหากไม่มีความเป็นไปได้)
(เพียงเพิ่มเพื่อให้รายการกลยุทธ์เดียวหรือ0หากเป็นไปไม่ได้)

ลองออนไลน์! (รูปแบบส่วนท้ายเพื่อแสดงรายการเสมอ)

Rock  Paper  Scissors  Spock  Lizard
0     1      2         3      4

หรือลองใช้ตัวอักษรแมปรุ่น (ที่จะถูกนำกลยุทธ์และการแสดงบนเส้นของตนเองโดยใช้RPSVLสัญกรณ์)

อย่างไร?

ตัวเลขจะถูกเลือกโดยที่หมายเลขใด ๆ ที่เป็นเลขคี่มากกว่าโมดูโลแบบอื่นห้าชนะ

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

_%5ḟ0ḢḂ¬ - Link 1, does B survive?: list A, list B (A & B of equal lengths)
                              e.g. RPSR vs RPVL ->  [0,1,2,0], [0,1,3,4]
_        - subtract (vectorises)                    [0,0,-1,-4]
 %5      - modulo five (vectorises)                 [0,0,4,1]   ...if all zeros:
   ḟ0    - filter discard zeros (ties)              [4,1]                       []
     Ḣ   - head (zero if an empty list)             4                           0
      Ḃ  - modulo two                               0                           0
       ¬ - logical NOT                              1                           1

ṁ€ZLḤƊçþ`Ạ€Tị;‘%5Ɗ$€ - Main Link: list of lists of integers
ṁ€                   - mould each list like:
     Ɗ               -   last three links as a monad
  Z                  -     transpose
   L                 -     length
    Ḥ                -     double  (i.e. 2 * throws in longest strategy)
        `            - use left as both arguments of:
       þ             -   table using:
      ç              -     last Link (1) as a dyad
         Ạ€          - all for each (1 if survives against all others, else 0)
           T         - truthy indices
            ị        - index into the input strategies
                  $€ - last two links as a monad for each:
             ;       -   concatenate with:
                 Ɗ   -     last three links as a monad:
              ‘      -       increment (vectorises)
               %5    -       modulo five (vectorises)

ผมใหม่ที่สมบูรณ์แบบให้กับวุ้น แต่ดูเหมือนว่าคุณสามารถได้รับไบต์โดยการแทนที่โดยZLḤ
Robin Ryder

@RobinRyder มันใช้งานไม่ได้ - มันใช้งานได้กับข้อมูลตัวอย่างเท่านั้นเพราะมีคู่ต่อสู้มากพอและมีการทุ่มน้อย - นี่คือตัวอย่างของเกมที่ไม่สามารถใช้งานได้ เราจำเป็นต้องวิเคราะห์การขว้างเป็นจำนวนมากเป็นสองเท่าของกลยุทธ์คู่ต่อสู้ที่ยาวที่สุด (รหัสของคุณเทียบเท่ากับสิ่งนี้จริง ๆ)
Jonathan Allan

... จริง ๆ แล้วเนื่องจากการกระทำƊในรหัสของคุณมันไม่ได้ทำสิ่งที่คุณอาจคิด - มันปั้นกันเหมือนความยาวของตัวเองแล้วได้รับผลรวมสะสมของผลลัพธ์เหล่านั้นดังนั้นจะเปรียบเทียบค่าที่ไม่ถูกต้องเช่นกัน ลองนี้เช่น - มันจะใช้เวลาใน[[1,2,3,4,5],[6,7],[8]]แม่พิมพ์แต่ละโดยความยาวของรายการทั้งหมด (3) ที่จะได้รับ[[1,2,3],[6,7,6],[8,8,8]]แล้วดำเนินการที่จะได้รับการสะสม=[[1,1+2,1+2+3],[6,6+7,6+7+8],[8,8+8,8+8+8]] [[1,3,6],[6,13,19],[8,16,24]]
Jonathan Allan

อ่าใช่ฉันรู้ว่าฉันเข้าใจผิดบางอย่าง!
Robin Ryder

7

JavaScript (ES6),  122 115  112 ไบต์

รับอินพุตเป็นอาร์เรย์ของสตริงของตัวเลขโดย:

  • 0
  • 1
  • 2
  • 3
  • 4

false

f=(a,m='',x=0,o,b=a.filter(a=>(y=a[m.length%a.length])-x?o|=y-x&1^x<y:1))=>b+b?x<4&&f(a,m,x+1)||!o&&f(b,m+x):m+x

ลองออนไลน์!

อย่างไร?

นี่เป็นการค้นหาแบบกว้างก่อนอื่นเราจะลองทำทุกขั้นตอนเพื่อดูว่าเราสามารถชนะได้หรือไม่ หากเราไม่สามารถชนะได้ในตอนนี้เราพยายามที่จะเพิ่มการเคลื่อนไหวอีกครั้งในการเคลื่อนไหวที่ไม่แพ้

AB(BA)mod5

ด้วยทางด้านซ้ายและด้านบน:AB

(S)(P)(R)(L)(V)01234(S) 01234(P) 14123(R) 23412(L) 32341(V) 41234

จากตรงนั้นเราสามารถอนุมานอีกวิธีหนึ่งในการทดสอบว่าชนะต่อสำหรับ :ABAB

((A - B) and 1) xor (B < A)

ที่ไหนandและxorเป็นผู้ประกอบการระดับบิต

แสดงความคิดเห็น

f = (                        // f is a recursive function taking:
  a,                         //   a[] = input
  m = '',                    //   m   = string representing the list of moves
  x = 0,                     //   x   = next move to try (0 to 4)
  o,                         //   o   = flag set if we lose, initially undefined
  b =                        //   b[] = array of remaining opponents after the move x
    a.filter(s =>            //     for each entry s in a[]:
    ( y =                    //       define y as ...
      s[m.length % s.length] //         ... the next move of the current opponent
    ) - x                    //       subtract x from y
    ?                        //       if the difference is not equal to 0:
      o |=                   //         update o using the formula described above:
        y - x & 1 ^ x < y    //           set it to 1 if we lose; opponents are removed
                             //           while o = 0, and kept as soon as o = 1
    :                        //       else (this is a draw):
      1                      //         keep this opponent, but leave o unchanged
  )                          //     end of filter()
) =>                         //
  b + b ?                    // if b[] is not empty:
    x < 4 &&                 //   if x is less than 4:
      f(a, m, x + 1)         //     do a recursive call with x + 1 (going breadth-first)
    ||                       //   if this fails:
      !o &&                  //     if o is not set:
        f(b, m + x)          //       keep this move and do a recursive call with b[]
  :                          // else (success):
    m + x                    //   return m + x

รหัสของคุณล้มเหลวสำหรับกรณีทดสอบ: test(['P','P','S','P','P']) คำตอบควรเป็น "SR" หรือ "SV"
Koishore Roy

@KoishoreRoy แก้ไขแล้ว
Arnauld

1
นี่เป็นวิธีการที่ยอดเยี่ยมจริงๆ ฉันไม่คิดแม้แต่จะคิดว่ามันเป็นกราฟ ฉันใช้พจนานุกรมและค้นหาแบบย้อนกลับในวิธีดั้งเดิมที่ไม่ได้รับการดูแลของฉัน (โดยไม่มีสป็อคหรือกิ้งก่า)
Koishore Roy

3

R , 213 190 ไบต์

-23 ไบต์ขอบคุณ Giuseppe

function(L){m=matrix(rep(0:2,1:3),5,5)
m[1,4]=m[2,5]=1
v=combn(rep(1:5,n),n<-sum(lengths(L)))
v[,which(apply(v,2,function(z)all(sapply(L,function(x,y,r=m[cbind(x,y)])r[r>0][1]<2,z)))>0)[1]]}

ลองออนไลน์!

หากวิธีการแก้ปัญหาที่มีอยู่มันจะส่งออกหนึ่ง NAหากมีวิธีการแก้ปัญหาไม่มีมันจะออกผลลัพธ์แถวของ หากรูปแบบผลลัพธ์นี้ไม่เป็นที่ยอมรับฉันสามารถเปลี่ยนค่าใช้จ่ายได้ไม่กี่ไบต์

การเคลื่อนไหวจะถูกเขียนเป็น 1 = R, 2 = S, 3 = P, 4 = L, 5 = V ดังนั้นเมทริกซ์ของผลลัพธ์คือ

     [,1] [,2] [,3] [,4] [,5]
[1,]    0    2    2    1    1
[2,]    1    0    2    2    1
[3,]    1    1    0    2    2
[4,]    2    1    1    0    2
[5,]    2    2    1    1    0

(0 = ไม่มีผู้ชนะ 1 = ผู้เล่น 1 ชนะ 2 = ผู้เล่น 2 ชนะ)

ขอบเขตบนของความยาวของการแก้ปัญหาถ้ามันมีอยู่n=sum(lengths(L))ที่Lรายการเคลื่อนไหวของฝ่ายตรงข้าม รหัสสร้างกลยุทธ์ที่เป็นไปได้ทั้งหมดของความยาวn(เก็บไว้ในเมทริกซ์v) ลองทั้งหมดของพวกเขาและแสดงกลยุทธ์ที่ชนะทั้งหมด

โปรดทราบว่าค่านี้nทำให้โค้ดช้ามากบน TIO ดังนั้นฉันจึงฮาร์ดโค้ดใน TIO n=4ซึ่งเพียงพอสำหรับกรณีทดสอบ

สำหรับกรณีทดสอบครั้งแรกผลลัพธ์คือ

     1 4 2 4

สอดคล้องกับโซลูชัน RLSL

สำหรับกรณีทดสอบที่สองผลลัพธ์คือ

 NA NA NA NA

หมายความว่าไม่มีวิธีแก้ปัญหา

คำอธิบายของรุ่นก่อนหน้า (จะอัปเดตเมื่อฉันสามารถ):

function(L){
  m = matrix(rep(0:2,1:3),5,5);
  m[1,4]=m[2,5]=1                      # create matrix of outcomes
  v=as.matrix(expand.grid(replicate(   # all possible strategies of length n
    n<-sum(lengths(L))                 # where n is the upper bound on solution length
    ,1:5,F)))             
  v[which(    
    apply(v,1,                         # for each strategy
          function(z)                  # check whether it wins
            all(                       # against all opponents
              sapply(L,function(x,y){  # function to simulate one game
                r=m[cbind(x,y)];       # vector of pair-wise outcomes
                r[r>0][1]<2            # keep the first non-draw outcome, and verify that it is a win
              }
              ,z)))
    >0),]                              # keep only winning strategies
}

whichมีความจำเป็นต้องได้รับการกำจัดของ NAS ซึ่งเกิดขึ้นเมื่อผู้เล่นทั้งสองวาดตลอดไป

ฉันไม่เชื่อว่านี่เป็นกลยุทธ์ที่มีประสิทธิภาพที่สุด แม้ว่าจะเป็นเช่นนั้นฉันก็มั่นใจว่ารหัสสำหรับmกอล์ฟนั้นอาจจะค่อนข้างน้อย


ทำไมlengths()aliased เสมอกลับมา4?
Giuseppe

1
อย่างไรก็ตามในขณะที่ฉันรอการตอบสนองของคุณฉันกอล์ฟลงไปที่197ส่วนใหญ่โดยมุ่งเน้นที่v...
Giuseppe

@Giuseppe ฉันใช้นามแฝงlengthsเพื่อบังคับใช้n=4TIO เพราะไม่เช่นนั้นจะใช้เวลานานเกินไปกว่ากลยุทธ์ ( ) ทั้งหมด n = 115nn=11
Robin Ryder

อารู้สึกเข้าท่าน่าจะรู้แล้ว 187 bytes
Giuseppe

@iuseppe ขอบคุณการเล่นกอล์ฟที่น่าประทับใจ! ฉันเพิ่ม 3 ไบต์เพื่อให้เอาต์พุตอ่านได้ง่ายขึ้น (ไม่เช่นนั้นเราจะจบลงด้วยวิธีแก้ปัญหาเดียวกันที่พิมพ์ออกมาหลายครั้ง)
Robin Ryder

0

Emacs Lisp, 730 ไบต์

(require 'cl-extra)
(require 'seq)
(defun N (g) (length (nth 1 g)))
(defun M (g) (mapcar (lambda (o) (nth (% (N g) (length o)) o)) (car g)))
(defun B (x y) (or (eq (% (1+ x) 5) y) (eq (% (+ y 2) 5) x)))
(defun S (g) (seq-filter (lambda (m) (not (seq-some (lambda (v) (B v m)) (M g)))) '(0 1 2 3 4)))
(defun F (g) (cond ((null (car g)) (reverse (nth 1 g))) ((null (S g)) nil) ((>= (nth 3 g) (seq-reduce (lambda (x y) (calc-eval "lcm($,$$)" 'raw x y)) (mapcar 'length (car g)) 1)) nil) (t (cl-some (lambda (m) (F   (let ((r (seq-filter 'identity (mapcar* (lambda (v o) (and (not (B m v)) o)) (M g) (car g))))) (list r (cons m (nth 1 g)) (1+ (N g)) (if (eq (car g) r) (1+ (nth 3 g)) 0))))) (S g)))))
(defun Z (s) (F (list s () 0 0)))

ฉันไม่พบล่ามออนไลน์ของ Emacs Lisp :( หากคุณติดตั้ง Emacs คุณสามารถคัดลอกโค้ดลงใน.elไฟล์คัดลอกบรรทัดทดสอบด้านล่าง

;; 0 = rock, 1 = lizard; 2 = spock;
;; 3 = scissors; 4 = paper
(print (Z '((0) (1) (2) (3) (4))))
; output: nil
(print (Z '((0) (4) (3) (1))))
; output: nil
(print (Z '((0 4 3) (0 4 4) (0) (3 0 0) (1))))
; output: (0 4 3 0 1)
(print (Z '((4) (4) (3) (4) (4))))
; output: (3 0)
(print (Z '((4 3 2 1 0) (2 1 0 4 3))))
; output: (1)
(print (Z '((2) (2) (3) (0) (2) (3) (0) (0))))
; output: (2 1)
(print (Z '((2) (2 0) (3) (0) (2 1) (3) (0) (0))))
; output: nil

$ emacs --script filename.elและเรียกใช้

มันทำงานอย่างไร

โปรแกรมของฉันทำการค้นหาในเชิงลึกก่อนด้วยบางครั้งการหาว่ามันเป็นไปไม่ได้ที่จะชนะและยกเลิกสาขาที่เปิดอยู่

คุณสามารถดูคำอธิบายแบบเต็มในรหัสรุ่นที่ไม่ได้ย่อ:

(require 'seq)
(require 'cl-extra)

;; This program does depth first search with sometimes figuring out
;; that it's impossible to win and terminating the branch it's on.
;;

;; A move is a number from 0 to 4. 
;; https://d3qdvvkm3r2z1i.cloudfront.net/media/catalog/product/cache/1/image/1800x/6b9ffbf72458f4fd2d3cb995d92e8889/r/o/rockpaperscissorslizardspock_newthumb.png
;; this is a nice visualization of what beats what.
;; Rock = 0, lizard = 1, spock = 2, scissors = 3, paper = 4.

(defun beats (x y) "Calculates whether move x beats move y"
  (or (eq (% (1+ x) 5) y)
      (eq (% (+ y 2) 5) x)))

;; A gamestate is a list with the following elements:
(defun get-orders (gamestate)
  "A list of orders of players who haven't lost yet. Each order is a list of moves.
For example, ((2) (2 0) (3) (0) (2 1) (3) (0) (0)) is a valid orders list.
This function gets orders from the gamestate."
  (car gamestate))

;; At index 1 of the gamestate lies a list of all moves we have made so far in reverse order
;; (because lists are singly linked, we can't push back quickly)
(defun get-num-moves-done (gamestate)
  "Returns the number of moves the player has done so far"
  (length (nth 1 gamestate)))

(defun get-rounds-since-last-elim (gamestate)
  "The last element of a gamestate is the number of rounds passed since an opponent
was eliminated. We use this to determine if it's possible to win from current
gamestate (more about it later)."
  (nth 2 gamestate))

;; next go some utility functions
;; you can skip their descriptions, they are not very interesting
;; I suggest you skip until the next ;; comment

(defun get-next-move (order num-rounds-done)
  "Arguments: an order (e.g. (1 0 1)); how many rounds have passed total.
Returns the move this opponent will make next"
  (nth (% num-rounds-done (length order)) order))

(defun moves-of-opponents-this-round (gamestate)
  "Returns a list of moves the opponents will make next"
  (mapcar (lambda (order) (get-next-move order (get-num-moves-done gamestate)))
          (get-orders gamestate)))

(defun is-non-losing (move opponents-moves)
  "Calculates if we lose right away by playing move against opponents-moves"
  (not (seq-some (lambda (opponent-move) (beats opponent-move move))
                 opponents-moves)))

(defun non-losing-moves (gamestate)
  "Returns a list of moves which we can play without losing right away."
  (seq-filter
   (lambda (move) (is-non-losing move (moves-of-opponents-this-round gamestate)))
   '(0 1 2 3 4)))

(defun advance-gamestate (gamestate move)
  "If this move in this gamestate is non-losing, returns the next game state"
  (let ((new-orders (seq-filter
                    'identity (mapcar* (lambda (opp-move order)
                                         (and (not (beats move opp-move)) order))
                                       (moves-of-opponents-this-round gamestate)
                                       (get-orders gamestate)))))
  (list new-orders
        (cons move (nth 1 gamestate))
        (if (eq (get-orders gamestate) new-orders) (1+ (get-rounds-since-last-elim gamestate)) 0))))

;; How do we prevent our depth first search from continuing without halting?
;; Suppose 3 players (except us) are still in the game and they have orders of lengths a, b, c
;; In this situation, if least_common_multiple(a, b, c) rounds pass without an elimination
;; we will be in the same situation (because they will be playing the same moves they played
;; lcm(a, b, c) rounds ago)
;; Therefore, if it's possible to win from this gamestate,
;; then it's possible to win from that earlier game state,
;; hence we can stop exploring this branch

(defun get-cycle-len (gamestate)
  "Returns a number of rounds which is enough for the situation to become the same
if the game goes this long without an elimination."
  (seq-reduce (lambda (x y) (calc-eval "lcm($,$$)" 'raw x y))
              (mapcar 'length (get-orders gamestate)) 1))

(defun unwinnable-cycle (gamestate)
  "Using the aforementioned information, returns t if we are in such a
suboptimal course of play."
  (>= (get-rounds-since-last-elim gamestate) (get-cycle-len gamestate)))

(defun find-good-moves (gamestate)
  "Given gamestate, if it's possible to win
returns a list of moves, containing all moves already done + additional moves which lead to win.
Otherwise returns nil"
  (cond ((null (get-orders gamestate)) ; if no opponents left, we won, return the list of moves
         (reverse (nth 1 gamestate)))
        ((null (non-losing-moves gamestate)) ; if no non-losing moves available, this gamestate
         nil) ; doesn't lead to a win, return nil
        ((unwinnable-cycle gamestate) ; either it's impossible to win, or
         nil) ; it's possible to win from an earlier position, return nil
        (t (cl-some (lambda (move) ; otherwise return the first non-losing move which leads
                      (find-good-moves (advance-gamestate gamestate move))) ; to a non-nil result
                    (non-losing-moves gamestate)))))

(defun make-initial-gamestate (orders)
  "Given an orders list, create initial gamestate"
  (list orders () 0))

1
tio.run/##S81NTC7WzcksLvgPBAA คุณสามารถแทรกรหัสของคุณได้ที่นี่และลองเรียกใช้หรือไม่
Koishore Roy

@ KoishoreRoy ฉันลอง tio.run แล้วและฉันไม่สามารถหาสาเหตุได้ว่าทำไมมันถึงไม่ทำงาน มีข้อความระบุว่า "การติดตามขยะตามการแสดงออก" และฉันไม่รู้ว่านั่นคืออะไรและ 5 นาทีของ Google ไม่ได้ช่วยฉันแก้ไข
CrabMan
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.