रेगेक्स पैटर्न के आंशिक आदेश


25

इस चुनौती के उद्देश्य के लिए, हम कहते हैं कि एक रेगेक्स पैटर्न एक स्ट्रिंग से मेल खाता है यदि पूरी स्ट्रिंग पैटर्न से मेल खाती है, न कि केवल एक विकल्प।

यह देखते हुए दो regex पैटर्न  एक  और  बी , हम कहते हैं कि  एक  है और अधिक विशेष से  बी   अगर हर स्ट्रिंग है के अनुरूप है  एक  भी अनुरूप है  बी   के आसपास नहीं बल्कि अन्य तरीके से। हम कहते हैं कि  A  , B के समतुल्य है   यदि दोनों पैटर्न स्ट्रिंग्स के एक ही सेट से मेल खाते हैं। न पैटर्न अधिक अन्य की तुलना में विशेष है और न ही वे बराबर हैं जाता है, तो हम कहते हैं कि  एक  और  बी  हैं अतुलनीय

उदाहरण के लिए, पैटर्न Hello, .*!की तुलना में अधिक विशिष्ट है .*, .*!; पैटर्न (Hello|Goodbye), World!और Hello, World!|Goodbye, World!समतुल्य हैं; और पैटर्न Hello, .*!और .*, World!अतुलनीय है।

संबंध "से अधिक विशिष्ट" रेगेक्स पैटर्न के सेट पर एक सख्त आंशिक आदेश को परिभाषित करता है। विशेष रूप से, सभी पैटर्न  A  और  B के लिए , निम्नलिखित में से एक सही है:

  • A  , B  ( A < B ) से अधिक विशिष्ट है  ।
  • B A  ( A > B )  से अधिक विशिष्ट है  ।
  • A  और  B  समतुल्य हैं ( A = B )।
  • एक  और  बी  अतुलनीय (हैं एकबी )।

जब  A  और  B  अतुलनीय हैं, तो हम दो मामलों के बीच अंतर कर सकते हैं:

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

चुनौती

एक प्रोग्राम या एक फ़ंक्शन लिखें जो रेगेक्स पैटर्न की एक जोड़ी लेता है और उपरोक्त आदेश का उपयोग करके उनकी तुलना करता है। है कि, अगर दो पैटर्न हैं  एक  और  बी , कार्यक्रम का निर्धारण करना चाहिए कि क्या  एक < बी ,  > बी ,
एक = बी  या  एकबी

× 92% बोनस  एक अतिरिक्त बोनस दिया जाता है यदि, जब पैटर्न अतुलनीय होते हैं, तो कार्यक्रम निर्धारित करता है कि क्या वे अंतरविरोध या असहमति जता रहे हैं।

इनपुट और आउटपुट

कार्यक्रम को दो रेगेक्स पैटर्न को स्वीकार करना चाहिए, जैसे कि नीचे दिए गए स्वाद में। आप फ़ंक्शन तर्कों या समकक्ष पद्धति के रूप में STDIN , कमांड लाइन के माध्यम से इनपुट पढ़ सकते हैं । आप मान सकते हैं कि पैटर्न मान्य हैं।

तुलना के परिणाम के आधार पर कार्यक्रम को चार अलग-अलग आउटपुट (या पांच अलग-अलग आउटपुट में से एक, यदि आप उपरोक्त बोनस के लिए जा रहे हैं) का उत्पादन करना चाहिए (सटीक आउटपुट आपके ऊपर हैं।) आप आउटपुट को STDOUT में लिख सकते हैं। , इसे फ़ंक्शन के परिणाम के रूप में लौटाएं या समकक्ष पद्धति का उपयोग करें ।

रेगेक्स फ्लेवर

