স্ট্রিং কনস্ট্রাকশন গেমের জন্য জয়ী কৌশল


14

পটভূমি

অ্যালিস এবং বব একটি বাইনারি শব্দের কনস্ট্রাক্ট নামে একটি খেলা খেলেন । গেমটি খেলতে, আপনি একটি দৈর্ঘ্য ঠিক n >= 0, একটি সেট Glength- এর nবাইনারি নামক শব্দ লক্ষ্য সেট , এবং একটি length- nস্ট্রিং tঅক্ষর ধারণকারী Aএবং Bবলা পালা অর্ডার । খেলার জন্য স্থায়ী হয় nপালাক্রমে, এবং পালা উপর i, প্লেয়ার দ্বারা সংজ্ঞায়িত t[i]একটি বিট নির্বাচন w[i]। গেমটি শেষ হয়ে গেলে, খেলোয়াড়রা wতাদের তৈরি বাইনারি শব্দটির দিকে নজর দেয়। এই শব্দটি যদি গোল সেটে পাওয়া যায় G, তবে অ্যালিস গেমটি জিতবে; অন্যথায়, বব জয়ী।

উদাহরণস্বরূপ, ফিক্স দিন n = 4, G = [0001,1011,0010]এবং t = AABA। অ্যালিস প্রথম পালা পায় এবং সে চয়ন করে w[0] = 0। দ্বিতীয় পালাটিও এলিসের এবং তিনি বেছে নেন w[1] = 0। বব তৃতীয় বার আছে, এবং তিনি চয়ন w[2] = 0। চূড়ান্ত মোড় এ, এলিস চয়ন w[3] = 1। ফলস্বরূপ শব্দটি 0001পাওয়া যায় G, সুতরাং অ্যালিস গেমটি জিততে পারে।

এখন, বব যদি চয়ন করতেন তবে w[2] = 1অ্যালিস w[3] = 0তার চূড়ান্ত পর্বে বেছে নিতে পারত এবং এখনও জিততে পারত । এর অর্থ হল যে বব যেভাবে খেলুক না কেন অ্যালিস গেমটি জিততে পারে। এই পরিস্থিতিতে, এলিসের একটি বিজয়ী কৌশল রয়েছে । এই কৌশলটি একটি লেবেলযুক্ত বাইনারি গাছ হিসাবে ভিজ্যুয়ালাইজ করা যেতে পারে, যা ববসের পালা অনুসারে স্তরে শাখা করে এবং যার প্রতিটি শাখায় একটি শব্দ রয়েছে G:

A A B A

-0-0-0-1
    \
     1-0

অ্যালিস কেবল তার ঘুরে শাখা অনুসরণ করে খেলে; বব কোন শাখা চয়ন করে তা বিবেচনা করে না, শেষ পর্যন্ত অ্যালিস জিততে পারে।

ইনপুট

আপনাকে ইনপুট হিসাবে দৈর্ঘ্য হিসাবে দেওয়া হবে এবং দৈর্ঘ্যের স্ট্রিংগুলির একটি (সম্ভবত খালি) তালিকা হিসাবে nসেট দেওয়া হবে ।Gn

আউটপুট

আপনার আউটপুট হ'ল টার্ন অর্ডারগুলির তালিকা যার জন্য অ্যালিসের একটি বিজয়ী কৌশল রয়েছে যা উপরে বর্ণিত হিসাবে বাইনারি গাছের অস্তিত্বের সমান। টার্ন অর্ডারগুলির ক্রম কোনও ব্যাপার না তবে ডুপ্লিকেটগুলি নিষিদ্ধ।

বিস্তারিত বিধি

আপনি একটি সম্পূর্ণ প্রোগ্রাম বা একটি ফাংশন লিখতে পারেন। কোনও প্রোগ্রামের ক্ষেত্রে, আপনি ইনপুট এবং আউটপুটটির জন্য ডিলিমিটারটি চয়ন করতে পারেন, তবে এটি উভয়ের ক্ষেত্রেই একই হতে হবে। সংক্ষিপ্ততম বাইট গণনা জয় এবং মানক লুফোলগুলি অনুমোদিত নয়।

পরীক্ষার কেস

3 [] -> []
3 [000,001,010,011,100,101,110,111] -> [AAA,AAB,ABA,ABB,BAA,BAB,BBA,BBB]
4 [0001,1011,0010] -> [AAAA,BAAA,AABA]
4 [0001,1011,0010,0110,1111,0000] -> [AAAA,BAAA,ABAA,BBAA,AABA,AAAB]
5 [00011,00110,00111,11110,00001,11101,10101,01010,00010] -> [AAAAA,BAAAA,ABAAA,BBAAA,AABAA,AAABA,BAABA,AAAAB,AABAB]

মজার ব্যাপার

