ASCII टोपोलॉजी pt 1: क्या मैं आप पर भरोसा कर सकता हूं?


28

मुझे एक गंभीर समस्या है। मेरे पास कुछ पाठ फाइलें हैं जहां मैं अपनी बहुत महत्वपूर्ण संख्याएं रखता हूं - सभी महत्वपूर्ण! और दोहों, और तेरो ।।

ये संख्याएँ इतनी महत्वपूर्ण थीं कि मैं उन्हें उन newfangled दशमलव या बाइनरी नंबर सिस्टम को नहीं सौंप सकता था। मैंने प्रत्येक संख्या को यूनेरी में इनकोडेड रखा, जैसे:

            +--+
            |  |
+---+  +----+  |
|   |  |       |
+---+  +-------+
   ~/two.txt

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

एक:

   +---+
   |   |
+--+   |
|      |
+--+   |
   |   |
   |   |
   |   |
+--+   +--+
|         |
+---------+

तीन:

+---------+
| +-----+ |
| | +-+ | |
| | | | | |
| | +-+ | |
| +-----+ |
+---------+

चार:

  +--------------+
  |  +--+  +--+  |
  |  |  |  |  |  |
+-|-----|-----|----+
| |  |  |  |  |  | |
| +--+  +--+  +--+ |
+------------------+

              +------------+
              |            |
        +-----+  +-----+   |
        |        |     |   |
  +-----|-----------+  |   |
  |     |  +--+  |  |  |   |
  +-+   +--|--|--+  +---------+
    |      |  +-+      |   |  |
    +------+    |      |   |  |
                +-------+  |  |
                       ||  |  |
                       |+-----+
                       |   |
                       +---+

पंज:

+--------+  +--------+  +--------+
|        |  |        |  |        |
|     +--|-----+  +--|-----+     |
|     |  |  |  |  |  |  |  |     |
+-----|--+  +-----|--+  +--------+
      |        |  |        |
      +--------+  +--------+

क्या आप मेरे छोरों को गिनने में मेरी मदद कर सकते हैं?

ये नियम हैं:

  • चूंकि मैं ASCII-एनकोडेड यूनरी में सब कुछ संग्रहीत करता हूं, इसलिए अंतरिक्ष दक्षता मेरे लिए बहुत महत्वपूर्ण है। इसलिए, यह कोड गोल्फ है। बाइट्स में सबसे छोटा कार्यक्रम जीत जाता है।
  • छोरों को +, -, - | लूप के प्रत्येक कोने को स्पष्ट रूप से खींचा गया है: ऊपर और नीचे के वर्णों में से एक + होगा, और ठीक एक या दाएं या बाएं एक होगा -। दो + अंक कभी आसन्न नहीं होते हैं।
  • स्ट्रैंड एक दूसरे के ऊपर से गुजर सकते हैं। जब स्ट्रैंड क्रॉस होता है, तो आप "अंडर" स्ट्रैंड को "ओवर" स्ट्रैंड के दोनों तरफ तुरंत देख पाएंगे।
  • आपके कार्यक्रम को लूप का एक स्ट्रिंग प्रतिनिधित्व (या तो स्टड से या एक फ़ंक्शन पैरामीटर के रूप में) लेना चाहिए और एक संख्या (या तो स्टडआउट या वापसी मूल्य के रूप में) का उत्पादन करना चाहिए।
  • लूप ड्राइंग में लाइन की लंबाई एक समान नहीं हो सकती है और प्रत्येक लाइन पर अनुगामी स्थान हो सकते हैं।
  • आप मान सकते हैं कि इनपुट में कम से कम एक लूप है।

मुझे आप पर भरोसा है!


क्या 'अंडर स्ट्रैंड' के पक्षों में से एक हो सकता है +?
feersum

@ फैरसम: नहीं, हमेशा से जुड़े दो किनारे दिखाई देंगे।
मैट नोनान