आप जो भी रेगेक्स सुविधाएँ पसंद करते हैं, उसका समर्थन कर सकते हैं, लेकिन आपको निम्नलिखित का समर्थन करना चाहिए :

  • साथ वैकल्पिक|
  • के साथ परिमाण*
  • के साथ समूहीकरण( और )
  • किसी भी पात्र से मेल खाना (संभवतः नए सिरे को छोड़कर) .
  • (वैकल्पिक: × 80% बोनस) क्रमशः और , के साथ  सरल और नकारात्मक चरित्र वर्गों का मिलान । आपको किसी भी पूर्वनिर्धारित चरित्र वर्ग (जैसे ) का समर्थन करने की आवश्यकता नहीं है, लेकिन आपको चरित्र श्रेणियों का समर्थन करना चाहिए।[…][^…][:digit:]
  • चरित्र के साथ भागने\ । कम से कम विशेष पात्रों (यानी |*().[^-]\) और अधिमानतः अन्य स्वादों (जैसे {}) में भी सामान्य विशेष वर्णों को बचाना संभव होना चाहिए, लेकिन निरर्थक पात्रों से बचते हुए व्यवहार अनिर्दिष्ट है। विशेष रूप से, आपको विशेष एस्केप अनुक्रमों का समर्थन करने की आवश्यकता नहीं है जैसे कि \nएक नई पंक्ति और पसंद के लिए। एक संभावित कार्यान्वयन केवल \एक शाब्दिक के रूप में चरित्र को लेने के लिए है ।

आप एक ऐसे इनपुट चरित्र की मौजूदगी को मान सकते हैं जो किसी भी शाब्दिक रूप से मेल नहीं खा सकता है (अर्थात यह केवल .वर्ण वर्गों और नकारात्मक वर्णों से मेल खा सकता है ।)

अतिरिक्त नियम

  • आप स्ट्रिंग मिलान और प्रतिस्थापन के उद्देश्य के लिए रेगेक्स लाइब्रेरी या बिलिन रेगेक्स कार्यक्षमता का उपयोग कर सकते हैं।
  • आप किसी भी स्थानीय से संबंधित मुद्दों, जैसे टकराव के नियमों की अनदेखी कर सकते हैं।
  • स्पष्ट बताने के लिए: आपका कार्यक्रम समाप्त होना चाहिए। यह समय-समय पर विशिष्ट पैटर्न को देखते हुए उचित मात्रा में निष्पादित करना चाहिए (निश्चित रूप से एक घंटे से अधिक नहीं, अधिमानतः बहुत कम)।

स्कोरिंग

यह कोड-गोल्फ है। आपका स्कोर है उत्पाद का कोड आकार , बाइट में, और के किसी भी बोनस । सबसे कम स्कोर जीतता है।

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

परीक्षण मामलों का प्रारूप इस प्रकार है:

<Test ID>
<Pattern A>
<Ordering>
<Pattern B>

<Test ID>
<Pattern A>
<Ordering>
<Pattern B>

...

<Test ID>परीक्षण के मामले के लिए एक पहचानकर्ता कहां है, <Pattern A>और <Pattern B>रेगेक्स पैटर्न हैं और <Ordering>उनके बीच क्रमबद्धता है, और इनमें से एक है:

  • <: <Pattern A>से अधिक विशिष्ट है <Pattern B>
  • >: <Pattern B>से अधिक विशिष्ट है <Pattern A>
  • =: पैटर्न बराबर हैं।
  • |: पैटर्न अतुलनीय और निराशाजनक हैं।
  • X: पैटर्न अतुलनीय और प्रतिच्छेदन हैं।

विशेष <empty pattern>पैटर्न खाली पैटर्न के लिए खड़ा है।

ए बुनियादी पैटर्न

B. जटिल पैटर्न

सी। चरित्र वर्गों के साथ बुनियादी पैटर्न

डी। चरित्र वर्गों के साथ जटिल पैटर्न

परीक्षण कार्यक्रम

Regex पैटर्न की तुलना करने के लिए निम्नलिखित स्निपेट का उपयोग किया जा सकता है:

<style>#main {display: none;}#main[loaded] {display: inline;}.pattern_container {position: relative;}.pattern_underlay, .pattern {font: 12pt courier, monospace;overflow: hidden;white-space: pre;padding: 7px;box-sizing: border-box;}.pattern_underlay {background-color: #dddddd;color: #707070;border-radius: 4px;box-shadow: 0.5px 0.5px 2.5px #aaaaaa;}.pattern_underlay[error] {background-color: #ffccbb;}.pattern {position: absolute;left: 0px;top: 0px;background: none;border: none;width: 100%;height: 100%;resize: none;white-space: normal;}#ordering {min-width: 28pt;text-align: center;font-size: 16pt;}#status {padding: 5px;background-color: #fffdce;box-shadow: 1.5px 1.5px 3.5px #aaaaaa;font-size: 10pt;white-space: pre;display: none;}#status[error] {display: inline;background-color: #ffe8df;}#status[loading] {display: inline;}.inline_code {background-color: #dddddd;font: 12pt courier, monospace;padding: 2px;}.placeholder {visibility: hidden;}.error_text {background-color: #fffcb7};</style><span id="main"><table><tr><td><div class="pattern_container"><div class="pattern_underlay" id="pattern1_underlay"></div><textarea class="pattern" id="pattern1" oninput="compare()">Hello, .*!</textarea></div></td><td id="ordering"></td><td><div class="pattern_container"><div class="pattern_underlay" id="pattern2_underlay"></div><textarea class="pattern" id="pattern2" oninput="compare()">.*, .*!</textarea></div></td></tr></table><br></span><span id="status" loading>Loading...</span><script type='text/javascript'>var Module = {setStatus: function (status) {document.getElementById("status").innerHTML = status;if (status == "") {compare();document.getElementById("status").removeAttribute("loading");document.getElementById("main").setAttribute("loaded", 1);}}};function underlay_chars(str) {if (/^\n*$/.exec(str))return str.split("\n").map(function () { return '<span class="placeholder"> \n</span>'; });if (str.indexOf("\n") >= 0)str = str.replace(/\s*$/gm, function (m) { return m.replace(/[^\n]/g, "\0"); });return (str + "\n").split("").map(function (c) {if (c == "\0") return "·";else return '<span class="placeholder">' + c + '</span>';});}function underlay_str(str) {return underlay_chars(str).join("");}function str_to_array32(str) {a = [];for (c of str) {n = c.charCodeAt(0);a.push(n & 0xff, (n >> 8) & 0xff, (n >> 16) & 0xff, n >> 24);}a.push(0, 0, 0, 0);return a;}function compare() {try {for (e of ["pattern1_underlay", "pattern2_underlay", "status"])document.getElementById(e).removeAttribute("error");for (e of ["pattern1", "pattern2"])document.getElementById(e + "_underlay").innerHTML = underlay_str(document.getElementById(e).value);c = Module.ccall("regex_compare", "number", ["array", "array"], [str_to_array32(document.getElementById("pattern1").value),str_to_array32(document.getElementById("pattern2").value)]);if (c >= 0)document.getElementById("ordering").innerHTML = "∥≬<>="[c];else {i = Module.ccall("regex_error_index", "number", [], []);l = Module.ccall("regex_error_length", "number", [], []);e = document.getElementById("pattern" + -c + "_underlay");t = underlay_chars(document.getElementById("pattern" + -c).value);e.setAttribute("error", 1);e.innerHTML =t.slice(0, i).join("") +'<span class="error_text">' + t.slice(i, i + l).join("") + "</span>" +t.slice(i + l).join("");e.setAttribute("error", 1);throw "Pattern error: " + Module.ccall("regex_error", "string", [], []).replace(/`(.*?)'/g, '<span class="inline_code">$1</span>');}} catch (e) {document.getElementById("ordering").innerHTML = "??";document.getElementById("status").innerHTML = e;document.getElementById("status").setAttribute("error", 1);}}</script><script async type="text/javascript" src="https://gist.githack.com/anonymous/91f27d6746566c7b4e4c/raw/c563bf84a01c3a1c6e5f021369a3e730a2e74a1a/rpo.js"></script>


