রক, পেপার, কাঁচি, টিকটিকি, স্পক টুর্নামেন্ট


13

4 মে এর ঠিক পরে স্টার ট্র্যাকের রেফারেন্স জড়িত একটি চ্যালেঞ্জ ভ্রূণু হতে পারে, কিন্তু এখানে রয়েছে।

আপনি, লুক, আনাকিন, প্যালপাটিন, যোদা এবং হ্যান সলো রক, পেপার, সিজার, টিকটিকি, স্পকের একটি উন্মাদ টুর্নামেন্টে অংশ নিয়েছেন।

এখানে ধরাটি হ'ল আপনাকে কেবল স্থির স্থির ক্রম ব্যবহারের অনুমতি দেওয়া হয়েছে। যদি আপনার অর্ডারটি "আর" হয়, তবে আপনাকে রক ব্যবহার করতে হবে, যতক্ষণ না আপনি হেরে বা সবার বিপক্ষে জয়ী হন। যদি আপনার অর্ডারটি আরআরভি হয়, তবে আপনাকে 2 টি রকস ব্যবহার করতে হবে তারপরে একটি স্পক এবং আপনি জেতা বা হারা না হওয়া পর্যন্ত পুনরাবৃত্তি চালিয়ে যেতে হবে।

লুক, আনাকিন, প্যালপাটিন, যোদা এবং হ্যান সলো তাদের নিজ নিজ অর্ডারগুলি জমা দিয়েছে এবং আপনি বিশেষজ্ঞ হ্যাকার হয়ে তাদের প্রতিটি অর্ডারে হাত পেয়েছেন!

এই জ্ঞান সহ, আপনি টুর্নামেন্টের জন্য আপনার ক্রমটি ডিজাইন করতে পারেন। যেহেতু সবাই জিততে চায়, আপনি এমন একটি অর্ডার তৈরি করতে চান যাতে আপনি সবাইকে হারিয়ে টুর্নামেন্টটি জিতেন। তবে এটি সব পরিস্থিতিতে সম্ভব নাও হতে পারে।

সম্ভাব্য বিজয়ী অর্ডার রয়েছে তবে তা মুদ্রণ করুন। আপনার জয়ের কোনও সম্ভাব্য উপায় না থাকলে, -1 (বা 0 বা মিথ্যা বা "অসম্ভব") মুদ্রণ করুন

ইনপুট : 5 টি আদেশের একটি তালিকা

আউটপুট : একটি একক আদেশ বা -1

নমুনা ইনপুট 1

R
P
S
L
V

নমুনা আউটপুট 1

-1

ব্যাখ্যা ঘ

আপনার প্রথম পদক্ষেপে আপনি যা খেলেন না কেন, কমপক্ষে একজন ব্যক্তি আপনাকে মারবে, সুতরাং আপনার পক্ষে জয় পাওয়া সম্ভব নয়।

নমুনা ইনপুট 2

RPS
RPP
R
SRR
L

নমুনা আউটপুট 2

RPSP

ব্যাখ্যা ২

আপনার প্রথম চালনায় একবার রক খেললে আপনি "এল" এবং "এসআরআর" কে পিটিয়ে শেষের দিকে বেঁধে দেন। কারণ টিকটিকি এবং কাঁচি রকের কাছে হেরে যায়। আপনি যখন পেপারটি খেলবেন, আপনি "আর" কে পরাজিত করবেন এবং বাকী ২ টির সাথে টাই করবেন কারণ এটি রক পেপারের কাছে হেরে গেছে। আপনি যখন পরবর্তী কাঁচি খেলেন, আপনি "আরপিপি" এর বিপরীতে স্কাইজারকে পেপার বিট হিসাবে জয়ী করবেন।

শেষ পর্যন্ত, আপনি কাগজটি রককে প্রহার হিসাবে আপনার কাগজ দিয়ে "আরপিএস" কে পরাজিত করবেন।