1
@ मार्टिन: मुझे डर नहीं है। मेरा संग्रहण स्थान वास्तव में एक प्रीमियम पर है, इसलिए मैं उन सभी अतिरिक्त स्थानों को नहीं छोड़ सकता।
मैट नोनान

मुझे लगता है कि आपको इसे ( पास्टबीन ) एक परीक्षण मामले के रूप में जोड़ना चाहिए जब तक कि मैं कुछ याद नहीं कर रहा हूं और यह वैध इनपुट नहीं है। 6 छोरें हैं; मैंने इसे केवल स्नेकएक्स सॉल्यूशन के साथ ऑनलाइन परीक्षण किया और यह 12.
ब्लटोरांगे

1
शायद आपको स्पष्ट रूप से मना करना चाहिए या उन छोरों को अनुमति देना चाहिए जो स्वयं को पार करते हैं (उदाहरण के लिए pastebin.com/5RLZuULG ) वर्तमान में, वे रूबी समाधान द्वारा पहचाने जाते हैं, लेकिन स्नेपएक्स समाधान द्वारा नहीं।
ब्लुटोरेंज

जवाबों:


19

SnakeEx - जावास्क्रिप्ट के साथ 98 बाइट्स, बिना 44

यह पाक्षिक चुनौती से मेरी भाषा आज़माने के लिए एक अच्छी समस्या की तरह लग रही थी:

m:({e<>PE}\-[|\-]*<T>\+|[|\-]*<T>)+`\+
e:\+

इसे आज़माने के लिए सबसे अच्छी जगह मेरा ऑनलाइन दुभाषिया है

स्नेकएक्स पाठ में पैटर्न का मिलान "सांप" से करता है जो पाठ से मेल खाने वाले रेगेक्स के चारों ओर घूमता है। कोड एक रेगेक्स की तरह पढ़ता है, सिवाय:

  • <T>अनुदेश। यह एक दिशा-निर्देश है जो सांप को उसकी वर्तमान दिशा से दाएं और बाएं घुमाता है।
  • {e<>PE}एक सबरूटीन कॉल की तरह है। यह एक सांप को eआगे बढ़ने वाली परिभाषा के साथ ( <>) और मापदंडों के साथ P(सूअर का बच्चा - spawning साँप नए साँप का अनुसरण करता है) और E(अनन्य - पहले से मिलान किए गए किसी भी चीज़ से मेल नहीं खाता)। यह विशेष जांच एकमात्र ऐसी चीज है जो सांप को असीम रूप से लूपिंग से रोकती है।
  • `अंत में उपसर्ग इंगित करता है कि क्या निम्न से मेल खाना चाहिए, अगर यह पहले से ही मेल खाता हो, जिसे हम लूप को बंद करने के लिए मजबूर करने के लिए उपयोग कर सकते हैं।

क्योंकि स्नेक्स एक्स रेगेक्स की तरह है और तकनीकी रूप से परिणाम को वांछित रूप से आउटपुट नहीं करता है, मुझे लगता है कि हमें दुभाषिया को बुलाकर कुछ जावास्क्रिप्ट में इसे लपेटने की आवश्यकता है:

function e(s){return snakeEx.run('m:({e<>PE}\\-[|\\-]*<T>\\+|[|\\-]*<T>)+`\\+\ne:\\+',s,1).length}

संपादित करें : यह ब्लोटोरेंज के अतिरिक्त परीक्षण मामलों के साथ काम करने के लिए तय किया गया है


1
+1 मैं वास्तव में इसे पसंद करता हूं, शायद इसलिए कि मैं इसे ऑनलाइन आज़मा सकता हूं और लूप को हाइलाइट कर सकता हूं। लेकिन आप इन दो परीक्षण मामलों की जांच करना चाहते हैं: 1 , 2
ब्लुटोरांगे

@blutorange अच्छा कैच। मैंने सेल्फ-क्रॉसिंग लूप के लिए थोड़ा सा हैकी फिक्स जोड़ा। मुझे परीक्षण केस 1 के बारे में थोड़ा और सोचना होगा, हालाँकि।
BMac

