रास्ते खोजो!


10

आपको एक प्रोग्राम या फंक्शन लिखना होगा।

इनपुट संख्याओं का 'मानचित्र' है। आप नई पंक्ति वर्ण ( \n) या स्ट्रिंग के 2 डी सरणी के साथ मानचित्र को या तो एक स्ट्रिंग के रूप में लेने का विकल्प चुन सकते हैं ।

सभी मानचित्र 5 वर्णों के 5 वर्ण हैं, और वर्ण हमेशा 0 या रिक्त स्थान से अधिक अंकों वाले होते हैं।

यहाँ एक मानचित्र का उदाहरण दिया गया है:

12 45
11233
  233
    1
2 899

आपका कार्य मानचित्र में जुड़े घटकों को खोजना है। एक वैध घटक कम से कम तीन क्षैतिज और / या लंबवत ( तिरछे नहीं ) समान रूप से जुड़े समान अंकों ( रिक्त स्थान नहीं ) की एक श्रृंखला है । फिर आपको xएस और प्रिंट के साथ वैध जुड़े घटकों के पात्रों को बदलने और उस परिणाम को वापस करने की आवश्यकता होगी ।

तो, उपरोक्त उदाहरण के लिए आउटपुट होगा:

x2 45
xx2xx
  2xx
    1
2 899

यहाँ एक और परीक्षण मामला है (मार्टिन एंडर का धन्यवाद):

Input:
2   3
    4
 1  5
111 6
11  7

Output:
2   3
    4
 x  5
xxx 6
xx  7

यह कोड गोल्फ है इसलिए बाइट्स जीत में सबसे छोटा कोड है!



बिल्ट-इन की अनुमति है?
Ioannes

@ जॉन्स, हाँ।
डैनियल

जवाबों:


1

जावास्क्रिप्ट (ईएस 6), 171 161 139 137 136 133 132 बाइट्स

f=(a,i=0)=>(F=i=>" "<c&&a[i]===c&&(a[i]=n,1+F(i-1)+F(i+1)+F(i-6)+F(i+6)),n=1,c=a[i],n=F(i)>2?"x":c,c=1,F(i),i>28?a:f(a,++i+(i%6>4)))
<!-- this HTML included just for testing --><textarea rows=5 cols=6 oninput="document.querySelector`pre`.innerHTML=this.value.length==29?f([...this.value]).join``:'invalid input'">12 45&#10;11233&#10;  233&#10;    1&#10;2 899</textarea><br/><pre></pre>

यह मेरे पायथन उत्तर का अनुवाद है। I / O चरित्र सरणियों के रूप में।

बहुत बुरा करने का कोई कारगर तरीका नहीं है sum...


5

पायथन 3, 238 237 200 199 192 181 बाइट्स

def f(a,i=0):F=lambda i,n,c:29>i>=0!=" "!=a[i]==c!=n and(a.__setitem__(i,n)or-~sum(F(i+j,n,c)for j in[-1,1,-6,6]));j=i+i//5;F(j,[a[j],"x"][2<F(j,1,a[j])],1);i>23or f(a,i+1);return a

एक फ़ंक्शन को परिभाषित करता f(a)है जो इनपुट को वर्णों के एक सरणी के रूप में लेता है और उसी सरणी को संशोधित करता है। ( वर्णों की सारणियाँ डिफ़ॉल्ट रूप से तार के रूप में स्वीकार्य हैं। )

स्पष्टीकरण के साथ असंगठित

संशोधित कोड पुनरावर्ती है, लेकिन समान काम करता है।

# The main function; fills all continuous nonempty areas of size >= 3 in array
# with x's. Both modifies and returns array.
def findpaths(array):
    # Fills a continuous area of curr_char in array with new_char, starting
    # from index. Returns the number of cells affected.
    def floodfill(index, new_char, curr_char):
        if (0 <= index < 29                   # Check that the position is in bounds
                and (index + 1) % 6 != 0      # Don't fill newlines
                and array[index] != " "       # Don't fill empty cells
                and array[index] == curr_char # Don't fill over other characters
                and curr_char != new_char):   # Don't fill already filled-in cells
            array[index] = new_char # Fill current position
            return (1 # Add neighboring cells' results, plus 1 for this cell
                    + floodfill(index + 1, new_char, curr_char)  # Next char
                    + floodfill(index - 1, new_char, curr_char)  # Previous char
                    + floodfill(index + 6, new_char, curr_char)  # Next line
                    + floodfill(index - 6, new_char, curr_char)) # Previous line
        return 0 # Nothing was filled. The golfed solution returns False here,
                 # but that's coerced to 0 when adding.

    for i in range(25): # Loop through the 25 cells
        i += i // 5 # Accommodate for newlines in input
        curr_char = array[i] # Get the cell's contents
        # Fill the area from the cell with dummies
        area_size = floodfill(i, 1, curr_char)
        # Convert dummies to "x" if area was large enough, back to original otherwise
        fill_char = "x" if 2 < area_size else curr_char
        floodfill(i, fill_char, 1)
    return array

