क्या यह एक रैखिक वृक्ष है? (चौड़ाई-प्रथम संस्करण)


11

पृष्ठभूमि

एक बिना पेड़ का पेड़ ऐसा लग सकता है:

   o
 / | \
o  o  o
|    / \
o   o   o

इस पेड़ को रैखिक बनाने के लिए , हम पहले प्रत्येक नोड oको बाल नोड की संख्या के साथ लेबल करते हैं:

   3
 / | \
1  0  2
|    / \
0   0   0

और फिर एक सूची में एक सांस-पहले तरीके से संख्याएं लिखें, जिसका अर्थ पंक्ति द्वारा रेखा और दाएं से बाएं:

[3, 1, 0, 2, 0, 0, 0]

यह ऊपर के पेड़ का एक अनूठा और अस्पष्ट प्रतिनिधित्व है, जिसका अर्थ है कि किसी भी दो अलग-अलग शुद्ध पेड़ों में एक ही रेखीयकरण नहीं होगा और हम सूची से मूल पेड़ को फिर से संगठित कर सकते हैं।

हालांकि प्रत्येक पेड़ एक निश्चित पूर्णांक सूची से मेल खाता है, प्रत्येक पूर्णांक सूची एक वैध रैखिक वृक्ष का [2, 0, 0, 0]प्रतिनिधित्व नहीं करती है : उदाहरण के लिए एक वैध पेड़ का प्रतिनिधित्व नहीं करता है, अगर हम इसे इस पेड़ के साथ समाप्त करने की कोशिश करते हैं

[2,0,0,0] -> 2 [0,0,0] -> 2 [0,0] -> 2 [0]
            / \          / \        / \
                        0          0   0

लेकिन अभी भी 0सूची में एक छोड़ दिया है और इसे कहीं नहीं रखा है। इसी तरह [2, 0]एक वैध वृक्ष रेखीयकरण नहीं है, क्योंकि डी-लीनरीकृत वृक्ष में एक खाली बच्चा होता है:

  2
 / \
0

कार्य

पूर्णांक सूची को देखते हुए, यह तय करें कि क्या यह संभव के रूप में कुछ बाइट्स का उपयोग करके किसी पेड़ का एक वैध रैखिककरण है। आप एक पूर्ण कार्यक्रम या एक समारोह लिख सकते हैं।

इनपुट: गैर-नकारात्मक पूर्णांक की एक गैर-रिक्त सूची।

आउटपुट: एक सत्य मूल्य अगर सूची एक वृक्ष का रैखिककरण है, तो एक मिथ्या मूल्य अन्यथा।

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

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

जवाबों:


4

हास्केल, 44 बाइट्स

f[n:k]=iterate f[k]!!n
f _=[]
g x=f[x]==[[]]

एक फ़ंक्शन को परिभाषित करता है gजो एक सूची लेता है और एक बूलियन देता है। देखें कि यह सभी परीक्षण मामलों को पास करता है

व्याख्या

यह इस तथ्य पर निर्भर करता है कि गहराई-पहले और चौड़ाई-पहले रेखीयकरण समान सरणियों का उत्पादन करते हैं। विवरण के लिए मार्टिन के उत्तर देखें; मूल रूप से वे दोनों सरणी पर समान अंकगणितीय स्थिति देते हैं।

फ़ंक्शन fको एक सिंगलटन सूची में लिपटे इनपुट सूची दी गई है। यह nसूची से एक नंबर को पॉप करता है , फिर nशेष सूची पर खुद को पॉपप्ड नोड (गहराई पहले) के बच्चों को संसाधित करने के लिए कहता है । खाली सूची के परिणाम को रोकने के लिए [], जिसे मैं एक त्रुटि स्थिति के रूप में उपयोग करता हूं। फ़ंक्शन gजाँचता है कि अंतिम परिणाम है [[]], बिना किसी गैर-नोड नोड के साथ अद्वितीय गैर-त्रुटिपूर्ण स्थिति। यदि हास्केल को कमजोर रूप से टाइप किया गया था, तो मैं 0त्रुटि स्थिति के रूप में बस कुछ या उपयोग कर सकता था , और इनपुट को किसी अन्य सूची में लपेटना नहीं होगा।