এখানে স্বরলিপিগুলির একটি তালিকা রয়েছে (আপনি কোনও 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

এটি , তাই খুব কম বাইট জিতেছে।

পিএস: আপনার আরও পরীক্ষার কেস দরকার হলে আমাকে জানান।


4
দয়া করে আপনার
স্ট্রোকটিতে

1
এটি একটি বেশ কঠিন সমস্যা। ভাল, বা আমি এই ধরনের প্রোগ্রামিং এ খারাপ।
ক্র্যাবম্যান

@ ক্র্যাবম্যান এটি গল্ফের জন্য কিছুটা কঠিন সমস্যা। বিশেষত ব্যবহারিক ভাষায়।
কুইশোর রায়

1
বেশ কয়েকটি কাজ, তবে তত্ত্বে রয়েছে অসীম বিজয়ী কৌশল, তাই এটি মনে রাখবেন
কোয়েশোর রায়

1
সম্পর্কিত , এবং একটি KOTH (সিসি: @ আর্নল্ড)
ডিএলকস

উত্তর:


2

জেলি , 29 বাইট

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

একটি মোনাডিক লিঙ্ক যা পূর্ণসংখ্যার তালিকার একটি তালিকা গ্রহণ করে (যার প্রত্যেকটি প্রতিপক্ষের কৌশল which
(কেবলমাত্র একটি একক কৌশল তালিকার যোগ করতে বা 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Ḥকরে একটি বাইট অর্জন করতে পারেন
রবিন রাইডার

@ রবিনরাইডার এটি কাজ করবে না - এটি কেবল উদাহরণের ডেটা নিয়ে কাজ করছে কারণ সেখানে যথেষ্ট বিরোধী এবং যথেষ্ট পরিমাণ নিক্ষেপ রয়েছে - এটি কাজ করবে না এমন একটি উদাহরণ । দীর্ঘতম প্রতিপক্ষ কৌশল হিসাবে আমাদের দ্বিগুণ ছোঁড়া বিশ্লেষণ করতে হবে। (আপনার কোড আসলে সমতূল্য এই )
জোনাথন অ্যালান

... আসলে Ɗআপনার কোডের ক্রিয়াটির কারণে এটি এমনকি আপনি যা ভাবেন সেগুলি করছেন না - এটি নিজের দৈর্ঘ্যের মতো প্রতিটি ছাঁচনির্মাণ করে সেই ফলাফলগুলির সংশ্লেষক অঙ্কগুলি পেয়েছে, তাই ভুল মানগুলিরও তুলনা করবে। উদাহরণস্বরূপ এটি ব্যবহার করে দেখুন - এটি [[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]]
জোনাথন অ্যালান

হ্যাঁ হ্যাঁ, আমি জানতাম আমি কিছু ভুল বুঝছিলাম!
রবিন রাইডার

7

জাভাস্ক্রিপ্ট (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']) উত্তরটি "এসআর" বা "এসভি" হওয়া উচিত।
কুইশোর রায়

পছন্দ করুন
আর্নল্ড

1
এটি আসলে একটি উজ্জ্বল পদ্ধতির। এমনকি এটিকে গ্রাফ হিসাবে বিবেচনা করার কথা ভাবিনি। আমি আমার অলগফুল্ড মূল পদ্ধতির (স্পক বা টিকটিকি ছাড়া) ব্যবহার করতে
চাইছিলাম

3

আর , 213 190 বাইট

-23 বাইট জিউসেপ্পিকে ধন্যবাদ জানায়।

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 = আর, 2 = এস, 3 = পি, 4 = এল, 5 = ভি হিসাবে কোড করা হয়, যাতে ফলাফলের ম্যাট্রিক্স হয়

     [,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টিআইও-তে কোডটি খুব ধীর করে তোলে তাই আমি টিআইওতে হার্ডকোড করেছি n=4যা পরীক্ষার ক্ষেত্রে যথেষ্ট।

প্রথম পরীক্ষার ক্ষেত্রে আউটপুট হয়

     1 4 2 4

সমাধানের সাথে সম্পর্কিত আরএলএসএল।

দ্বিতীয় পরীক্ষার ক্ষেত্রে আউটপুট হয়

 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দুই খেলোয়াড় চিরকালের জন্য ড্র করার সময় ঘটে যাওয়া এনএগুলি থেকে মুক্তি পাওয়ার প্রয়োজন The

আমি নিশ্চিত নই যে এটিই সবচেয়ে দক্ষ কৌশল। এটি যদি হয় mতবেও আমি নিশ্চিত যে এর কোডটি বেশ খানিকটা গল্ফ করা যেতে পারে।


lengths()সর্বদা ফিরতে এলিয়াস কেন 4?
: Giuseppe

1
যাইহোক, আমি যখন আপনার প্রতিক্রিয়াটির জন্য অপেক্ষা করছিলাম তখন আমি এটিকে 197 এ নিয়ে গল্ফড করেছিলাম , বেশিরভাগের দিকে মনোনিবেশ করে v...
জিউসেপে

@ জিউস্পেপ আমি টিআইওর উপর lengthsচাপ প্রয়োগ করতে পেরেছি n=4, কারণ অন্যথায় সমস্ত ( ) কৌশলগুলি অতিক্রম করতে খুব বেশি সময় লাগে । এন = 115nn=11
রবিন রাইডার

আহ, বোঝায়, জানা উচিত ছিল। 187 বাইট
জিউসেপ

@ জিউসেপ ধন্যবাদ, চিত্তাকর্ষক গল্ফিং! আউটপুটটিকে আরও পঠনযোগ্য করে তোলার জন্য আমি 3 বাইট যুক্ত করেছি (অন্যথায় আমরা একই সমাধানটি বহুবার মুদ্রিত করে শেষ করি)।
রবিন রাইডার

0

ইমাস লিস্প, 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)))

আমি ইমাস লিস্পের একটি অনলাইন দোভাষী খুঁজে পাইনি :( আপনি যদি ইমাস ইনস্টল করেন তবে আপনি কোনও .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 আপনি কি নিজের কোডটি এখানে sertোকাতে এবং চালানোর চেষ্টা করতে পারেন?
কুইশোর রায়

@ কাইশোররোয় আমি টিও.আরুন চেষ্টা করেছিলাম এবং কেন এটি চালাচ্ছে তা আমি বুঝতে পারি না। এটি "ট্রেলিং জঞ্জাল অনুসরণ করে" বলে এবং এটি কী তা আমার কোনও ধারণা নেই এবং 5 মিনিটের গুগল আমাকে এটি ঠিক করতে সহায়তা করে নি।
ক্র্যাবম্যান
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.