गणितज्ञ समाधान को हराने के लिए 2 बाइट्स ...
21

1
@FlipTack हाँ। मुझे नहीं लगता कि यह आज हो रहा है, लेकिन मैं इसे जेएस में अनुवाद कर रहा हूं और यह आशाजनक लग रहा है।
PurkkaKoodari

3

रूबी, 304 बाइट्स

def b(s,i)
  @v=[]
  b2(s,i,s[i])
end
def b2(s,i,c)
  if(0...s.size)===i&&s[i]==c&&!@v[i]
    @v[i]=s[i]='x'
    [1,-1,6,-6].each{|j|b2(s,i+j,c)}
  end
  s
end
def f(s)
  z = s.dup
  ps = ->(i){b(z.dup,i).scan('x').size}
  (0...s.size).each{|i|b(s, i)if ![' ',"\n"].include?(s[i])&&ps.call(i)>2}
  s
end

उदाहरण का उपयोग:

puts f(File.read("map.txt"))

कोड लंबाई पथ की गणना करने के लिए 'धब्बा' विधि का पुन: उपयोग करता है।

चर / विधि:

  • f (s): मैप स्ट्रिंग बदलने के लिए फ़ंक्शन, 'x's के साथ नया मैप देता है
  • ps (i): मैप इंडेक्स i (जहाँ x = i% 6, y = i / 6) से पथ का आकार
  • s: इनपुट स्ट्रिंग, मैप लाइनें "\ n" द्वारा अलग की गईं
  • z: इनपुट स्ट्रिंग की प्रतिलिपि
  • b (s, i): 'blot' फंक्शन: मैप इंडेक्स i ओवर पाथ्स से 'x' लिखता है
  • @v: 'विज़िट' एरे

अधिक विस्तृत विवरण पर प्रयास करें:

इनपुट स्ट्रिंग की एक प्रतिलिपि बनाएँ, जिसका उपयोग हम नक्शे में किसी भी बिंदु से पथ की लंबाई खोजने के लिए करते हैं।

z = s.dup

एक 'पीएस' (पथ लंबाई) अनाम फ़ंक्शन (लंबो) को परिभाषित करता है जो एक तर्क के रूप में मानचित्र सूचकांक को लेता है। यह उस बिंदु से पथ की लंबाई लौटाता है। यह मूल नक्शे की एक प्रति पर एक्स को सम्मिलित करने के लिए 'बी' (धब्बा) विधि को कॉल करके करता है और फिर लौटे स्ट्रिंग में x की संख्या की गिनती करता है।

  ps = ->(i){b(z.dup,i).scan('x').size}

निम्नलिखित भाग मानचित्र में प्रत्येक वर्ण (सूचकांक I, वर्ण s [i]) पर प्रसारित होता है। यदि मैं स्थिति से पथ की लंबाई 2 से अधिक है, और यदि यह कोई स्थान या न्यूलाइन वर्ण नहीं है, तो मैं मानचित्र स्थिति पर 'b' (धब्बा) फ़ंक्शन को कॉल करता हूं।

  (0...s.size).each { |i|
     b(s, i) if ![' ',"\n"].include?(s[i]) && ps.call(i) > 2
  }

बी (धब्बा) फ़ंक्शन मानचित्र स्ट्रिंग और एक सूचकांक को तर्क के रूप में लेता है। यह @v (विज़िट की गई सरणी) को आरंभ करता है और b2 सहायक फ़ंक्शन को कॉल करता है।

def b(s,i)
  @v=[]
  b2(s,i,s[i])
end

b2 फंक्शन मैप स्ट्रिंग, मैप पोजीशन (i), और करंट पाथ (c) में एक कैरेक्टर लेता है। यह अंकों के जुड़े वर्गों को 'x' वर्ण से बदलने के लिए स्वयं को पुनरावर्ती कहता है। यह इनपुट स्ट्रिंग लौटाता है (यह ऐसा है कि पीएस फ़ंक्शन रिटर्न मान पर स्कैन () कॉल कर सकता है)।