यह ठीक करने के लिए एक आसान है, बस के [^ ]साथ बदलें [|\-];)
blutorange

हह, मुझे यह पता लगाने में बहुत समय लगा कि ऐसा क्यों था। अच्छा निर्णय।
BMac

यह कमाल का है!
इंगो बुर्क

10

सी # - 338 388 433 बाइट्स

1-आयामी सरणी में बदलकर बाइट्स का एक गुच्छा बचाया।

using C=System.Console;using System.Linq;class P{static void Main(){var D=C.In.ReadToEnd().Split('\n');int z,w=D.Max(m=>m.Length)+1,d,c=0;var E=D.SelectMany(l=>l.PadRight(w)).ToList();for(z=E.Count;z-->1;)if(E[z-1]==43)for(d=1,c++;E[z+=d%2<1?w*d-w:d-2]>32;)if(E[z]<44){E[z]=' ';d=d%2>0?z<w||E[z-w]<99?2:0:E[z+1]!=45?1:3;}C.WriteLine(c);}}

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

using C=System.Console;
using System.Linq;

class P
{
    static void Main()
    {
        // read in
        var D=C.In.ReadToEnd().Split('\n');

        int z, // z is position in E
        w=D.Max(m=>m.Length)+1, // w is width
        d, // d is direction of travel (1 == horizontal?, 2 == down/right?)
        c=0; // c is loop count

        // make all the lines the same length
        var E=D.SelectMany(l=>l.PadRight(w)).ToList(); // say no to horizontal bounds checking

        // consume +s
        for(z=E.Count;z-->1;)
            if(E[z-1]==43) // right-most lower-most +
                for(d=1,c++; // go left, increment counter
                    E[z+=d%2<1?w*d-w:d-2]>32 // move z, then check we havn't hit a space (when we do, z is basiclly z - 1)
                    ;)
                    if(E[z]<44) // +
                    {
                        E[z]=' '; // toodles

                        d=
                            d%2>0? // currently horizontal, must go vertical
                                z<w||E[z-w]<99?2 // can't go up, must go down
                                :0 // can go up, go up
                            : // currently vertical, must go horizontal
                                E[z+1]!=45?1 // can't go right, must go left
                                :3 // can go right, go right
                            ;
                    }

        // output result
        C.WriteLine(c);
    }
}

वाह। यह प्रभावशाली है: ओ
मेटोनीम

6

स्लिप , 51 41 + 2 = 43 बाइट्स

$a(`+`-[^ +]*`+(<|>)`|[^ +]*`+#(<|>))+?$A

(अब बड़ी कीमत पर @ blutorange के टेस्ट केस के साथ काम करने के लिए अपडेट किया गया)

चूँकि @BMac ने इस चुनौती के लिए SnakeEx का उपयोग किया, मैंने सोचा कि मैं अपने 2D पैटर्न-मिलान भाषा प्रस्तुत करने की कोशिश करूँगा , स्लिप। लेकिन क्योंकि स्लिप में इस समस्या को हल करने के लिए आवश्यक सुविधाएँ नहीं थीं, इसलिए मैं उन्हें पिछले कुछ दिनों से जोड़ रहा हूँ। दूसरे शब्दों में, यह सबमिशन जीतने के योग्य नहीं है

nमैचों की संख्या के लिए ध्वज के साथ चलाएं , जैसे

py -3 slip.py regex.txt input.txt n

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


व्याख्या

इस सबमिशन में नए फीचर्स के ढेरों के कारण, यह उन्हें शोकेस करने का अच्छा मौका है।

$a                Set custom anchor at current position
(
  `+`-            Match '+-'
  [^ +]*          Match any number of '|' or '-'
  `+              Match a '+'
  (<|>)           Either turn left or turn right
  `|              Match a '|'
  [^ +]*          Match any number of '|' or '-'
  `+              Match a '+'
  #               Prevent next match from moving the match pointer (doubling up on '+')
  (<|>)           Either turn left or turn right
)
+?                Do the above at least once, matching lazily
$A                Make sure we're back where we started

