अराजकता की गिरावट (एक न्यूनतम एपेरियोडिक अनुक्रम का निर्माण)


9

यहां विचार लगभग दोहराए जाने वाले पैटर्न का उत्पादन करने का है । यही है, अनुक्रम को कुछ क्षणों की पुनरावृत्ति से बचने के लिए अंतिम क्षण में परिवर्तन का निर्माण किया जा रहा है। एए और एबीए प्रकार के परिणामों से बचा जाना चाहिए (जहां बी अब ए से अधिक नहीं है)।

उदाहरण:

मैं अपने विवरण को स्पष्ट करने के लिए सभी छोटे उदाहरणों को सूचीबद्ध करके आगे बढ़ूंगा। 0 से शुरू करते हैं।

मान्य: ०

अमान्य: 00 (AA पैटर्न)
मान्य: ०१

अमान्य: 010 (ABA पैटर्न)
अमान्य: 011 (AA पैटर्न)
मान्य: 012

मान्य: 0120
अमान्य: 0121 (ABA पैटर्न)
अमान्य: 0122 (AA पैटर्न)

अमान्य: 01200 (AA पैटर्न)
अमान्य: 01201 (ABA पैटर्न; 01-2-01)
अमान्य: 01202 (ABA पैटर्न)
मान्य: 01203

अब, मैं दृढ़ता से मानता हूं कि 4इसकी कभी आवश्यकता नहीं है, हालांकि मेरे पास कोई सबूत नहीं है, क्योंकि मुझे आसानी से सैकड़ों वर्णों के अनुक्रम मिल गए हैं जो केवल उपयोग करते हैं 0123। (यह संभवतः बारीकी से संबंधित है कि केवल तीन वर्णों के लिए अनंत तारों की आवश्यकता होती है जिनके पास कोई एए पैटर्न नहीं है। इस पर एक विकिपीडिया पृष्ठ है।)

इनपुट आउटपुट

इनपुट एक एकल, सकारात्मक, गैर-शून्य पूर्णांक है n। आप ऐसा मान सकते हैं n <= 1000

आउटपुट एक nआवर्ती अनुक्रम है जिसमें कोई भी अनुगमन नहीं है जो निषिद्ध पैटर्न (AA या ABA) से मेल खाता है।

नमूना इनपुट और आउटपुट

>>> 1
0

>>> 2
01

>>> 3
012

>>> 4
0120

>>> 5
01203

>>> 50
01203102130123103201302103120132102301203102132012

नियम

  • केवल पात्रों 0123की अनुमति है।
  • बी नहीं रह गया है की तुलना में ए यह स्थिति जहां से बचना है 012345द्वारा अपनाई जाने वाली है 6क्योंकि 0123451यह है: 1-2345-1। दूसरे शब्दों में, अनुक्रम तुच्छ और अविच्छिन्न होगा।
  • nहार्ड-कोडिंग को छोड़कर , वांछित किसी भी विधि के माध्यम से इनपुट किया जा सकता है ।
  • आउटपुट या तो एक सूची या एक स्ट्रिंग हो सकता है, जिसके आधार पर यह आसान है।
  • कोई क्रूर बल नहीं ; रन का समय मिनटों के क्रम पर होना चाहिए, वास्तव में धीमी गति से मशीन पर अधिकतम एक घंटे के लिए n=1000। (यह उन समाधानों को अयोग्य ठहराने के लिए है, जो केवल-के सभी- nपरिकलन क्रमों के माध्यम से लूप करते हैं {0,1,2,3}, ताकि ट्रिक और इसी तरह की चालों को रोक दिया जाए।)
  • मानक खामियों को हमेशा की तरह खारिज कर दिया जाता है।
  • स्कोरिंग बाइट्स में है। ये है, इसलिए सबसे छोटी प्रविष्टि जीतती है (शायद - बोनस देखें)।
  • बोनस: प्रत्येक चरण पर सबसे कम अनुमत अंक चुनें। तो 1और 3क्रम में अगला अंकों के लिए संभव विकल्प हैं, लेने 1। अपने स्कोर से 5 बाइट घटाएं । हालाँकि, नीचे दिए गए नोट पर ध्यान दें।

