बैश ब्रेस का विस्तार करें


20

ज्यादातर ऐतिहासिक कारणों से, बैश काफी वाक्यविन्यास और प्रोग्रामिंग प्रतिमानों का एक शौक-चकमा है - यह इसे अजीब और कभी-कभी गोल्फ के लिए निराशाजनक बना सकता है। हालांकि इसकी आस्तीन में कुछ चालें होती हैं जो अक्सर अन्य मुख्यधारा की स्क्रिप्ट के साथ प्रतिस्पर्धा कर सकती हैं। भाषाओं। इनमें से एक ब्रेस विस्तार है

ब्रेस विस्तार के दो मूल प्रकार हैं:

  • सूची ब्रेसिज़ में मनमाने तार (डुप्लिकेट और खाली स्ट्रिंग सहित) की अल्पविराम से अलग की गई सूची हो सकती है। उदाहरण के लिए (खाली तारों के चारों ओर रिक्त स्थान पर ध्यान दें) का {a,b,c,,pp,cg,pp,}विस्तार होगा a b c pp cg pp
  • अनुक्रम ब्रेसिज़ अनुक्रम एंडपॉइंट द्वारा अलग हो सकते हैं ..। वैकल्पिक रूप से एक और ..का पालन कर सकते हैं, एक कदम आकार के बाद। अनुक्रम समापन बिंदु पूर्णांक या वर्ण हो सकते हैं। अनुक्रम स्वचालित रूप से चढ़ेगा या उतरेगा जिसके अनुसार समापन बिंदु अधिक है। उदाहरण के लिए:
    • {0..15} तक विस्तार होगा 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
    • {-10..-5} तक विस्तार होगा -10 -9 -8 -7 -6 -5
    • {3..-6..2} तक विस्तार होगा 3 1 -1 -3 -5
    • {a..f} तक विस्तार होगा a b c d e f
    • {Z..P..3} तक विस्तार होगा Z W T Q

इसके अलावा, अनुक्रम और सूची ब्रेसिज़ सूची ब्रेसिज़ के साथ मौजूद हो सकते हैं:

  • {a,b,{f..k},p} तक विस्तार होगा a b f g h i j k p
  • {a,{b,c}} तक विस्तार होगा a b c

ब्रेस गैर-व्हाट्सएप तारों के साथ दोनों ओर विस्तारित होते हैं। उदाहरण के लिए:

  • c{a,o,ha,}t तक विस्तार होगा cat cot chat ct

यह एक साथ कई ब्रेसिज़ के लिए भी काम करता है:

  • {ab,fg}{1..3} तक विस्तार होगा ab1 ab2 ab3 fg1 fg2 fg3

यह काफी जटिल हो सकता है। उदाहरण के लिए:

  • {A..C}{x,{ab,fg}{1..3},y,} तक विस्तार होगा Ax Aab1 Aab2 Aab3 Afg1 Afg2 Afg3 Ay A Bx Bab1 Bab2 Bab3 Bfg1 Bfg2 Bfg3 By B Cx Cab1 Cab2 Cab3 Cfg1 Cfg2 Cfg3 Cy C

हालांकि, अगर विस्तार के बीच व्हाट्सएप है, तो वे बस अलग-अलग विस्तार के रूप में विस्तार करते हैं। उदाहरण के लिए:

  • {a..c} {1..5} तक विस्तार होगा a b c 1 2 3 4 5

ध्यान दें कि ऑर्डर हमेशा कैसे संरक्षित किया जाता है।