यदि यह कथन जाँच रहा है कि दिया गया मानचित्र स्थिति (i) स्ट्रिंग की सीमा के भीतर है (0 ... s.size) और यह कि चरित्र [s] प्रारंभिक वर्ण के समान है। अनंत पुनरावृत्ति से बचने के लिए भी @v [i] की जाँच की जाती है।

if(0...s.size) === i && s[i] == c && !@v[i]

यह वह बिट है जो वर्ण को 'x' वर्ण के साथ अनुक्रमणिका (i) में बदलता है। यह उस इंडेक्स को भी चिह्नित करता है जो विज़िट किया गया था।

@v[i] = s[i] = 'x'

यह वह जगह है जहां b2 कॉल खुद को पुन: खोजता है। i + 1 दाईं ओर एक वर्ण है, i-1 बाईं ओर एक वर्ण है, i + 6 एक पंक्ति नीचे है (5 अंक + 1 नई पंक्ति = 6 वर्ण), i-6 एक पंक्ति ऊपर है।

[1,-1,6,-6].each { |j| b2(s, i+j, c) }

1

सी (एएनआई), 243 233 179 188 बाइट्स

golfed:

#define O o[1][l]
x,n,l,L;r(o,l)char**o;{if(!(l>L|l<0|O<47|O!=x))n++,O++,r(o,l-1),r(o,l+6),r(o,l-6),r(o,l+1),n>2?O='x':O--;}main(g,o)char**o;{for(;(L=30)>l;l++)n=0,x=O,r(o,l);puts(o[1]);}

एनोटेशन के साथ:

#define O o[1][l]
x,n,l,L;      /*-------------------------- Globals*/
r(o,l)char**o;{ /*------------------------ Recursive Function*/
    if(!(l>L|l<0|O<47|O!=x)) /*----------- if this cell is valid(in
                                              range, is a number, is the 
                                              same as the parent number*/
    n++,     /*--------------------------- Increment count*/
    O++,     /*--------------------------- Increment character to mark*/
    r(o,l-1),  /*------------------------- Recurse left*/
    r(o,l+6),  /*------------------------- Recurse down*/
    r(o,l-6),  /*------------------------- Recurse down*/
    r(o,l+1),  /*------------------------- Recurse right*/
    n>2?O='x':O--;  /*---------------------If greater than 3, replace with x, else decrement character*/ 
}          /*----------------------------- Return*/

main(g,o)char**o;{ /*--------------------- Main*/
    for(;l<(L=30);l++){ /*---------------- For entire string and set L*/
        n=0;
        x=O;        /*-------------------- set counter to 0*/
        r(o,l); /*------------------------ Recurse*/
    } /*---------------------------------- End While*/
    puts(o[1]); /*------------------------ Print*/

}

इनपुट:

स्ट्रिंग की शुरुआत और अंत में एक नई रेखा की उम्मीद है।

उदाहरण इनपुट:

./findPaths "
12 45
11233
  233
    1
2 899
"

उदाहरण आउटपुट:

x2 45
xx2xx
  2xx
    1
2 899

अपडेट करें

ग्रिड को ठीक करने से मुझे लगभग 60 बाइट्स से दाढ़ी बनाने की अनुमति मिली।


मुझे लगता है कि मैं 22 पात्रों की तरह बचा सकता हूं यदि मैं इसे फिक्स मैप के आकार में बदल देता हूं - मैं
बदलूंगा

1

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