আউটপুটে টার্ন অর্ডারগুলির সংখ্যা সর্বদা লক্ষ্য সংখ্যার শব্দের সংখ্যার সমান।


5
ইনপুট এবং আউটপুট সমান আকার আছে এই বিষয়টি শুনে আমি আগ্রহী। এই সত্যটির জন্য আপনার কাছে কোনও প্রমাণ বা উদ্ধৃতি রয়েছে? আমি ভাবছি যে এই ফাংশনটি স্বজ্ঞাতভাবে আকার সংরক্ষণ করে এমন গণনা করার কোনও উপায় আছে কিনা?
xnor

2
আপনার পরীক্ষার কেস # 5 আপনার মজাদার ঘটনাটির বিরোধিতা করে ...
mbomb007

3
@ mbomb007 পরীক্ষার কেস # 5 তালিকা 11101দু'বার; মজার ঘটনা এখনও সেট জন্য রাখা। জগারব, ইনপুটটিতে পুনরাবৃত্তি উপাদান থাকতে পারে, বা এটি একটি ত্রুটি ছিল?
xnor

@ এক্সনর এটি এমন কিছু যা আমার গবেষণায় কিছুদিন আগে উঠে এসেছে। আমার এই প্রিপ্রিন্টের 16 পৃষ্ঠার একটি প্রমাণ রয়েছে তবে এটি মূলত আপনার মতো।
Zgarb

1
@xnor স্বজ্ঞাতভাবে, যে কোনও সময়ে, যদি 0 এবং 1 উভয়ই বিজয়ী হয়, তবে অ্যালিস বা বব হয় পরবর্তী পদক্ষেপটি চয়ন করতে পারেন। যদি একমাত্র বিজয়ী বিকল্প থাকে তবে অ্যালিসকে অবশ্যই পরবর্তী নির্বাচন করতে হবে। সুতরাং স্ট্রিংয়ের জন্য পছন্দগুলির সংখ্যা বিজয়ী কৌশলগুলির পছন্দগুলির সংখ্যার সমান। কঠোরভাবে কঠোর, কিন্তু বাধ্য।
অ্যালকিমিস্ট

উত্তর:


1

ডায়ালগ এপিএল, 59 বাইট

{(a≡,⊂⍬)∨0=⍴a←∪⍵:a⋄(∇h/t)(('A',¨∪),'B',¨∩)∇(~h←⊃¨a)/t←1↓¨a}

@ Xnor এর সমাধান হিসাবে একই অ্যালগরিদম।

(a≡,⊂⍬)∨0=⍴a←∪⍵:a
           a←∪⍵    ⍝ "a" is the unique items of the argument
        0=⍴a       ⍝ is it empty?
 a≡,⊂⍬             ⍝ is it a vector that contains the empty vector?
       ∨       :a  ⍝ if any of the above, return "a"

(∇h/t)(('A',¨∪),'B',¨∩)∇(~h←⊃¨a)/t←1↓¨a
                                 t←1↓¨a  ⍝ drop an item from each of "a" and call that "t"
                         ~h←⊃¨a          ⍝ first of each of "a", call that "h", then negate it
                                /        ⍝ use "~h" as a boolean mask to select from "t"
                       ∇                 ⍝ apply a recursive call
(∇h/t)                                   ⍝ use "h" as a boolean mask on "t", then a recursive call
      (('A',¨∪),'B',¨∩)                  ⍝ apply a fork on the results from the two recursive calls:
       ('A',¨∪)                          ⍝   prepend 'A' to each of the intersection
               ,                         ⍝   concatenated with
                'B',¨∪                   ⍝   prepend 'B' to each of the union

13

পাইথন, 132

def f(S,n):
 if n<1:return S
 a,b=[f({x[1:]for x in S if x[0]==c},n-1)for c in'01']
 return{'A'+y for y in a|b}|{'B'+y for y in a&b}

উদাহরণ রান:

f({'000','001','010','011','100','101','110','111'},3) == 
{'ABA', 'ABB', 'AAA', 'AAB', 'BBB', 'BBA', 'BAB', 'BAA'}

এটি কেবল ধরণের গল্ফযুক্ত, বেশিরভাগই অ্যালগরিদম দেখানোর জন্য। ইনপুট এবং আউটপুট স্ট্রিংগুলির সেট। পাইথনের কাছে এই অংশগুলির সংক্ষিপ্তভাবে প্রকাশ করার জন্য সঠিক বৈশিষ্ট্য রয়েছে বলে মনে হয় না, তাই কেউ এটি আরও ভাল-উপযুক্ত ভাষায় লিখলে ভাল হবে।

এখানে পুনরাবৃত্তিটি কীভাবে গাণিতিকভাবে প্রকাশ করা যায় তা এখানে। দুর্ভাগ্যক্রমে, পিপিসিগিতে এখনও গণিতের রেন্ডারিংয়ের অভাব রয়েছে, সুতরাং আমাকে কোড ব্লক ব্যবহার করতে হবে।

