एक स्ट्रिंग निर्माण खेल के लिए रणनीतियाँ जीतना


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 , औरG के तारों की एक (संभवतः खाली) सूची के रूप में सेट किया गया है n

उत्पादन

आपका आउटपुट टर्न ऑर्डर की सूची है, जिसके लिए ऐलिस की जीतने की रणनीति है, जो ऊपर वर्णित बाइनरी ट्री के अस्तित्व के बराबर है। टर्न ऑर्डर का क्रम मायने नहीं रखता है, लेकिन डुप्लिकेट निषिद्ध हैं।

विस्तृत नियम

आप एक पूर्ण कार्यक्रम या एक फ़ंक्शन लिख सकते हैं। एक कार्यक्रम के मामले में, आप इनपुट और आउटपुट के लिए सीमांकक चुन सकते हैं, लेकिन यह दोनों के लिए समान होना चाहिए। सबसे छोटी बाइट गिनती जीतती है, और मानक खामियों को रोक दिया जाता है।

परीक्षण के मामलों

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दो बार; मजेदार तथ्य अभी भी सेट के लिए है। Zgarb, इनपुट में बार-बार तत्व हो सकते हैं, या यह एक त्रुटि थी?
22

@xnor यह कुछ ऐसा है जो कुछ समय पहले मेरे शोध में सामने आया था। मेरे पास इस प्रस्तावना में एक प्रमाण है , पृष्ठ 16, लेकिन यह अनिवार्य रूप से आपके जैसा ही है।
जर्बर्ग

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'}

यह केवल तरह का गोल्फ है, ज्यादातर एल्गोरिथ्म दिखाने के लिए। इनपुट्स और आउटपुट स्ट्रिंग्स के सेट हैं। इस कॉम्पैक्ट के कुछ हिस्सों को व्यक्त करने के लिए पायथन के पास सही विशेषताएं नहीं हैं, इसलिए यदि कोई इसे बेहतर-अनुकूल भाषा में लिखता है तो यह अच्छा होगा।

यहां बताया गया है कि कैसे गणितीय रूप से पुनरावृत्ति को व्यक्त किया जा सकता है। दुर्भाग्य से, PPCG में अभी भी गणित प्रतिपादन का अभाव है, इसलिए मुझे कोड ब्लॉक का उपयोग करना होगा।

ब्याज की वस्तुएं तार के सेट हैं। आज्ञा देना |सेट गठबंधन प्रतिनिधित्व करते हैं और &सेट चौराहे प्रतिनिधित्व करते हैं।

यदि cएक चरित्र है, तो c#Sचरित्र cको सभी तार में प्रस्तुत करने का प्रतिनिधित्व करते हैं S। इसके विपरीत, संकुचन को प्रारंभिक वर्ण का अनुसरण c\Sकरने वाले एकल-वर्ण-छोटे तार होने दें , जैसे,Sc0\{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

@ mbomb007 फ़ंक्शन को इस तरह लागू करने की आवश्यकता है f({'000','001','010','011','100','101','110','111'},3)। क्या आपको इस तरह एक त्रुटि मिलती है?
22 दिसंबर को xnor

आह, मैंने नहीं देखा कि मैं उद्धरण याद कर रहा था, धन्यवाद। यह भी साथ चलता हैprint f(['0001','1011','0010'],4)
mbomb007

यदि आप nमापदंडों से स्वतंत्र जानते हुए कार्यक्रम चलाना चाहते हैं तो यह होगाn=len(S[0])if S!=[]else 0
mbomb007

इसे यहां चलाएं: repl.it/7yI
mbomb007
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.