क्या यह एक वास्तविक वृक्ष है?


20

आपको एक प्रोग्राम या फ़ंक्शन लिखना चाहिए जो इनपुट के रूप में एक स्ट्रिंग प्राप्त करता है और आउटपुट या रिटर्न अगर इनपुट एक ASCII पेड़ है।

  _
\/  /
 \_/
  |
  |

ASCII पेड़ वर्ण होने / \ | _ spacesऔर newlines

गैर-व्हाट्सएप पात्र अपनी कोशिकाओं के दो किनारे बिंदुओं को एक रेखाखंड से जोड़ते हैं:

  • / नीचे बाएं और ऊपर दाएं कोनों को जोड़ता है
  • \ नीचे दाएं और बाएं बाएं कोनों को जोड़ता है
  • | नीचे के किनारे और शीर्ष किनारे के मध्य बिंदुओं को जोड़ता है
  • _ नीचे बाएं और नीचे दाएं कोनों और नीचे के किनारे के मध्य बिंदु को जोड़ता है

(ध्यान दें कि यह मतलब है कि |केवल के साथ जुड़ सकते |या _लेकिन साथ नहीं /या \।)

यदि निम्नलिखित नियम लागू होते हैं तो ASCII चित्र को पेड़ कहा जाता है:

  • वास्तव में एक वर्ण का एक बिंदु (मूल) अंतिम पंक्ति के निचले किनारे को छूता है।
  • आप किसी भी सेगमेंट के किसी भी बिंदु तक पहुँच सकते हैं:

    • जड़ से शुरू
    • केवल लाइन सेगमेंट का उपयोग करना
    • कभी नीचे की दिशा में नहीं जाना (नीचे की ओर भी नहीं)

इनपुट

  • वर्णों / \ | _ spaceसे newlineयुक्त एक स्ट्रिंग और जिसमें कम से कम एक गैर-व्हाट्सएप चरित्र होता है।
  • आप दो इनपुट प्रारूप चुन सकते हैं:

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

उत्पादन

  • एक सुसंगत सत्य मान यदि इनपुट एक आस्की वृक्ष है।
  • यदि इनपुट ascii ट्री नहीं है, तो एक सुसंगत मिथ्या मूल्य।

उदाहरण

वैध पेड़:

|
  _
\/  /
 \_/
  |
  |
/ /    \/
\ \____/
 \/
 /
/
 \___/
 /   \
 \___/
   |
   |
   __/
 _/
/
____
  \  ___
 \ \/
  \/\_____/
 \/  \/
  \__/
    |
    |

अमान्य पेड़ (अतिरिक्त स्पष्टीकरण के साथ जो इनपुट के भाग नहीं हैं):

\/
 \_______/
  \__   /
   | \_/    <- reachable only on with downward route
   |
_           <- multiple roots
\/          <- multiple root characters
/\          <- multiple roots
|           <- unreachable part

|
 __/
/           <- unreachable parts
|
\____/
 |  |       <- multiple roots