3

गणितज्ञ, 38 बाइट्स

Last@#<0<=Min@Most@#&@Accumulate[#-1]&

मूल विचार यह है कि हम भरने के लिए कई नोड्स का ट्रैक रखते हैं। सूची में प्रत्येक तत्व एक नोड का उपयोग करता है और इसमें कई बच्चे शामिल हैं। इसलिए प्रत्येक तत्व iकुल गणना को बदलता है i-1। यह गिनती एक से बंद है, क्योंकि 1(रूट) से शुरू होना चाहिए , नहीं 0

पेड़ के वैध होने के लिए हम) 0पूरी सूची में नीचे कभी नहीं जा सकते हैं , क्योंकि हमारे पास वर्तमान नोड को रखने के लिए कहीं भी नहीं होगा और बी) को अंत में समाप्त होने की आवश्यकता है -1, अन्यथा हमें अप्रयुक्त नोड्स छोड़ दिया गया है।

हम इस शेष कुल नोड को प्राप्त करते हैं Accumulate[#-1](जो इनपुट सूची के उपसर्ग योगों को घटाता है)। और फिर हम जाँचते हैं कि अंतिम तत्व और केवल अंतिम तत्व -1निम्न है:

Last@#<0<=Min@Most@#

ध्यान दें कि अंतिम तत्व ऋणात्मक है, पर्याप्त है, क्योंकि हम कभी भी अधिक से अधिक नहीं घटा सकते हैं 1, इसलिए यदि अंतिम मान -2या कम था तो न्यूनतम दूसरों के लिए गैर-नकारात्मक होना असंभव होगा।


2

रेटिना , 29 बाइट्स

\d+
$*
^(?<-1>(1)*,)*$(?(1)!)

इसे ऑनलाइन आज़माएं! (पहली पंक्ति एक लाइनफ़ीड-पृथक परीक्षण सूट को सक्षम करती है।)

व्याख्या

मूल विचार मेरे गणितज्ञ उत्तर के समान है : हम शेष नोड्स के चलने वाले कुल का ट्रैक रखते हैं, यह सुनिश्चित करते हैं कि यह कभी शून्य से नीचे नहीं जाता है लेकिन शून्य पर समाप्त होता है। हालाँकि, इसे रेगेक्स के साथ लागू करने का तरीका बहुत अलग है।

\d+
$*

यह प्रत्येक इनपुट को 1s nमें बदलकर बस इनपुट को unary में बदल देता है n

^(?<-1>(1)*,)*$(?(1)!)

यहीं से असली जादू होता है। यह काफी छोटा रेगेक्स है जो केवल वैध पेड़ों से मेल खाता है, लेकिन यह यांत्रिकी काफी सूक्ष्म है।

मैं नोड्स की संख्या का ट्रैक रखने के लिए बैलेंसिंग समूहों का उपयोग कर रहा हूं , जो रेगेक्स के अंदर ढेर के साथ काम करने का एक तरीका है।

सबसे पहले, निश्चित रूप से इस तरह के स्टैक में कभी भी नकारात्मक गहराई नहीं हो सकती है, इसलिए हम वास्तव में अंत में एक प्रतिनिधित्व के साथ समाप्त नहीं कर सकते हैं -1, जैसा कि हम गणित के समाधान में करते हैं। हालाँकि, हम नोट कर सकते हैं कि इनपुट का अंतिम तत्व एक वैध स्टैक पर शून्य होना चाहिए (अन्यथा हम साथ समाप्त नहीं कर सकते -1)। ऐसा लगता है कि यह वास्तव में जांच करने के लिए बाइट्स की बचत होती है दोनों है कि हम शून्य पर और शून्य शेष नोड्स के साथ समाप्त।

तो यहाँ रेगेक्स का एक विराम है:

^        e# Anchor the match to the beginning of the string.
(?<-1>   e# Each repetition of this group will match one number. 
         e# We can ignore the <-1> for now.
  (1)*   e#   Match each unary digit of the current number, pushing
         e#   a capture onto stack 1. This increments our total of
         e#   remaining nodes by 1 for each child.
  ,      e#   Match a comma. Note that this requires that there is at
         e#   least one more number in the list.
)*       e# At the end of the repetition the <-1> pops one capture from
         e# the stack. This is the node that the current number itself
         e# takes up.
$        e# Match the end of the string. This requires the input to end
         e# in a zero, because the last thing we matched was a comma.
(?(1)!)  e# Make sure that stack 1 is empty, so that we don't have any
         e# unused nodes.

1

CJam (20 बाइट्स)

{X0@{+\(_0>{\}*}/|!}

ऑनलाइन टेस्ट सूट । यह एक अनाम ब्लॉक है जो स्टैक पर एक सरणी लेता है और स्टैक पर 0 या 1 छोड़ देता है।

विच्छेदन

स्यूडोकोड में यह है:

p = 1
q = 0
foreach (i in input):
  q += i
  if (--p <= 0):      # in practice, if (--p == 0):
      p, q = q, p
return (p | q) == 0   # i.e. p == 0 && q == 0

qपेड़ में वर्तमान स्तर पर नोड्स के लेबल का योग जमा करता है; pवर्तमान स्तर में शेष नोड्स को गिना जाता है।


{X0@{+\(_{\}&}/|!}मुझे लगता है?
मार्टिन एंडर

इसके अलावा ऐसा लगता है कि आप से बचने के लिए एक पूर्ण कार्यक्रम का उपयोग करके एक बाइट को बचाने में सक्षम होना चाहिए @
मार्टिन एंडर

1

भूलभुलैया , 17 बाइट्स

(
+?
;-)
,_"
@@,!

इसे ऑनलाइन आज़माएं!

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

>"F
 T

इस मामले में, मैं सीधे आगे झूठे (क्योंकि आंदोलन की दिशा अप्रभावित है) और सच मोड़ पर विचार करूंगा। ये क्रमशः शून्य और गैर-शून्य के अनुरूप हैं। शून्य का प्रतिनिधित्व करने के लिए एक खाली आउटपुट का उपयोग करने का कारण यह है कि, यदि आप आउटपुट को किसी अन्य भूलभुलैया कार्यक्रम में वापस पाइप करने के लिए थे, तो इनपुट ऑपरेटर ?वास्तव में शून्य को धक्का देगा यदि इनपुट खाली है, तो मैं रिक्त स्ट्रिंग को वैध मानता हूं शून्य का प्रतिनिधित्व।

व्याख्या

एल्गोरिथ्म अभी भी मेरे गणितज्ञ और रेटिना के उत्तरों की तरह ही है, लेकिन लैबिंथिथ के नियंत्रण प्रवाह के कारण, यह इस बार कुछ अलग काम करता है:

  • हम यहां कुल काउंटर ऑफ बाय-वन के साथ काम नहीं करते हैं। इसके बजाय हम a) एक नकारात्मक काउंटर के साथ काम करते हैं और b) इसे -11शुरू में शुरू करते हैं, ताकि हम चाहते हैं कि काउंटर पूरी सूची में नकारात्मक रहे और आखिरी इनपुट पर शून्य मारा। यह वास्तव में यहाँ नियंत्रण प्रवाह को सरल करता है।
  • पूरी सूची बनाने और जाँचने के बजाय कि क्या इसमें गलत मूल्य है, तीन संभावित समाप्ति की स्थिति है:

    1. शून्य की कुल संख्या तक पहुंचने से पहले हमने ईओएफ को मारा। उस स्थिति में अप्रयुक्त नोड्स बचे हैं और हम कुछ भी नहीं प्रिंट करते हैं।
    2. हम शून्य तक पहुँचते हैं और हम EOF पर हैं। इस मामले में, हमें एक वैध पेड़ मिला है।
    3. हम शून्य तक पहुँचते हैं और अभी EOF पर नहीं हैं। इस मामले में, हम सभी तत्वों को कवर करने से पहले नोड्स से बाहर भाग गए, और हम कुछ भी नहीं प्रिंट करते हैं।

वास्तविक कोड के लिए, हम शीर्ष बाएं कोने में शुरू करते हैं। (एक में ढेर के शीर्ष पर निहित शून्य हो जाती है -1, जो चल रहा है कुल किया जाएगा। हम तब कार्यक्रम के बहुत तंग मुख्य लूप में प्रवेश करते हैं +?-)"_,;+:

+   Add the top two values. This does nothing on the first iteration,
    but gets rid of a helper-zero on subsequent iterations.
?   Read and push integer.
-   Subtract it from running total.
)   Increment.
"   No-op. There is a branch at this point. If the running total is zero,
    we move straight ahead onto the , (see below). Otherwise, the loop continues.