स्लिप हर स्थिति से शुरू होने वाले मैच की कोशिश करता है, और केवल अद्वितीय मैच देता है। ध्यान दें कि हम उपयोग [^ +]करते हैं - जबकि [-|]सैद्धांतिक रूप से दो बाइट्स का उपयोग करते हुए , -चरित्र वर्गों की शुरुआत / अंत में अनसेप्ड अभी तक स्लिप में लागू नहीं किया गया है।


1
@blutorange में वह threeभी है +जो एक -, एक |और 2 स्थान नहीं हैं, इसलिए मैं मान रहा हूं कि यह कोई गलती नहीं है
Sp3000

5

रूबी 295

F=->i{l=i.lines
g={}
l.size.times{|y|i.size.times{|x|l[y][x]==?+&&g[[y,x]]=[[y,x]]}}
c=->a,b{w=g[b]+g[a];w.map{|x|g[x]=w}}
k=g.keys
k.product(k).map{|n,o|
r,p=n
s,q=o
((r==s&&p<q&&l[r][p...q]=~/^\+-[|-]*$/)||(p==q&&r<s&&l[r...s].map{|l|l[p]||c}.join=~/^\+\|[|-]*$/))&&c[n,o]}
g.values.uniq.size}

इसे ऑनलाइन आज़माएं: http://ideone.com/kIKELi ( मैंने #to_aपहली पंक्ति में एक कॉल जोड़ा , क्योंकि ideone.com रूबी 1.9.3 का उपयोग करता है, जो s के #sizeलिए समर्थन नहीं करता है Enumerable। रूबी में 2.1.5+ कोड ठीक चलता है। । )

दृष्टिकोण निम्नलिखित है:

  • +इनपुट में सभी संकेतों की एक सूची बनाएं और उनमें से प्रत्येक को एक अलग आकार पर विचार करें
  • क्षैतिज और ऊर्ध्वाधर रेखाएँ खोजें जो दो +संकेतों को जोड़ती हैं और एक में अपनी आकृतियों को जोड़ती हैं
  • अंत में, विभिन्न आकृतियों की संख्या परिणाम से मेल खाती है

यहाँ एक और अधिक पठनीय संस्करण है:

def ascii_topology_count(input)
  lines = input.lines
  max_length = lines.map(&:size).max

  # hash in which the keys are corners ("+"s), represented by their [y, x] coords
  # and the values are arrays of corners, representing all corners in that group
  corner_groups = {}

  lines.size.times { |y|
    max_length.times { |x|
      if lines[y][x] == ?+
        corner_groups[[y, x]] = [[y, x]]
      end
    }
  }

  # function that combines the groups of two different corners
  # into only one group
  combine_groups =-> c1, c2 {
    g1 = corner_groups[c1]
    g2 = corner_groups[c2]

    g2 += g1
    corner_groups[c1] = g2
    g2.map{|x| corner_groups[x] = g2}
  }

  corner_groups.keys.product(corner_groups.keys).map{|c1, c2|
    y1,x1=c1
    y2,x2=c2
    if y1 == y2 && x1 < x2
      # test horizontal edge
      t = lines[y1][x1...x2]
      if t =~ /^\+-[|-]*$/
        # p "#{c1}, #{c2}, [H] #{t}"
        combine_groups[c1, c2]

      end
    end

    if x1 == x2 && y1 < y2
      # test vertical edge
      t=lines[y1...y2].map{|l|l[x1]||' '}.join

      if t =~ /^\+\|[|-]*$/
        # p "#{c1}, #{c2}, [V] #{t}"
        combine_groups[c1, c2]
      end
    end
  }

  corner_groups.values.uniq.count
end