আগ্রহের বিষয়গুলি স্ট্রিংগুলির সেট। দিন |সেট ইউনিয়ন প্রতিনিধিত্ব করেন এবং& সেট ছেদ প্রতিনিধিত্ব করে।

যদি cএকটি চরিত্র হয় তবে আসুন সমস্ত স্ট্রিং-এ c#Sঅক্ষরটি পূর্বনির্ধারিত করুন । বিপরীতে, সংকোচনটি প্রাথমিক অক্ষরের অনুসরণ করে এমন এক-অক্ষর-সংক্ষিপ্ত স্ট্রিং হওয়া যাক , উদাহরণস্বরূপ,cSc\SSc0\{001,010,110,111} = {01,10} ,।

অক্ষরের প্রথম অক্ষর দ্বারা Sঅক্ষরের একটি সেট আমরা অনন্যভাবে ভাগ করতে পারি 01

S = 0#(0\S) | 1#(1\S)

তারপরে, আমরা fপ্রথম দুটি লাইনে ঘাঁটি কেসগুলি এবং শেষ লাইনে পুনরাবৃত্ত করতে পারে: নিম্নরূপে আমরা পছন্দসই ফাংশনটি প্রকাশ করতে পারি :

f({})   = {}
f({''}) = {''}
f(S)    = A#(f(0\S)|f(1\S)) | B#(f(0\S)&f(1\S))

নোট করুন যে আমাদের দৈর্ঘ্যটি ব্যবহার করার দরকার নেই n

কেন এই কাজ করে? আসুন মুভ-স্ট্রিংগুলি সম্পর্কে ভাবুন যা অ্যালিসকে স্ট্রিংগুলির একটি সেট জিততে দেয় S

প্রথম অক্ষর থাকে তবে A, এলিস প্রথম পদক্ষেপ নিতে পারবেন ( '0' বা '1'), তার সমস্যা কমাতে চয়ন লেট S0বা S1। সুতরাং এখন বাকী মুভ-স্ট্রিং কমপক্ষে একটি f(S0)বা এর মধ্যে থাকতে হবে f(S1), তাই আমরা তাদের ইউনিয়ন নিই|

একইভাবে, যদি প্রথম চরিত্রটি 'বি' হয় তবে ববটি বাছাই করতে পারে এবং সে এলিসের জন্য আরও খারাপটি বেছে নেবে, তাই বাকী মুভ-স্ট্রিংটি অবশ্যই ছেদটি ( &)তে থাকতে হবে ।

বেস কেসগুলি Sখালি কিনা শেষে পরীক্ষা করে দেখুন। আমরা nপ্রতিবার পুনরাবৃত্তি করার সময় 1 টি বিয়োগ করে যদি স্ট্রিংয়ের দৈর্ঘ্য সন্ধান করি, তবে তার পরিবর্তে ঘাঁটিগুলি লিখিত হতে পারে:

f(S) = S if n==0

পুনরাবৃত্তাকারী সমাধানটি মজাদার ঘটনাটিরও f(S)সমান আকার ধারণ করে S। এটি বেস কেসগুলির জন্য এবং প্ররোচক কেসের ক্ষেত্রে সত্য

f(S) = A#(f(0\S)|f(1\S)) | B#(f(0\S)&f(1\S))

আমাদের আছে

size(f(S)) = size(A#(f(0\S)|f(1\S)) | B#(f(0\S)&f(1\S)))
           = size(A#(f(0\S)|f(1\S))) + size(B#(f(0\S)&f(1\S))))
           = size((f(0\S)|f(1\S))) + size((f(0\S)&f(1\S))))
           = size(f(0\S)) + size(f(1\S))  [since size(X|Y) + size(X&Y) = size(X) + size(Y)]
           = size(0\S) + size(1\S)
           = size(S)

আপনার কোড দেয় চালানো TypeError: 'int' object is not subscriptable। আপনার কি চলমান প্রোগ্রামের লিঙ্ক আছে? আমি কেবল এটি আটকিয়েছি এবং এটি দিয়ে print f([0001,1011,0010],4)
চালিয়েছি

@ mbomb007 ফাংশনটির মতো অনুরোধ করা দরকার f({'000','001','010','011','100','101','110','111'},3)। আপনি কি এভাবে ত্রুটি পান?
xnor

আহ, আমি দেখিনি যে আমার উদ্ধৃতিগুলি অনুপস্থিত ছিল, ধন্যবাদ। এছাড়া সঙ্গে চালায়print f(['0001','1011','0010'],4)
mbomb007

আপনি যদি nপ্যারামিটারগুলি থেকে n=len(S[0])if S!=[]else 0
আলাদা

এটি এখানে চালান: repl.it/7yI
mbomb007
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.