_   Push a zero. This is necessary to prevent the IP from turning south.
,   Read a character. This will either be the next separator (some positive
    number) or EOF (-1). If it's EOF, the IP turns south and the program
    terminates. Otherwise, the loop continues.
;   Discard the separator.

यह केवल उन मामलों को छोड़ देता है जहां हमने कुछ बिंदु पर चल रहे शून्य को कम कर दिया है। IP निचले-दाएं की ओर बढ़ता ,है और यह जांचने के लिए कि हम EOF तक पहुँच चुके हैं, किसी अन्य वर्ण को पढ़ता है। यदि नहीं, तो मान सकारात्मक होगा और आईपी पश्चिम की ओर मुड़ जाता है @और कार्यक्रम समाप्त हो जाता है। यदि हम EOF तक पहुँचते हैं, तो IP पूर्व की ओर मुड़ता है और -1साथ प्रिंट करता है !। आईपी ​​तब @कार्यक्रम को समाप्त करने के लिए थोड़ा अजीब रास्ते के माध्यम से निचले बाएं की ओर अपना रास्ता खराब कर देगा ।


0

पायथन, 82 बाइट्स

lambda l:len(l)==sum(l)+1 and not any(list(l[x]>=len(l)-x for x in range(len(l))))

अधिक परीक्षण मामलों की आवश्यकता है।