इस चुनौती के लिए प्रविष्टियाँ बैश ब्रेस विस्तार का विस्तार करेगी जैसा कि ऊपर वर्णित है। विशेष रूप से:

  • द्वारा bash(या अन्य गोले जो समान विस्तार करते हैं) की अनुमति नहीं है
  • अनुक्रम ब्रेसिज़ हमेशा नंबर-टू-नंबर, लोअरकेस-टू-लोअरकेस या अपरकेस-टू-अपरकेस होगा जिसमें कोई मिश्रण नहीं होगा। नंबर 32-बिट हस्ताक्षरित सीमा में पूर्णांक होंगे। यदि दिया जाता है, तो वैकल्पिक चरण आकार हमेशा एक सकारात्मक पूर्णांक होगा। (ध्यान दें कि बैश का भी विस्तार होगा {A..z}, लेकिन इस चुनौती के लिए इसे नजरअंदाज किया जा सकता है)
  • सूची ब्रेसिज़ में अलग-अलग आइटम हमेशा केवल ऊपरी और निचले मामले के अल्फ़ान्यूमेरिक वर्ण (खाली स्ट्रिंग शामिल) से बने होंगे
  • सूची ब्रेस में अन्य ब्रेस विस्तार के मनमाने ढंग से घोंसले हो सकते हैं
  • ब्रेसिज़ को मनमाने ढंग से संख्या के आधार पर समवर्ती किया जा सकता है। यह आपकी भाषा की मेमोरी द्वारा सीमित होगा, इसलिए यह अपेक्षा की जाती है कि आप सैद्धांतिक रूप से संख्या की मनमानी कर सकते हैं, लेकिन यदि / जब आप स्मृति से बाहर निकलते हैं जो आपके खिलाफ नहीं गिना जाएगा।

ऊपर दिए गए पाठ में उदाहरण वृषण के रूप में कार्य करते हैं। संक्षेप, आउटपुट की एक ही लाइन के अनुरूप इनपुट की प्रत्येक पंक्ति के साथ, वे हैं:

इनपुट

{0..15}
{-10..-5}
{3..-6..2}
{a..f}
{Z..P..3}
{a,b,{f..k},p}
{a,{b,c}}
c{a,o,ha,}t
{ab,fg}{1..3}
{A..C}{x,{ab,fg}{1..3},y,}
{a..c} {1..5}
{a{0..100..10},200}r

उत्पादन

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
-10 -9 -8 -7 -6 -5
3 1 -1 -3 -5
a b c d e f
Z W T Q
a b f g h i j k p
a b c
cat cot chat ct
ab1 ab2 ab3 fg1 fg2 fg3
Ax Aab1 Aab2 Aab3 Afg1 Afg2 Afg3 Ay A Bx Bab1 Bab2 Bab3 Bfg1 Bfg2 Bfg3 By B Cx Cab1 Cab2 Cab3 Cfg1 Cfg2 Cfg3 Cy C
a b c 1 2 3 4 5
a0r a10r a20r a30r a40r a50r a60r a70r a80r a90r a100r 200r

