एक बाइनरी शब्द से मेल खाते हुए सबसे छोटा सरल रेगेक्स


20

कार्य

नॉन-खाली रेगुलर एक्सप्रेशन के रूप में एक सिंपल रेगेक्स को परिभाषित करें जिसमें केवल शामिल हो

  • वर्ण 0और 1,
  • कोष्ठक समूहीकरण (और ),
  • एक या अधिक पुनरावृत्ति परिमाणक +

0एस और 1एस के एक गैर-खाली स्ट्रिंग को देखते हुए , आपके प्रोग्राम को पूर्ण इनपुट स्ट्रिंग से मेल खाते हुए सबसे छोटा सरल रेगेक्स मिलना चाहिए । (यही है, जब एक साधारण regex मिलान, नाटक यह द्वारा bookended है ^ और  $।) कई कम से कम regexes देखते हैं, तो किसी भी या उन सभी को मुद्रित करें।)

, इसलिए सबसे छोटा सबमिशन (बाइट्स में) जीतता है।

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

1 -> 1
00 -> 00 or 0+
010 -> 010
1110 -> 1+0
01010 -> 01010
0101010 -> 0(10)+ or (01)+0
011111 -> 01+
10110110 -> (1+0)+
01100110 -> (0110)+ or (01+0)+
010010010 -> (010)+
111100111 -> 1+001+ or 1+0+1+
00000101010 -> 0+(10)+ or (0+1)+0
1010110001 -> 1(0+1+)+ or (1+0+)+1

3
आपको यह स्पष्ट करना चाहिए कि आप चाहते हैं कि हम एक ऐसा प्रोग्राम लिखें जो रेगेक्स लिखता है, न कि रेगेक्स आवरसाइड लिखें। लेकिन यह दिलचस्प लग रहा है।
18 अक्टूबर को gcampbell

1
मेरे परीक्षण में, 01100110एक दिलचस्प मामला है ... एक भोली एल्गोरिथ्म लिखना होगा 01+0+1+0या (0+1+)+0जो इष्टतम नहीं हैं।
नील

जवाबों:


2

अजगर, 20 बाइट्स

hf.x}z:zT1Zy*4"()01+

इसे चलाने में लगभग 30 सेकंड लगते हैं, इसलिए इसे ऑफ़लाइन चलाने की आवश्यकता है।

स्पष्टीकरण:

hf.x}z:zT1Zy*4"()01+
                        Implicit: z is the input string.
              "()01+    "()01+"
            *4          Repeated 4 times
           y            All subsequences in length order
hf                      Output the first one such that
      :zT1              Form all regex matches of z with the candidate string
    }z                  Check if the input is one of the strings
  .x      Z             Discard errors

मुझे पूरी तरह से यकीन नहीं है कि हर छोटी से छोटी स्ट्रिंग "() 01+" * 4 की एक परिकल्पना है, लेकिन जरूरत पड़ने पर 4 को बिना बाइट लागत के 9 तक बढ़ाया जा सकता है।


9

जावास्क्रिप्ट (ईएस 6), 488 341 बाइट्स

s=>[s.replace(/(.)\1+/g,'$1+'),...[...Array(60)].map((_,i)=>`(${(i+4).toString(2).slice(1)})+`),...[...Array(1536)].map((_,i)=>`${i>>10?(i>>8&1)+(i&2?'+':''):''}(${i&1}${i&4?i>>4&1:i&16?'+':''}${i&8?''+(i>>7&1)+(i&64?i>>5&1:i&32?'+':''):''})+${i&512?(i>>8&1)+(i&2?'+':''):''}`)].filter(r=>s.match(`^${r}$`)).sort((a,b)=>a.length-b.length)[0]

व्याख्या: चूँकि छः रेगीक्स सभी संभव बाइनरी शब्दों को व्यक्त कर सकते हैं, और सबसे लंबे दो नौ अक्षर लंबे होते हैं, यह उन और सभी छोटे रेगेक्स की जांच करने के लिए पर्याप्त है। एक उम्मीदवार स्पष्ट रूप से "रन लेंथ एन्कोडिंग" के साथ स्ट्रिंग है (यानी सभी अंकों को उपयुक्त +एस के साथ बदल दिया जाता है ), लेकिन एस के एक सेट के साथ तार को भी जांचने की ()आवश्यकता होती है। मैं 1596 ऐसे रेगेक्स उत्पन्न करता हूं (इसमें डुप्लिकेट और बेकार रेगेक्स शामिल हैं, लेकिन वे अभी समाप्त हो जाएंगे) और सभी 1597 का परीक्षण करें कि यह सबसे छोटा मैच कौन सा है। उत्पन्न रेग्जेस दो प्रकारों में आते हैं: \(\d{2,5}\)\+(60 रेगेक्स) और (\d\+?)?\(\d[\d+]?(\d[\d+]?)?\)(\d\+?)?(1536 रीजैक्स, क्योंकि मैं लीडिंग और ट्रेलिंग अंक दोनों के साथ रेग्जेस पैदा करने से बचता हूं)।


@LeakyNun मूल रूप से मैंने सोचा था कि लंबाई 9 के 4 रीजैक्स थे लेकिन यह स्पष्ट रूप से गलत है इसलिए मैंने अपना स्पष्टीकरण स्पष्ट कर दिया है।
नील।

2

पायथ - 31 30 29 बाइट्स

पाशविक बल! शायद पुनरावृति थोड़ा गोल्फ कर सकते हैं।

 f=+Yf.x:zjY"^$")Z^"10+()"T1Y

टेस्ट सूट


1

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

यह उबाऊ जानवर बल दृष्टिकोण है। काम करता है क्योंकि कोई भी रेगेक्स कभी भी 9 अक्षरों (नील नोटों के रूप में) से अधिक लंबा नहीं होता है और किसी भी व्यक्तिगत चरित्र को 4 से अधिक बार दोहराने की आवश्यकता नहीं होती है (यह '01()+'.chars*9मेरे सीपीयू को दुखी करने की कोशिश करता है )।

10.times{|i|('01()+'.chars*4).combination(i).map{|s|begin
/^#{s*''}$/=~$*[0]&&[puts(s*''),exit]
rescue
end}}
$ for word in `grep -Po '^\S+' test_cases.txt`; do nice -n20 ruby sre.rb $word; done
1
0+
010
1+0
01010
0(10)+
01+
(1+0)+
(01+0)+
(010)+
1+0+1+
0+(10)+
1(0+1+)+

1

पायथन 3, 186 बाइट्स

मैं जांच कर रहा हूं कि क्या जानवर-मजबूर के अलावा इस समस्या के लिए एक दृष्टिकोण है, लेकिन यहां अभी के लिए पायथन जानवर-बल समाधान है।

import re,itertools
def a(b):
 for z in range(10):
  for i in itertools.combinations("01()+"*4,z):
   j=''.join(i)
   try:
    if re.fullmatch(j,b)and len(j)<=len(b):return j
   except:1
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.