5

जावास्क्रिप्ट (ईएस 6) 190 197 202 215 235 289 570

2 आयाम के बजाय एकल आयाम सरणी संपादित करें , अधिकतम पंक्ति आकार 999 वर्ण (लेकिन बिना किसी लागत के अधिक हो सकता है, उदाहरण के लिए 999 के बजाय 1e5)

संपादित करें जोड़ा गया एनिमेटेड कोड स्निपेट, नीचे देखें

F=s=>[...s.replace(/.+/g,r=>r+Array(e-r.length),e=999)]
  .map((c,x,z,d=1,f='-',g='|')=>{
    if(c=='+')
      for(++n;z[x+=d]!='+'||([f,g,e,d]=[g,f,d,z[x-e]==g?-e:z[x+e]==g&&e],d);)
        z[x]=z[x]==g&&g
  },n=0)|n

अनगुल्ड पहले प्रयास करें

f=s=>
{
  cnt=0
  s = (1+s+1).split(/[1\n]/)

  for(;x=-1, y=s.findIndex(r=>~(x=r.indexOf('+-'))), x>=0;++cnt)
  {
    //console.log(y+' '+x+' '+s.join('\n'))
    dx = 1
    for(;dx;)
    {
      a=s[y-1],b=s[y+1],
      r=[...s[y]]
      for(r[x]=' ';(c=r[x+=dx])!='+';)
      {
        if (c=='-')
          if((a[x]||b[x])=='|')r[x]='|';
          else r[x]=' ';
      }  

      if(a[x]=='|')dy=-1;
      else if(b[x]=='|')dy=1;
      else dy=0
      r[x]=' '
      s[y]=r.join('')
      if (dy) {
        for(;y+=dy,r=[...s[y]],(c=r[x])!='+'&c!=' ';)
        {
          if (c=='|') 
            if((r[x-1]||r[x+1])=='-')r[x]='-';
            else r[x]=' ';
          s[y]=r.join('')
        }  
        if(r[x-1]=='-')dx=-1;
        else if(r[x+1]=='-')dx=1;
        else dx=0;
      }
    }  
  }
  return cnt
}

एनिमेटेड स्निपेट

फ़ायरफ़ॉक्स / फायरबग कंसोल में टेस्ट करें

F('\
  +--------------+\n\
  |  +--+  +--+  |\n\
  |  |  |  |  |  |\n\
+-|-----|-----|----+\n\
| |  |  |  |  |  | |\n\
| +--+  +--+  +--+ |\n\
+------------------+\n\
\n\
              +------------+\n\
              |            |\n\
        +-----+  +-----+   |\n\
        |        |     |   |\n\
  +-----|-----------+  |   |\n\
  |     |  +--+  |  |  |   |\n\
  +-+   +--|--|--+  +---------+\n\
    |      |  +-+      |   |  |\n\
    +------+    |      |   |  |\n\
                +-------+  |  |\n\
                       ||  |  |\n\
                       |+-----+\n\
                       |   |\n\
                       +---+')

4

F('\
+--------+  +--------+  +--------+\n\
|        |  |        |  |        |\n\
|     +--|-----+  +--|-----+     |\n\
|     |  |  |  |  |  |  |  |     |\n\
+-----|--+  +-----|--+  +--------+\n\
      |        |  |        |\n\
      +--------+  +--------+')

5


निश्चित रूप से आप गोल्फ संस्करण के सिंगल-लाइनिंग द्वारा कुछ बाइट्स बचाएंगे? आप केवल एक अनाम फ़ंक्शन भी बना सकते हैं (मुझे लगता है कि कोडगोल्फ के नियमों के भीतर है)
Theonlygusti

@Theonlygusti गोल्फ संस्करण को सिंगल-लाइन के रूप में गिना जाता है (कोई नई रेखाएं और इंडेंटेशन रिक्त स्थान नहीं गिना जाता है)। एक अनाम फ़ंक्शन के साथ मैं 2 बाइट्स बचाता हूं, नगण्य बचत ...
edc65