आपको यह बताने की आवश्यकता नहीं है listकि यह पायथन 2 है, और कम से कम, और दूसरी शर्त को उलट कर आप इसे 70 बाइट्स में प्राप्त कर सकते हैं:lambda l:all(l[x]<len(l)-x for x in range(len(l)))and len(l)==sum(l)+1
केड

^ इस के संबंध में, आप के शरीर को बदल सकते हैं allहोने के लिए x<len(l)-y for y,x in enumerate(l)68. करने के लिए इसे पाने के लिए एक और 2 बाइट्स को बचाने के लिए
Kade

मैं इसे अभी और आगे नहीं बढ़ा रहा हूं क्योंकि मुझे नहीं लगता कि यह एक सटीक समाधान है। सुझावों के लिए धन्यवाद।
स्पर्म

0

पायथ, 13 बाइट्स

qxsM._tMQ_1tl

हम इनपुट प्रतिनिधित्व में सभी बिंदुओं पर पेड़ के वर्तमान भरे-नेस की गणना करके शुरू करते हैं। विचार का वह हिस्सा काफी हद तक मार्टिन एंडर से उधार लिया गया है, इसलिए उसके लिए धन्यवाद।sM._tMQ

एक बार जब हमारे पास यह सूची होती है, तो हम जांचते हैं कि पहला इंडेक्स युक्त -1( x..._1) इनपुट माइनस एक ( q...tl(Q)) की लंबाई है या नहीं ।

विश्वास मत करो यह काम करता है? इसे स्वयं आज़माएं!

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