(f=Flatten@#;p=Partition)[If[Tr[1^VertexComponent[r~Graph~Cases[##&@@p[#,2,1]&/@Join[g=p[r,5],g],{a_,b_}/;(A=f[[a]])==f[[b]]&&A!=" ":>a<->b],#]]<3,f[[#]],"x"]&/@(r=Range@25),5]&

स्पष्टीकरण:

(f=Flatten@#;p=Partition)[
  If[
    Tr[1^VertexComponent[
        r~Graph~Cases[
          ##&@@p[#,2,1]&/@Join[g=p[r,5],g],
          {a_,b_}/;(A=f[[a]])==f[[b]]&&A!=" ":>a<->b
        ],
        #
      ]]<3,
    f[[#]],
    "x"
  ]&/@(r=Range@25),
  5
]&

शुद्ध कार्य जो एक 5x5सरणी को स्वीकार करता है । 3-बाइट निजी-उपयोग चरित्र है U+F3C7जो पोस्टफ़िक्स ट्रांसपोज़ ऑपरेटर का प्रतिनिधित्व करता है \[Transpose]

(f=Flatten@#;p=Partition): इनपुट सूची को समतल करता है और इसमें संग्रहीत करता है f। सेट करता है p = Partitionऔर उसे लौटाता है।

g=p[r,5]: सरणी {{1,2,3,4,5}, ..., {21,22,23,24,25}}(यह इसलिए है क्योंकि rसेट हो जाता है Range@25)।

Join[g=p[r,5],g]: पंक्तियों और स्तंभों की सूची g

p[#,2,1]&: शुद्ध कार्य जो ओवरलैप के साथ #लंबाई के उप सूची में विभाजन को विभाजित करता 2है 1; यानी, आसन्न जोड़े की सूची #

##&@@p[#,2,1]&: ऊपर के रूप में एक ही इसे छोड़कर एक Sequence

##&@@p[#,2,1]&/@Join[g=p[r,5],g]: gआसन्न प्रविष्टियों में से सभी की एक सूची प्राप्त करने के लिए पंक्तियों और स्तंभों के पिछले फ़ंक्शन को मैप करें g। मेरा पेट कहता है कि ऐसा करने का एक छोटा तरीका है।

r~Graph~Cases[...]: ग्राफ़ जिनके कोने पूर्णांक हैं 1, ..., 25और जिनके किनारे आसन्न प्रविष्टियों के बीच के किनारे हैं gजिनमें इनपुट सरणी में समान अनुवर्ती प्रविष्टियाँ हैं (अन्य के अलावा " ")

{a_,b_}/;(A=f[[a]])==f[[b]]&&A!=" ": पैटर्न जो {a,b}इस तरह से मेल खाता है f[[a]] == f[[b]](इनपुट सरणी में समान मूल्य) और जो इसके बराबर नहीं हैं " "। बाइट A = f[[a]]बचाने के लिए सेट करें 1

...:>a<->b: हर मैच को एक अप्रत्यक्ष रूप से किनारे से b में बदलें।

VertexComponent: पहले तर्क (एक ग्राफ) में दूसरे तर्क (एक शीर्ष) के जुड़े घटक देता है।

Tr[1^VertexComponent[...]]: जुड़े घटक का आकार। 1से बाइट बचाता है Length@VertexComponent[...]

If[Tr[...]<3,f[[#]],"x"]&: शुद्ध कार्य जो एक प्रविष्टि लेता #है g। यदि इसके जुड़े घटक का आकार इससे कम है 3, तो इसे इनपुट में संबंधित प्रविष्टि के साथ बदलें। अन्यथा, इसके साथ बदलें "x"

(f=Flatten@#;p=Partition)[...,5]: और अंत में परिणाम को एक 5x5सरणी के रूप में बदल दें।


0

क्लोजर, 188 बाइट्स

यह काफी भारी है: डी

#(apply str(map-indexed(fn[i v](if((set(flatten(for[m(range 30)](let[n(for[p[-1 -6 1 6]:when(=(get %(+ m p)0)((set"123456789")(% m)))](+ m p))](if(< 1(count n))(conj n m)[])))))i)\x v))%))

इस तरह कहा जाता है (यह वर्णों का 1D वेक्टर लेता है):

(def f #(apply str(...))

(print (str "\n" (f (vec (str "12 45\n"
                              "11233\n"
                              "  233\n"
                              "    1\n"
                              "2 899\n")))))

(print (str "\n" (f (vec (str "2   3\n"
                              "    4\n"
                              " 1  5\n"
                              "111 6\n"
                              "11  7\n")))))

इसे अनगल करने के लिए बहुत आलसी है, लेकिन मूल रूप से for[m(range 30)]प्रत्येक सूचकांक पर जाता है और प्रत्येक सूचकांक के लिए आंतरिक let[n(for[p[-1 -6 1 6]...(+ m p))]0 से 4 तत्वों की सूची बनाता है जो उन स्थानों को सूचीबद्ध करता है जिनके बीच के स्थान के समान मूल्य (1 - 9) था। यदि 1 से अधिक पड़ोसी मिड पीस से मेल खाते हैं, तो इसका मतलब है कि ये सभी एक क्लस्टर बनाते हैं, इसलिए उन स्थानों को सेट में उपयोग किया जाता है (if((set(flatten(...)))i)। यदि सूचकांक iसेट से पाया जाता है तो \xउत्सर्जित होता है और मूल मूल्य अन्यथा। यह :when( ... )काफी दिलचस्प है ...

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