4

रूबी, 178 187 199 212

बेहतर रूबी संस्करण, एक फ़ंक्शन बनाता है एफ। अब अधिक स्वादिष्ट दुभाषिया चेतावनियों के साथ लगातार।

b=->n{Q[I]=?~
d=Q[I+n]==(n>1??|:?-)?1:-1
loop{I+=d*n
b[n>1?1:N]if Q[I]==?+
Q[I]<?~?4:break}}
F=->s{N=s.size;Q=s+?\n
Q.gsub!(/^.*$/){$&.ljust N-1}
(0..N).find{!(I=Q=~/\+/)||b[1]}}

इसे ऑनलाइन टेस्ट करें: आइडोन

मूल रूप से, फ़ंक्शन bकिसी भी समय शुरू होता है +, पुनरावर्ती लूप से गुजरता है, सभी +को सेट करता है u। इस प्रकार एक लूप हटा दिया जाता bहै जिसे हर बार कहा जाता है। फ़ंक्शन Fकेवल कोशिश करता है कि हमें कितनी बार कॉल करने की आवश्यकता है bजब तक कि कोई लूप शेष न हो।


2

अजगर 2 - 390

स्टड से newlines के साथ एक स्ट्रिंग लेता है। यह एक बहुत ही सरल विधि है जो एक निष्पक्ष सा है, लेकिन मुझे यकीन है कि यह जितना लंबा हो सकता है, उतना नहीं है।

s=raw_input().split('\n');L=len
def R(x,y):
 b=p,q=x,y;u=v=f=0
 while b!=(p,q)or not f:
    p+=u;q+=v;f=u+v;c=s[q][p]
    if'+'==c:u,v=[(i,j)for i,j in{(-1,0),(1,0),(0,-1),(0,1)}-{(-u,-v)}if 0<=q+j<L(s)and 0<=p+i<L(s[q+j])and s[q+j][p+i]in['-+','|+'][j]][0];s[q]=s[q][:p]+' '+s[q][p+1:]
    if c+s[q+v][p+u]in'-|-':p+=u;q+=v
print L([R(x,y)for y in range(L(s))for x in range(L(s[y]))if'+'==s[y][x]])

1

पायथन 2 - 346 बाइट्स

एक फ़ंक्शन के रूप में कार्यान्वित किया cजाता है जो फ़ाइल डेटा को इनपुट के रूप में लेता है और लूप की संख्या लौटाता है।

सबसे पहले, फ़ंक्शन डेटा को उस स्थान (जैसे {(0,0): '+'}) पर तत्व प्रकार के लिए लूप तत्व स्थानों के मानचित्रण के लिए विघटित करता है । फिर, यह दो परस्पर-पुनरावर्ती आंतरिक कार्यों का उपयोग करता है। पहले मैपिंग से एक लूप सेगमेंट को हटाता है और बाद के सेगमेंट के लिए कौन से स्थानों की जाँच करता है, यह तय करता है। दूसरा चेक करता है कि चयनित स्थानों में किस तरह का लूप तत्व है और अगर यह अपेक्षित है तो यह अनुकूल है, नए पाए गए खंड को हटाने के लिए सबसे पहले कॉल करता है।

e=enumerate
def c(d):
 D={(i,j):k for i,l in e(d.split('\n'))for j,k in e(l)if k in'+-|'}
 def f(r,c,R,C,t):
  if D.get((r,c),t)!=t:g(r,c)
  elif D.get((R,C),t)!=t:g(R,C)
 def g(r,c):
  t=D.pop((r,c))
  if t!='|':f(r,c-1,r,c-2,'|');f(r,c+1,r,c+2,'|')
  if t!='-':f(r-1,c,r-2,c,'-');f(r+1,c,r+2,c,'-')
 n=0
 while D:g(*D.keys()[0]);n+=1
 return n
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.