10
वाह। इस पर प्रस्तुत किसी भी उत्तर को मुझसे एक स्वचालित +1 प्राप्त होता है। यह निर्धारित करना कि क्या दो औपचारिक भाषाएं आइसोमॉर्फिक हैं, काफी कठिन है। यह निर्धारित करना कि क्या एक दूसरे का एक उपवर्ग है, एक पूर्ण स्नातक सीएस परियोजना है। @ ___ @
COTO

क्या अमान्य रेगेक्स पैटर्न के लिए कोई निर्दिष्ट व्यवहार है?
पॉल गयोट

@PaulGuyot No. आप मान सकते हैं कि पैटर्न मान्य हैं।
एल डे

1
मुझे आश्चर्य है - क्या आपने खुद को जीता है (यह देखने के लिए कि यह कोड गोल्फ प्रश्न के लिए कितना व्यावहारिक है) या आपने नहीं किया?
गर्वित हैकेलर

1
@proudhaskeller मैंने किया; मैंने टेस्ट स्निपेट लिखा। यह एक कठिन चुनौती है, और यहां कोई एक-लाइनर बनने वाला नहीं है, लेकिन यह गोल्फ खेलने योग्य है।
एलएएल

जवाबों:


10

पायथन 2, 522 बाइट्स * .92 = 480.24 537.28

2 संपादित करें : -60 बाइट्स

संपादित करें : जोड़ा गया स्पष्टीकरण।

निर्धारित फ़ंक्शन है fजो तर्क और रिटर्न के रूप में दो पैटर्न तार लेता है '<', '=', '>', '|', या 'X'। सभी परीक्षण मामलों को संसाधित करने के लिए एक मिनट से भी कम समय की आवश्यकता होती है।

कोड निम्नलिखित के होते हैं, लेकिन साथ \r, \n \t, और हेक्स पलायन (लेकिन \0) उनकी वास्तविक बाइट मूल्यों के साथ बदल दिया।

#encoding=Latin
exec"""x\xda]RMo\xdb0\x0c\xbd\xe7Wx\'K\x96\x92\xc5mOR\xb8\xdf1@%|\x98%X\x80a\x19\x96\x02\x03n\xf2\xdfG:i;\xec$\x92z|\x8f_\x1b\x84%m~\xca\xbe\x1c\x0e\xbd\x0fU\x10Agi\x0e\x87\xea\n\x1f\xf9n{=\xea\0\x93\x08\xd2\xaez\xd0\x99\xcc,m\x07g\xbb\x80s\x9b\x08\xee\x8cRo"\xf3\x8bHy!-\x95\xd7\xa9\x8aS\xb50O5\xc3&\xb68\x0b\xe7\xb1\x19t\x92\x8a\x1d\xaf]\xc2f\x94\x92\x111T\xf3\xf1j\xba\x1b\x081r\xa2\x97\xea\xa5\x11\x03\x9bI\xca\xe6\xed\xe7\xab\xbd\xde`\xb6\x8b"\xd1\xc5\xf7\xd7?^l\xa7\xaeKK\xd7i\x91\x92\x8b\xaaE\x16\x8e\x9c\x12#3\x86\xe0"\xc6\xc9\x15\xfd\x86\xae\\\xde\xcc^\xa7\x94;,\xea\x94t\x08\x84\xa6J\x82\xee%\xb1\xe8\xacW\xb9\xb3\x14f\xd9\x84\xeb\x89\xe1\x8b\xd5\xa3r\xeb\xbf\x81D\rS\xf5\x8b/\xd7e\xaao\xf0\xeb\xf2\xbbv\xdd\xf1\x15\x1f\x93\xe4Aq\xff\x19\xc6\x98\x8b\xa8E\xad\xb2\xaae-m\x843\xc5\xd7!\x8e\xbe\xca.\x1a4\x01\xe8E;@-\xe4\xad9\xd5\xa7\x10\xa7\x9eg\xcea\x10\x83\x0e\xd2\r\x973\xb2o\xb8\xd7\x06\xc2\x0f\xa8\xdf\xdfk\x1b\x15\xb4v\x84H\xc9\xad]\xc1\x83C;\x03m\xc3\x16p\x1f\xe3\x1d\xbf\xa4\xe2\xbe\x8d\x1eX)\x1e\t\x9dv\xf3\xa9\xcd\xe8xGU\x9e\x0b\t\x97\xd6\x0c\x8c\xf2\nxa\xa9\x19u\xaf\xf2iN3\r\xd1\xae\x0f\xe3\x13\x0c@h\xb5W\xb0\xaad3\xef\t\x91s]R=~\xc3^Lv\xc7\x16\x15\xf4\xfb\xa7\x88ze_~B\x06\x80\x99\x03\x86\x7f\x0bY\x06U\xd2.\xeaV\x95\x87$\xd1\xce\xff\x8b\xbf\x9a\x99\xe0\x03u\xa1 =o0<n\xd0\xef]s`b\xb7\x98\x89\xael\xd2\x85\xceO:>\x80j\xfa\xdeb\x95\x95k\x91N\xbe\xfc'5\xac\xe7\xe8\x15""".decode('zip')