3
मैंने इस पर ध्यान दिया और यह सभी किनारे के मामलों के कारण बस दर्द को दूर करने के लिए है :-(
नील

जवाबों:


3

रूबी, 405 403 401 400 बाइट्स

एक बुद्धिमान व्यक्ति (जेमी ज़्विन्स्की) ने एक बार कहा था, "कुछ लोग, जब एक समस्या का सामना करते हैं, तो सोचते हैं कि 'मुझे पता है, मैं नियमित अभिव्यक्ति का उपयोग करूँगा।" अब उन्हें दो समस्याएं हैं। ''

मुझे नहीं लगता कि मैंने उस उद्धरण की पूरी तरह से सराहना की जब तक मैंने पुनरावर्ती rexx के साथ इस समस्या को हल करने की कोशिश नहीं की। प्रारंभ में, रेगेक्स के मामले सरल लग रहे थे, जब तक मुझे कोष्ठक से सटे पत्रों से जुड़े किनारे के मामलों से निपटना नहीं था, और तब मुझे पता था कि मैं नरक में था।

वैसे भी, इसे ऑनलाइन यहां परीक्षण मामलों के साथ चलाएं

->s{s.gsub!(/{(-?\w+)..(-?\w+)(..(\d+))?}/){x,y=$1,$2;a,b,c=[x,y,$4].map &:to_i
$1[/\d/]?0:(a,b=x,y)
k=a<b ?[*a..b]:[*b..a].reverse
?{+0.step(k.size-1,$4?c:1).map{|i|k[i]}*?,+?}}
r=1
t=->x{x[0].gsub(/^{(.*)}$/){$1}.scan(/(({(\g<1>|,)*}|[^,{}]|(?<=,|^)(?=,|$))+)/).map{|i|i=i[0];i[?{]?r[i]:i}.flatten}
r=->x{i=x.scan(/({(\g<1>)*}|[^{} ]+)/).map(&t)
i.shift.product(*i).map &:join}
s.split.map(&r)*' '}

Ungolfed:

->s{
  s.gsub!(/{(-?\w+)..(-?\w+)(..(\d+))?}/){  # Replace all range-type brackets {a..b..c}
    x,y=$1,$2;a,b,c=[x,y,$4].map &:to_i     # Set up int variables
    $1[/\d/]?0:(a,b=x,y)                    # Use int variables for a,b if they're numbers
    k=a<b ?[*a..b]:[*b..a].reverse          # Create an array for the range in the correct direction
    '{'+                                    # Return the next bit surrounded by brackets
      0.step(k.size-1,$4?c:1).map{|i|k[i]   # If c exists, use it as the step size for the array
      }*','                                 # Join with commas
      +'}'
  }
  r=1                                       # Dummy value to forward-declare the parse function `r`
  t=->x{                                    # Function to parse a bracket block
    x=x[0].gsub(/^{(.*)}$/){$1}             # Remove outer brackets if both are present
                                            # x[0] is required because of quirks in the `scan` function
    x=x.scan(/(({(\g<1>|,)*}|[^,{}]|(?<=,|^)(?=,|$))+)/)
                                            # Regex black magic: collect elements of outer bracket
    x.map{|i|i=i[0];i[?{]?r[i]:i}.flatten   # For each element with brackets, run parse function
  }
  r=->x{                                    # Function to parse bracket expansions a{b,c}{d,e}
    i=x.scan(/({(\g<1>)*}|[^{} ]+)/)        # Regex black magic: scan for adjacent sets of brackets
    i=i.map(&t)                             # Map all elements against the bracket parser function `t`
    i.shift.product(*i).map &:join          # Combine the adjacent sets with cartesian product and join them together
  }
  s.split.map(&r)*' '                       # Split on whitespace, parse each bracket collection
                                            #   and re-join with spaces
}

2

पायथन 2.7, 752 728 बाइट्स

वाह, यह एक चुनौती में कोड गोल्फ का एक गुच्छा की तरह है!

एक लंबोदर को छोटा करने के लिए @Neil को धन्यवाद

def b(s,o,p):
 t,f=s>':'and(ord,chr)or(int,str);s,o=t(s),t(o);d=cmp(o,s)
 return list(map(f,range(s,o+d,int(p)*d)))
def e(s):
 c=1;i=d=0
 while c:d+=-~'{}}'.count(s[i])%3-1;i+=1;c=i<len(s)and 0<d
 return i
def m(s):
 if len(s)<1:return[]
 if','==s[-1]:return m(s[:-1])+['']
 i=0
 while i<len(s)and','!=s[i]:i+=e(s[i:])
 return[s[:i]]+m(s[i+1:])
n=lambda a,b:[c+d for c in a for d in b]or a or b
def p(s):
 h=s.count
 if h('{')<1:return[s]
 f,l=s.index('{'),e(s)
 if h('{')<2and h('..')>0and f<1:s=s[1:-1].split('..');return b(s[0],s[1],s[2])if len(s)>2 else b(s[0],s[1],1)
 if f>0 or l<len(s):return n(p(s[:f]),n(p(s[f:l]),p(s[l:])))
 return sum(map(list,map(p,m(s[1:-1]))),[])
o=lambda s:' '.join(p('{'+s.replace(' ',',')+'}'))

व्याख्या

  • b: चश्मा की गणना के अनुसार सीमा होती है।
  • e: पहले बाहरी घनिष्ठ ब्रेस की स्थिति। Iterative।
  • m: कॉमा पर बाहरी तत्वों को विभाजित करता है। पुनरावर्ती।
  • n: खाली करने के लिए जाँच करते समय सरणियों को जोड़ती है। मुझे and/orकाम नहीं मिला ।
  • p: जहाँ ज्यादातर काम पूरा हो जाता है। सभी मामलों की जाँच करता है (रेंज, बस सूची, गठबंधन करने की आवश्यकता है)। पुनरावर्ती।
  • o: क्या इनपुट लेना चाहिए प्रारूप इनपुट / आउटपुट को p

मुझे लगता है कि मैं कुछ स्थानों में सुधार कर सकता हूं, इसलिए मैं और अधिक गोल्फ करने की कोशिश करूंगा। इसके अलावा मुझे स्पष्टीकरण में और अधिक विवरण देना चाहिए।


मुझे [c+d for c in a for d in b] or a or bकाम करने की उम्मीद होती।
नील

2

जावास्क्रिप्ट (फ़ायरफ़ॉक्स 30-57), 465 427 425 बाइट्स

f=s=>/\{/.test(s)?f(s.replace(/([^,{}]*\{[^{}]*\})+[^,{}]*/,t=>t.split(/[{}]+/).map(u=>u.split`,`).reduce((a,b)=>[for(c of a)for(d of b)c+d]))):s.split`,`.join` `
s=>f(`{${s.split` `}}`.replace(/\{(-?\w+)\.\.(-?\w+)(\.\.(\d+))?\}/g,(m,a,o,_,e)=>{m=(a>'@')+(a>'_');a=parseInt(a,m?36:10);o=parseInt(o,m?36:10);e=+e||1;if(o<a)e=-e;for(r=[];e<0?o<=a:a<=o;a+=e)r.push(m?a.toString(36):a);r=`{${r}}`;return m-1?r:r.toUpperCase()}))

fअतिरिक्त 10 बाइट्स में वजन का ES6 संस्करण :

f=s=>/\{/.test(s)?f(s.replace(/([^,{}]*\{[^{}]*\})+[^,{}]*/,t=>t.split(/[{}]+/).map(u=>u.split`,`).reduce((a,b)=>[].concat(...a.map(c=>b.map(d=>c+d)))))):s.split`,`.join` `
g=s=>f(`{${s.split` `}}`.replace(/\{(-?\w+)\.\.(-?\w+)(\.\.(\d+))?\}/g,(m,a,o,_,e)=>{m=(a>'@')+(a>'_');a=parseInt(a,m?36:10);o=parseInt(o,m?36:10);e=+e||1;if(o<a)e=-e;for(r=[];e<0?o<=a:a<=o;a+=e)r.push(m?a.toString(36):a);r=`{${r}}`;return m-1?r:r.toUpperCase()}))
h=(s,t=s.replace(/\{[^{}]*\}/,""))=>s!=t?h(t):!/[{}]/.test(s)
<input oninput="o.textContent=h(this.value)?g(this.value):'{Invalid}'"><div id=o>

व्याख्या: रिक्त स्थान को अल्पविराम में बदलने और {}स्थिरता के लिए पूरे स्ट्रिंग को लपेटने से शुरू होता है (विचार के लिए @Blue के लिए धन्यवाद)। फिर सभी {..}निर्माणों की खोज करता है और उन्हें {,}निर्माणों में विस्तारित करता है । अगला बार-बार {,}बाहर से सभी निर्माणों का विस्तार करने के लिए पुनरावृत्ति का उपयोग करता है। अंत में सभी अल्पविराम को रिक्त स्थान के साथ बदल देता है।

f=s=>/\{/.test(s)?                  while there are still {}s
 f(s.replace(                       recursive replacement
  /([^,{}]*\{[^{}]*\})+[^,{}]*/,    match the deepest group of {}s
  t=>t.match(/[^{}]+/g              split into {} terms and/or barewords
   ).map(u=>u.split`,`              turn each term into an array
   ).reduce((a,b)=>                 loop over all the arrays
    [for(c of a)for(d of b)c+d]))   cartesian product
  ):s.split`,`.join` `              finally replace commas with spaces
s=>f(                               change spaces into commas and wrap
 `{${s.split` `}}`.replace(         match all {..} seqences
   /\{([-\w]+)\.\.([-\w]+)(\.\.(\d+))?\}/g,(m,a,o,_,e)=>{
    m=(a>'@')+(a>'_');              sequence type 0=int 1=A-Z 2=a-z
    a=parseInt(a,m?36:10);          convert start to number
    o=parseInt(o,m?36:10);          convert stop to number
    e=+e||1;                        convert step to number (default 1)
    if(o<a)e=-e;                    check if stepping back
    for(r=[];e<0?o<=a:a<=o;a+=e)    loop over each value
     r.push(m?a.toString(36):a);    convert back to string
    r=`{${r}}`;                     join together and wrap in {}
    return m-1?r:r.toUpperCase()})) convert type 1 back to upper case
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.