_\__/       <- unreachable parts (_ and \ don't connect to each other)
|

यह कोड-गोल्फ है इसलिए सबसे छोटी प्रविष्टि जीतती है।

जवाबों:


7

पीएमए / घोंघे , 99 93

प्रिंट 1 अगर यह "पेड़" परिभाषा को संतुष्ट करता है या 0 नहीं तो। आयताकार अंतरिक्ष-गद्देदार रूप इनपुट पसंद किया जाता है, हालांकि यह केवल एक बाइट ( Fविकल्प का उपयोग करके ) को रैग्ड संस्करण को अंतरिक्ष से भरे आयत में बदलने के लिए खर्च करता है, जो परीक्षण में उपयोगी था।

&
\ |{(\_|\|)d=\||(\\a7|\/d|\_da7)=\\|(\\d|\/a5|\_da5)=\/|(\_lr|\|d|\/l|\\r)=\_},^_!(r.,^ )d~

Ungolfed, पुराना संस्करण (मेरे व्यक्तिगत आनंद के लिए):

F&
\ |
{
  \_ (lr=\_|da5=\/|da7=\\|d=\|) | \/ (l=\_|a5=\/|d=\\) | 
    \\ (r=\_|a7=\\|d=\/) | \|d=(\_|\|)    
}, 
^_ !(r.,^ ) d~

यह वर्तमान भाषा सुविधाओं के काफी अनुकूल है। दुर्भाग्य से, मुझे काम गिनने वाले बग से पहले कुछ घंटों का समय बिताना पड़ा, इससे पहले कि यह काम कर सके।

&विकल्प का मतलब है कि मैच हर चरित्र में सफल होने चाहिए। प्रत्येक गैर-अंतरिक्ष शुरुआती बिंदु से यह नीचे की ओर नीचे की ओर जाने के लिए जांच करता है। एक regex के साथ एक परिमित राज्य मशीन बनाना, मुखर रूप से उपयोग करके बहुत कम है, यहाँ =...। नीचे की पंक्ति में, यह जांचता है कि दाईं ओर कोई गैर-स्पेस वर्ण नहीं हैं।


10

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

अभी भी काफी लंबा है, लेकिन मुझे लगता है कि यह एक शुरुआत है ...

(s=StringSplit;v=Reverse;#=="|"||#=="\\"||#=="/"&[""<>s@#]&&(g={};i=0;(c={i,++j};d={i,j+1/2};e=2d-c;g=Join[g,Switch[#,"|",{d->{1,0}+d},"/",{c->c+1},"\\",{e->{i+1,j}},"_",{c->d,d->e,e->c},_,{}]])&/@Characters[++i;j=0;#]&/@{##};Sort@VertexOutComponent[Graph@g,g[[1,1]]]==Union@@List@@@g)&@@v@s[#,"
"])&

यहाँ एक थोड़ा ungolfed संस्करण है:

(
  s = StringSplit;
  v = Reverse;
  # == "|" || # == "\\" || # == "/" &[
      "" <> s@#
      ] && (
      g = {};
      i = 0;
      (
           c = {i, ++j};
           d = {i, j + 1/2};
           e = 2 d - c;
           g = Join[g, Switch[#,
              "|", {d -> {1, 0} + d},
              "/", {c -> c + 1},
              "\\", {e -> {i + 1, j}},
              "_", {c -> d, d -> e, e -> c},
              _, {}
              ]]
           ) & /@ Characters[
          ++i;
          j = 0;
          #
          ] & /@ {##};
      Sort@VertexOutComponent[Graph@g, g[[1, 1]]] == 
       Union @@ List @@@ g
      ) & @@ v@s[#, "\n"]
) &

यह एक अनाम फ़ंक्शन को परिभाषित करता है जो इनपुट और रिटर्न के रूप में स्ट्रिंग लेता है Trueया False

मूल विचार यह जांचने के लिए है कि एक एकल रूट है, और उसके बाद एक वास्तविक (निर्देशित) Graphऑब्जेक्ट का निर्माण करने के लिए यह जांचने के लिए कि क्या सभी जड़ें रूट से पहुंच सकती हैं। यहाँ हम ग्राफ का निर्माण कैसे करें:

एएससीआईआई कला पर पूर्णांक ग्रिड की कल्पना करें, जहां पूर्णांक निर्देशांक कोशिकाओं के कोनों के अनुरूप हैं। फिर प्रत्येक कोशिकाओं पर छह प्रासंगिक बिंदु होते हैं जिन्हें जोड़ा जा सकता है। यहाँ एक उदाहरण है, जहाँ मैंने बिंदुओं aको भी लेबल किया है f:

     |                 |
     |                 |
---(2,3)---(2.5,3)---(3,2)---
     | d      e      f |
     |                 |
     |                 |
     |                 |
     |                 |
     |                 |
     |                 |
     | a      b      c |
---(2,2)---(2.5,2)---(3,2)---
     |                 |
     |                 |

तो हम एक ग्राफ बना सकते हैं जिसका सिरा इन आधा-पूर्णांक निर्देशांक हैं, और जिनके किनारों को इनपुट में गैर-अंतरिक्ष वर्णों द्वारा निर्धारित किया जाता है। |से जुड़ता bहै e, से /जुड़ता aहै fऔर से \जुड़ता cहै d। ध्यान दें कि इन्हें यह सुनिश्चित करने के लिए किनारों को निर्देशित किया जाना चाहिए कि हम ग्राफ़ को बाद में पीछे करते हुए नीचे की ओर कभी नहीं बढ़ रहे हैं। के लिए _हम किसी भी तरह से जा सकते हैं, इसलिए सिद्धांत रूप में हम चार किनारों की जरूरत है a -> b,b -> a , b -> c, c -> b। हालांकि, हम देख सकते हैं कि सभी मामलों वहाँ एक चक्र तीनों कोने से युक्त है, तो हम तीन किनारों को यह छोटा कर सकते हैं कि यह है कि: a -> b, b -> c, c -> a

इस ग्राफ का निर्माण मैथेमेटिका में काफी सरल है, क्योंकि किसी भी वस्तु, एक शीर्ष के रूप में कार्य कर सकते हैं तो मैं वास्तव में एक ग्राफ जिसका कोने का निर्माण कर सकते हैं समन्वय जोड़े।

अंत में, हम जाँचते हैं कि प्रत्येक शीर्ष को जड़ से पहुँचा जा सकता है। रूट का समन्वय आसानी से बहुत पहले शीर्ष के रूप में पाया जाता है जिसे हमने ग्राफ में जोड़ा है। फिर सबसे छोटा तरीका मैंने यह जांचने के लिए पाया है कि क्या सभी कोने तक पहुंचा जा सकता है या नहीं, यह देखने VertexOutComponentके लिए कि क्या रूट (यानी रूट से उपलब्ध सभी कोने का सेट) ग्राफ में सभी कोने के सेट के समान है या नहीं।


1
300 बाइट लंबी हो सकती हैं, लेकिन वास्तव में 300 इतनी संतोषजनक है!
एलेक्स ए।

2

रूबी 226 227 228

->i{w=i.index(?\n)+1
t=[i.index(/[^ _] *\n\z/)]
a=->x,c{(i[x]==c||i[x]==?_)&&t<<x}
((x=t.pop)&&(s=x-w;c=i[x])<?0?(a[s+1,?/];a[s,?\\]):c<?]?(a[s-1,?\\];a[s,?/]):c<?`?(a[x-1,?\\];a[x+1,?/]):a[s,?|]
i[x]=' ')while t!=[]
!i[/\S/]}

ऑनलाइन टेस्ट: http://ideone.com/Z7TLTt

कार्यक्रम निम्नलिखित करता है:

  • एक रूट के लिए खोज (एक \, /या |अंतिम पंक्ति पर)
  • उस जड़ से शुरू होकर, नियमों का उपयोग करते हुए पेड़ पर चढ़ें और एक जगह के साथ हर आने वाले चार की जगह लें
  • अंत में, देखें कि क्या हमारी स्ट्रिंग पूरी तरह से व्हाट्सएप (जिसका अर्थ वैध पेड़ है) से बना है, या नहीं (अमान्य पेड़; सभी टुकड़े "नहीं गए हैं")

यहाँ यह अपुष्ट है:

F =-> input {
  row_size = input.index(?\n)+1

  root_coord = input.index /[^ _] *\n\z/

  # coordinates to process
  todo = [root_coord]

  add_todo = -> coord, char{
    if input[coord] == char || input[coord] == ?_
      todo << coord
    end
  }

  while todo.any?
    x = todo.pop

    next unless x # exit quickly if no root present

    case input[x]
    when ?|
      add_todo[x - row_size, ?|]
    when ?_
      add_todo[x - 1, ?\\]
      add_todo[x + 1, ?/]
    when ?/
      add_todo[x - row_size + 1, ?/]
      add_todo[x - row_size, ?\\]
    when ?\\
      add_todo[x - row_size - 1, ?\\]
      add_todo[x - row_size, ?/]
    end
    input[x]=' '
  end
  input.strip < ?*
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.