उपरोक्त कथन निम्नलिखित कोड को निष्पादित करता है:

z=frozenset
def f(f,s):
 u={s};d,l,f=n(f);w,h,s=n(s);_=0;r=[[z(f[0]),z(s[0])]]
 for e,o in r:
  p=z(zip([e]*h,o)+zip(e,[o]*l))
  if p-u:_|=((l in e)+2*(h in o))*4/3;u|=p;r+=[[reduce(z.__or__,(oo[i+1]for i in ii if ff[i]in[t,4][t<4:]),z())for ii,oo,ff in(e,f,d),(o,s,w)]for t in z([d[i]for i in e]+[w[i]for i in o])]
 return'|=><X'[_-3]
def n(s):
 s=list('('+s+')');i=0
 while s[i:]:f=s[i];h='()|*.'.find(f);s[i]=(h,f)[h<0];s[i:i+1]*=f!='\\';i+=1;l=i;h=1;w=e=[];p=[0];t=[{l}]
 while i:
  d=[i];i-=1;o=[i];f=s[i];t=[{i}]+t
  if f<1:h-=1;e+=zip(o*l,d+s.pop());w.pop()
  if f==1:h+=1;w=w+o;s+=[[]];e+=[o+d]
  if f==2:s[-1]+=d;e+=[(i,w[-1])]
  if h==p[-1]:e+=[t[-1:]+o,[i,1+t.pop()]];p.pop()
  if f==3:p+=[h];t+=o
 for f,o in e:
  for n in t:n|=(n,t[o])[f in n]
 return s+[1],l,t

यदि दूसरा कोड नमूना स्ट्रिंग में संग्रहीत किया जाता है s, तो पहले के समान कुछ अभिव्यक्ति द्वारा निर्मित किया जा सकता है '#encoding=Latin\nexec"""%s"""'%__import__('zlib').compress(s)। कुछ पात्रों जैसे कि नल बाइट्स या बैकस्लैश को ठीक करना आवश्यक हो सकता है। अनज़िप कोड लगभग है 1000 800 बाइट्स तो शायद इसे और अधिक golfed से समझ से परे है ... लेकिन कम से कम मैं गोल्फ करने में कामयाब रहे एक सा एन्कोडिंग: से Latin1करने के लिए Latin

व्याख्या

कार्यक्रम स्ट्रिंग के पार्सिंग के राज्यों का ट्रैक रखने के लिए एक कच्चे रास्ते के रूप में स्ट्रिंग के सूचकांकों का उपयोग करके काम करता है। nसमारोह संक्रमण टेबल बनाता है। पहले यह स्ट्रिंग को पार्स करता है और दो प्रकार के संक्रमणों के सभी उदाहरणों को पाता है। सबसे पहले, ऐसे संक्रमण होते हैं जो स्ट्रिंग में एक और अक्षर जोड़ना शामिल नहीं करते हैं। उदाहरण के लिए, *एक मात्रात्मक अभिव्यक्ति की शुरुआत से कूद । दूसरे, एक चरित्र को जोड़ने के संक्रमण हैं, जो बस एक सूचकांक द्वारा आगे बढ़ते हैं। फिर नो-कैरेक्टर ट्रांज़िशन के ट्रांज़िटिव क्लोजर की गणना की जाती है, और जिन्हें 1-कैरेक्टर ट्रांज़िशन के डेस्टिनेशन के लिए प्रतिस्थापित किया जाता है। तो यह सूचकांक के मानचित्रण और सूचकांकों के समूह में एक चरित्र देता है।

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


