रेटिना , 66 63 45 43 36 बाइट्स
^()(\1(?<1>.\1))+(\1(.(?(4).\4)))*$
रेटिना के शीर्षक के बावजूद, यह केवल एक सादा .NET .NET रेगेक्स है जो लोसेचियन नंबरों के एकात्मक प्रतिनिधित्व को स्वीकार करता है ।
इनपुट्स 999 और 1000 एक सेकंड के तहत अच्छी तरह से लेते हैं।
इसे ऑनलाइन आज़माएं! (पहली पंक्ति एक लाइनफ़ीड-अलग किए गए परीक्षण सूट को सक्षम करती है, और अगले दो रूपांतरण सुविधाओं के लिए एकात्मकता का ख्याल रखते हैं।)
व्याख्या
समाधान वर्गीकरण पर आधारित है कि इनपुट को i*i + j*(i + j)
सकारात्मक i
और गैर-नकारात्मक j
(चूंकि हमें इनपुट को संभालने की आवश्यकता नहीं है 0
) के लिए लिखा जा सकता है , और n*n
यह केवल पहले n
विषम पूर्णांक का योग है । इसे आगे के संदर्भों में देखना एक दिलचस्प अभ्यास था।
एक "फॉरवर्ड रेफरेंस" तब होता है जब आप उस समूह के अंदर एक बैकरेसेंस रखते हैं जिसे वह संदर्भित करता है। बेशक, जब समूह पहली बार उपयोग किया जाता है, तो काम नहीं करता है, क्योंकि अभी तक बैकरेफ़र्ड होने के लिए कुछ भी नहीं है, लेकिन यदि आप इसे एक लूप में रखते हैं, तो बैकरेफेरेंस को पिछली बार पुनरावृत्ति प्राप्त होती है। यह बदले में, चलो आप प्रत्येक पुनरावृत्ति के साथ एक बड़ा कब्जा बनाते हैं। इसका उपयोग त्रिकोणीय संख्याओं, वर्गों और फाइबोनैचि संख्याओं जैसी चीजों के लिए बहुत कॉम्पैक्ट पैटर्न तैयार करने के लिए किया जा सकता है।
एक उदाहरण के रूप में, इस तथ्य का उपयोग करते हुए कि वर्ग पहले n
विषम पूर्णांक के योग हैं, हम इस तरह एक वर्ग इनपुट से मेल कर सकते हैं:
(^.|..\1)+$
पहली यात्रा पर, ..\1
काम नहीं कर सकते, क्योंकि \1
अभी तक कोई मूल्य नहीं है। इसलिए हम ^.
समूह में किसी एक वर्ण को कैप्चर करना शुरू करते हैं 1
। बाद के पुनरावृत्तियों पर, ^.
लंगर के कारण अब मेल नहीं खाता, लेकिन अब ..\1
मान्य है। यह पिछले पुनरावृति की तुलना में दो अधिक वर्णों से मेल खाता है और कैप्चर को अद्यतन करता है। इस तरह हम बढ़ती संख्याओं से मेल खाते हैं, प्रत्येक पुनरावृत्ति के बाद एक वर्ग हो रहा है।
अब दुर्भाग्य से, हम इस तकनीक का उपयोग नहीं कर सकते हैं। मिलान करने के बाद i*i
, हमें भी प्राप्त करने की आवश्यकता है i
, ताकि हम इसे गुणा कर सकें j
। ऐसा करने का एक सरल (लेकिन लंबा) तरीका इस तथ्य का उपयोग करना है कि मिलान पुनरावृत्तियों i*i
लेता है i
, ताकि हमने i
समूह में चीजों को पकड़ लिया है 1
। अब हम इसे निकालने के लिए संतुलन समूहों का उपयोग कर सकते हैं i
, लेकिन जैसे मैंने कहा कि यह महंगा है।
इसके बजाय, मैंने इस "लगातार विषम पूर्णांक का योग" लिखने के लिए एक अलग तरीका निकाला i
, जो अंत में एक कैप्चरिंग समूह में भी पैदावार देता है। निश्चित ही i
विषम संख्या बस है 2i-1
। यह हमें प्रत्येक पुनरावृत्ति पर केवल 1 द्वारा आगे के संदर्भ को बढ़ाने का एक तरीका देता है। यह हिस्सा है:
^()(\1(?<1>.\1))+
यह ()
सिर्फ समूह पर एक खाली कब्जा धक्का 1
(initialising i
लिए 0
)। यह ^.|
ऊपर दिए गए सरल समाधान में काफी समान है , लेकिन |
इस मामले में उपयोग करना थोड़ा पेचीदा होगा।
फिर हमारे पास मुख्य लूप है (\1(?<1>.\1))
। \1
पहले से मेल खाता है i
, (?<1>.\1)
फिर समूह 1
को अपडेट करता है i+1
। नए के संदर्भ में i
, हमने अभी-अभी 2i-1
वर्णों का मिलान किया है। वास्तव में हमें जो चाहिए।
जब हम कर लेते हैं, तो हम कुछ वर्ग से मेल खाते हैं i*i
और समूह में 1
अभी भी i
अक्षर हैं।
दूसरा भाग सरल वर्ग मिलान के करीब है जो मैंने ऊपर दिखाया था। चलो 1
अब के लिए पीछे हटने की उपेक्षा करें :
(.(?(4).\1))*
यह मूल रूप से समान है (^.|..\4)*
, सिवाय इसके कि हम उपयोग नहीं कर सकते ^
क्योंकि हम स्ट्रिंग की शुरुआत में नहीं हैं। इसके बजाय हम एक सशर्त का उपयोग करते हैं, अतिरिक्त से मेल खाने के लिए .\1
जब हम पहले ही समूह का उपयोग कर चुके होते हैं 4
। लेकिन वास्तव में यह बिल्कुल वैसा ही है। यह हमें देता है j*j
।
केवल एक चीज जो गायब है वह है j*i
पद। हम इसे इस j*j
तथ्य के उपयोग से जोड़ते हैं कि j*j
गणना अभी भी j
पुनरावृत्तियों को लेती है । इसलिए प्रत्येक यात्रा के लिए हम भी द्वारा कर्सर अग्रिम i
के साथ \1
। हमें केवल यह सुनिश्चित करने की आवश्यकता है कि इसे समूह में न लिखें 4
, क्योंकि यह लगातार विषम संख्याओं के मिलान के साथ गड़बड़ करेगा। इस प्रकार हम यहां पहुंचे:
(\1(.(?(4).\1)))*