ध्यान दें!

डेड-एंड संभव है। आपके कार्यक्रम या समारोह को इनसे बचना चाहिए। यहाँ एक उदाहरण है:

स्टंप: 0120310213012310320130210312013210230120310213201230210312013023103201230213203102301203210231201302103123013203102130120321023013203123021032012310213012031023013203123021320123102130120
स्टंप: 0120310213012310320130210312013210230120310213201230210312013023103201230213203102301203210231201302103123013203102130120321023013203123021032012310213012031023013203123021320123102130123
स्टंप: 012031021301231032013021031201321023012031021320123021031201302310320123021320310230120321023120130210312301320310213012032102301320312302103201231021301203102301320312302132012310320
स्टंप: 012031021301231032013021031201321023012031021320123021031201302310320123021320310230120321023120130210312301320310213012032102301320312302103201231021301203102301320312302132012310321301203102130

इनमें से प्रत्येक क्रम को आगे (बिना उपयोग किए 4) बढ़ाया नहीं जा सकता । लेकिन यह भी ध्यान दें कि पहले दो और दूसरे दो के बीच एक महत्वपूर्ण अंतर है। मैं इसे Xस्पष्ट करने के लिए साझा प्रारंभिक अनुवर्ती को प्रतिस्थापित करूँगा ।

स्टंप: X2130120
स्टंप: X2130123
स्टंप: X320
स्टंप: X321301203102130

अंतिम दो अंक Xहैं 10, इसलिए अगले अंक के लिए एकमात्र संभव विकल्प हैं 2और 3। चुनना 2एक ऐसी स्थिति की ओर जाता है जहां अनुक्रम को समाप्त करना होगालालची एल्गोरिथ्म यहां काम नहीं करेगा । (बिना पीछे किए, वैसे भी नहीं।)


क्या कोई हर संभव स्ट्रिंग के परीक्षण की एक क्रूर बल रणनीति का उपयोग कर सकता है, भले ही वह यथार्थवादी समय में आउटपुट न दे? क्या आप जानते हैं कि सभी के लिए एक समाधान होना चाहिए n? यदि कोई व्यक्ति एक अर्ध-लालची एल्गोरिथ्म देता है, तो आप कैसे जांचेंगे कि यह बहुत बड़ी लंबाई के लिए समस्याओं में नहीं चलता है? सामान्य समस्या एक दिलचस्प है, और मैं पैटर्न परिहार पर कुछ भी नहीं पा रहा हूं जहां हम पैटर्न के हिस्से की लंबाई को सीमित करते हैं। अगर कोई सामान्य नुस्खा का उत्पादन कर सकता है, तो मुझे उम्मीद है कि सबसे अच्छा तरीका होगा।
20

मेरा मानना ​​है कि मैंने नियमों में क्रूर बल को अस्वीकार कर दिया। मुझे शायद उस पर प्रकाश डालना चाहिए। मेरे पास इस बात का प्रमाण नहीं है कि सभी के लिए एक समाधान मौजूद है n, लेकिन यह देखते हुए कि मेरे कार्यक्रम में जो स्टंप लगता है, वह हर बार औसतन 10 अंकों का हो जाता है, मुझे पूरा यकीन है कि एक अनंत क्रम मौजूद है। मुझे यकीन नहीं है कि कैसे अर्ध-लालची एल्गोरिदम को मनमाने ढंग से बड़े दृश्यों के लिए परीक्षण किया जा सकता है। मैं आवश्यकता को n1000 तक सीमित कर सकता हूं और उच्चतर की चिंता नहीं कर सकता n
एल'एंडिया स्ट्रैटन

4
मुझे लगता AAहै कि वास्तव में प्रकार है ABAजहां Bखाली है। यह शायद कुछ समाधानों को कारगर बनाने में मदद कर सकता है।
मैथमैडैन

जवाबों:


6

रेटिना , 86 बाइट्स - 5 = 81

$
_
(r`^(?<-2>.)+_((.)+)\b$
$1!
\b$
0
3#
#
0#
1
1#
2
2#
3
)r`\1(?<-2>.)*((.)+)$
$0#
!
<empty>

जहां <empty>एक खाली अनुरेखण रेखा का प्रतिनिधित्व करता है। आप -sध्वज के साथ एक फ़ाइल से उपरोक्त कोड चला सकते हैं ।

इनपुट को unary में दिया जाना चाहिए , जैसे 111111। मैंने इसे हज़ारों के क्रम पर आउटपुट के लिए अभी तक परीक्षण नहीं किया है - दो रीगेक्स थोड़ी देर के बाद थोड़ा धीमा हो सकते हैं - लेकिन यह कुछ सेकंड में सौ के एक जोड़े को आसानी से संभाल सकता है।

व्याख्या

यह एक सरल backtracking समाधान है।

  1. एक संलग्न करें 0
  2. जबकि वर्तमान अनुक्रम अमान्य है, सभी अनुरेखण 3s को हटा दें और अंतिम गैर-वृद्धि करें 3
  3. तब तक दोहराएं जब तक हमारे पास वांछित लंबाई का वैध अनुक्रम न हो।

यह बैकट्रैकिंग रेगेक्स प्रतिस्थापन के एक लूप द्वारा कार्यान्वित की जाती है जो स्ट्रिंग को एक पुनरावृत्ति के माध्यम से अपरिवर्तित रहने पर निरस्त कर देता है।

$
_

यह एक _इनपुट को जोड़ता है , जिसका उपयोग हमारे द्वारा निर्मित अनुक्रम से अनरी इनपुट को अलग करने के लिए किया जाता है।

(r`^(?<-2>.)+_((.)+)\b$
$1!

यह लूप में पहला प्रतिस्थापन है (अग्रणी द्वारा दर्शाया गया है ()। Regex मेल खाता है यदि a) स्ट्रिंग के अंत में एक शब्द वर्ण (यानी एक अंक) है (जिसका अर्थ है कि स्ट्रिंग वैध है - हम नीचे देखेंगे कि अमान्य अनुक्रम एक अनुगामी के साथ चिह्नित हैं #) और b) कम से कम हैं अनुक्रम में जितने भी वर्ण हैं (इनपुट समूहों का उपयोग करके यह जाँच की जाती है )। यदि ऐसा है, तो हम इनपुट हटाते हैं और संलग्न करते हैं !। यह !लूप में सभी रेगेक्स को विफल करने का कार्य करता है, जैसे कि यह समाप्त हो जाता है।

\b$
0

यदि अंत में एक शब्द चरित्र है (यानी अनुक्रम मान्य है, और लूप को पिछले चरण से समाप्त नहीं किया गया था), तो संलग्न करें 0

3#
#

यदि (इसके बजाय) अनुक्रम अमान्य चिह्नित किया गया था और समाप्त हो गया है 3, तो हम उसे हटा देते हैं 3(लेकिन अनुक्रम को अमान्य के रूप में छोड़ देते हैं, क्योंकि वर्तमान उपसर्ग के लिए कोई संभावित निरंतरता नहीं है ... इसलिए अगले चरित्र को भी पीछे करने की आवश्यकता है)।

0#
1
1#
2
2#
3

यदि अनुक्रम अमान्य है और इसके अलावा कोई भी अंक 3अंत में है, तो हम अंक को बढ़ाते हैं और मार्कर को हटाते हैं।

)r`\1(?<-2>.)*((.)+)$
$0#

लूप में अंतिम प्रतिस्थापन (जैसा कि संकेत दिया गया है ))। यह जांचता है कि क्या स्ट्रिंग समाप्त होती है ABA(जहां संभावित Bसे अधिक नहीं है, Aलेकिन संभावित रूप से खाली है)। की सापेक्ष लंबाई Aऔर Bफिर से संतुलन वाले समूहों का उपयोग करके जाँच की Aजाती है , और पुनरावृत्ति की जाँच एक साधारण बैकरीफेरेंस के साथ की जाती है।

यदि यह रेगेक्स मेल खाता है, तो हम अनुक्रम को जोड़कर अमान्य मानते हैं #

!
<empty>

एक बार जब लूप समाप्त हो जाता है, तो हमें केवल इतना करना होगा कि इसे हटा दिया जाए !और फिर वांछित आउटपुट के साथ छोड़ दिया जाए।


2

पायथन 2, 175 - 5 = 170 बाइट्स

n=input();s='';u=j=-1
while n>len(s):
 while u>2:u=int(s[0]);s=s[1:]
 u+=1;t=`u`+s;m=c=0
 while t[c:]*0**m:c+=1;i=t[c:].find(t[:c]);m=j<i<=c
 if c>=len(t):s=t;u=j
print s[::j]

यह लालची एल्गोरिथ्म है जिसमें बैकट्रैकिंग है। काश यह छोटा होता। मुझे आशा है कि यह सही है (नीचे देखें)।

यह एक बार में एक अंक का निर्माण करता है। dअंकों की एक स्ट्रिंग को देखते हुए कि यह पहले से ही पाया गया है, यह सेंट अंक के 0रूप में संलग्न करने की कोशिश करता है (d+1)। अगर वह काम नहीं करता है, तो यह एक कोशिश करता है 1, तो ए2 , फिर ए 3। यदि इनमें से कोई भी काम नहीं करता है, तो यह dवें अंक पर वापस जाता है और इसे बढ़ाता है (यदि इससे कम है 3) या इसे हटा देता है (यदि बराबर है 3, तो उस स्थिति में यह पिछले एक को बढ़ाता है, आदि)।

वैधता के लिए जाँच .findइसके साथ की रेखा है। यदि कोई मेरे कोड को पढ़ने का निर्णय लेता है, तो मुझे यह कहना चाहिए कि यह कार्यक्रम वास्तव में स्ट्रिंग को पीछे की ओर संग्रहीत कर रहा है, जिसका अर्थ है कि यह सामने की ओर अंक जोड़ रहा है । इसलिए चेक में उन स्थानों की तलाश करना शामिल है जहां पहले c अंक फिर से बाद में स्ट्रिंग में दिखाई देते हैं (पहले cअंक के बाद कहीं भी ), और यदि कोई ऐसी जगह हैं, तो क्या अंतराल की लंबाई सबसे अधिक है c

(बेशक यह मुद्रण से पहले स्ट्रिंग को उलट देता है।)

यह आसानी से तेज भी हो सकता है; मेरे पास मूल रूप से दक्षता के लिए विभिन्न छोरों से बाहर निकलना था, लेकिन यह कीमती बाइट्स की लागत थी। यह अभी भी की सीमा में ठीक हैn=1000 , हालांकि।

वैसे भी, कार्यक्रम छोटे अंकों के लिए वरीयता प्रदर्शित करता है, लेकिन यह बहुत मजबूत प्राथमिकता नहीं है। उदाहरण के लिए, इसे चलाने से n=2000मुझे 523शून्य के साथ एक तार दिया गया , जो कि दो 502, 497दो और 478तीन थे, अंत में 30210312013021। इसलिए अगर कोई और लालची एल्गोरिथम पर काम कर रहा है, तो शायद वे इस परिणाम की पुष्टि कर सकते हैं। या n=1000मैं [263, 251, 248, 238]अंकों के हिसाब से गिनता हूं ।

अंत में, मैं यह उल्लेख करूंगा कि ये गणना समरूपता के विचारोत्तेजक के प्रकार हैं, लगभग (हालांकि बिल्कुल नहीं) जैसे कि हमने एक समान वितरण के साथ शुरू किया था और फिर कुछ 3को 0's' और कुछ को 2's 1' में बदल दिया। रों। लेकिन जाहिर है कि यह महज संयोग हो सकता है। मुझे पता नहीं है!


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