बहुत अच्छा! सभी परीक्षणों को समूह ए और बी (कोई चरित्र वर्ग नहीं है, ऐसा लगता है।) मुझे काम करने के लिए संपीड़ित संस्करण नहीं मिल सकता है, हालांकि, या एक ही बाइट की गिनती मिलती है। किसी भी तरह से, आप x 0.92अपने स्कोर की गणना करते समय बोनस का दावा कर सकते हैं । और, ज़ाहिर है, एक स्पष्टीकरण का स्वागत है!
एल डे

4

हास्केल, 560 553 618

भविष्य में किए गए कुछ बोनस मिल सकते हैं।

यह अभी तक पूरी तरह से गोल्फ नहीं है।

import Data.List
c%j|'\\':h:s<-j=[s|c==h]|(a,b):_<-[(a,b)|x<-[0..length j],(a,'|':b)<-[splitAt x j],snd(k b)==[]]=c%a++c%b|'(':s<-j,(a,_:'*':b)<-k s=map(++j)(c%a)++c%b|'(':s<-j,(a,_:b)<-k s=map(++b)(c%a)|h:'*':s<-j=map(++j)(c%[h])++c%s
c%"."=[""|c>'\0']
c%s@[_]=c%('\\':s)
c%(a:b)=map(++b)(c%[a])
c%s=[""|c>'\0']
a&b=nub[(x,nub$b>>=(c%))|c<-[' '..'~'],x<-c%a]
g e(k@(a,l):r)|j<-a&l\\e=g(k:e)(j++r)
g e[]=e
a#b=or[all(null.('\0'%))m|(x,m)<-g[][(a,[b])],""<-'\0'%x]
a!b|a#b,b#a='x'|a#b='>'|b#a='<'|0<1='='
k"("=("","(")
k(c:s)|'('<-c,(x,y)<-k$tail b=('(':a++')':x,y)|')'<-c=("",')':s)|0<1=(c:a,b)where(a,b)=k s
k j=(j,j)

एल्गोरिथ्म का एक हाथ-लहराती विवरण:

reg!reg' आवश्यक चर लौटाता है, "= <> x" में से एक।

a#bयह सच है कि अगर हर स्ट्रिंग से aमेल नहीं खाता है b

c%regऐसी है कि नियमित अभिव्यक्ति की एक सूची है regमैचों c:sउत्पादन मैचों में regexps में से एक है iff s। मैं मूल रूप से रेक्सक्स से आंशिक रूप से मेल खाता हूं। सिवाय अगर cहै '\0'। फिर यह regकिसी भी अधिक इनपुट को प्राप्त करने के लिए बाध्य नहीं करता है, []अगर regमैच करने के लिए अधिक इनपुट प्राप्त करना होगा और [""]अन्यथा।

#सभी संभावित "रेगेक्स-स्टेट" की एक सीमित सूची तैयार करके काम करता है, दोनों रेगेक्स एक मनमानी स्ट्रिंग के बाद होंगे। फिर यह जांचने के लिए कि क्या a<bहम मौसम की जांच करते हैं एक "रेगेक्स-स्टेट" है जिसमें aपूरी तरह से मिलान किया गया है लेकिन bपूरी तरह से मिलान नहीं किया गया है।


ठंडा! आप स्पष्ट रूप से सही रास्ते पर हैं। हालाँकि, अभी यह परीक्षण में विफल है B4
इल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.