रेगेक्स (ECMAScript फ्लेवर), 392 358 328 224 206 165 बाइट्स
तकनीक है कि एक ECMAScript regex (unary में) के साथ फाइबोनैचि संख्याओं से मेल खाने के लिए खेलने की आवश्यकता होती है, यह इस बात से बहुत दूर है कि यह सबसे अन्य regex जायके में कैसे किया जाता है। फॉरवर्ड / नेस्टेड बैकरेफेरेंस या रिकर्सन की कमी का मतलब है कि किसी भी चीज़ का सीधा भाग गिनना या रखना असंभव है। तलाश के अभाव में अक्सर काम करने के लिए पर्याप्त जगह होना भी एक चुनौती बन जाता है।
कई समस्याओं को एक पूरी तरह से अलग दृष्टिकोण से संपर्क किया जाना चाहिए, और कुछ प्रमुख अंतर्दृष्टि के आने तक असम्भव प्रतीत होता है। यह आपको यह पता लगाने के लिए बाध्य करता है कि जिन संख्याओं के साथ आप काम कर रहे हैं, उनके गणितीय गुणों का उपयोग किसी विशेष समस्या को हल करने में सक्षम किया जा सकता है।
मार्च 2014 में, फाइबोनैचि संख्याओं के लिए यही हुआ है। विकिपीडिया पृष्ठ को देखते हुए, मैं शुरू में यह पता नहीं लगा सका, हालांकि एक विशेष संपत्ति tantalizingly करीब लग रहा था। तब गणितज्ञ टेकोन ने एक ऐसी विधि की रूपरेखा तैयार की, जिससे यह स्पष्ट हो गया कि ऐसा करना संभव होगा, उस संपत्ति का उपयोग दूसरे के साथ करना। वह वास्तव में रेगेक्स के निर्माण के लिए अनिच्छुक था। उनकी प्रतिक्रिया जब मैंने आगे बढ़कर यह किया:
तुम पागल हो! ... मुझे लगा कि आप ऐसा कर सकते हैं।
जैसा कि मेरे अन्य ECMAScript यूनरी गणित regex पदों के साथ होता है, मैं एक चेतावनी देता हूँ : मैं अत्यधिक ECMAScript regex में अनैतिक गणितीय समस्याओं को हल करने का तरीका सीखने की सलाह देता हूँ। यह मेरे लिए एक आकर्षक यात्रा रही है, और मैं इसे किसी ऐसे व्यक्ति के लिए खराब नहीं करना चाहता, जो संभवतः इसे स्वयं प्रयास करना चाहते हैं, विशेष रूप से संख्या सिद्धांत में रुचि रखने वाले। एक-एक करके हल करने के लिए लगातार बिगाड़ने वाले टैग की गई समस्याओं की सूची के लिए उस पोस्ट को देखें ।
तो आगे पढ़िए नहीं अगर आप नहीं चाहते हैं कि आपके लिए कुछ अनगढ़ rexx जादू खराब हो जाए । यदि आप स्वयं इस जादू का पता लगाने के लिए एक शॉट लेना चाहते हैं, तो मैं उच्च स्तर पर उल्लिखित उस पोस्ट में उल्लिखित ECMAScript regex में कुछ समस्याओं को हल करके शुरू करने की सलाह देता हूं।
मुझे शुरू में जो चुनौती मिली थी: एक सकारात्मक पूर्णांक x एक फाइबोनैचि संख्या है यदि और केवल यदि 5x 2 + 4 और / या 5x 2 - 4 एक पूर्ण वर्ग है। लेकिन रेगेक्स में इसकी गणना करने के लिए कोई जगह नहीं है। हमारे पास काम करने के लिए एकमात्र स्थान संख्या ही है। हमारे पास 5 से गुणा करने या वर्ग लेने के लिए पर्याप्त जगह नहीं है , दोनों को अकेले जाने दें।
इसे हल करने के तरीके पर टेकोन का विचार ( मूल रूप से यहां पोस्ट किया गया है ):
रेगेक्स को प्रपत्र की एक स्ट्रिंग के साथ प्रस्तुत किया जाता है ^x*$
, Z को उसकी लंबाई के रूप में जाना जाता है। जाँच करें कि क्या z हाथ से पहले कुछ फाइबोनैचि संख्याओं में से एक है (21 तक करना चाहिए)। अगर यह नही तो:
- संख्याओं के एक जोड़े को पढ़ें, <b, जैसे कि 2a से बड़ा नहीं है।
- 2 , ab और b 2 के निर्माण के लिए फॉरवर्ड लुक-अहेड का उपयोग करें ।
- दावा है कि या तो 5a 2 + 4 या 5a 2 - 4 एक पूर्ण वर्ग है (इसलिए कुछ n के लिए F n-1 होना चाहिए )।
- दावा है कि या तो 5 बी 2 + 4 या 5 बी 2 + 4 एक आदर्श वर्ग है (इसलिए बी को एफ एन होना चाहिए )।
- जाँचें कि z = F 2n + 3 या z = F 2n + 4 पूर्व में निर्मित 2 , ab और b 2 और पहचानों का उपयोग करके:
- एफ 2 एन -1 = एफ एन 2 + एफ एन -1 2
- एफ 2 एन = (2 एफ एन -1 + एफ एन ) एफ एन
संक्षेप में: ये पहचानें हमें यह जांचने की समस्या को कम करने की अनुमति देती हैं कि एक दी गई संख्या फिबोनाची है यह जांचने के लिए कि बहुत छोटी संख्याओं की एक जोड़ी फिबोनाची है। थोड़ा बीजगणित दिखाएगा कि बड़े पर्याप्त n (n = 3 के लिए करना चाहिए), F 2n + 3 > F n + 5F n 2 + 4 इसलिए हमेशा पर्याप्त स्थान होना चाहिए।
और यहाँ सी में एल्गोरिथ्म का एक मज़ाक है जो मैंने इसे रेगेक्स में लागू करने से पहले एक परीक्षण के रूप में लिखा था।
तो आगे कोई हलचल नहीं है, यहाँ regex है:
^((?=(x*).*(?=x{4}(x{5}(\2{5}))(?=\3*$)\4+$)(|x{4})(?=xx(x*)(\6x?))\5(x(x*))(?=(\8*)\9+$)(?=\8*$\10)\8*(?=(x\2\9+$))(x*)\12)\7\11(\6\11|\12)|x{0,3}|x{5}|x{8}|x{21})$
इसे ऑनलाइन आज़माएं!
और सुंदर मुद्रित, टिप्पणी संस्करण:
^(
(?=
(x*) # \2+1 = potential number for which 5*(\2+1)^2 ± 4
# is a perfect square; this is true iff \2+1 is a Fibonacci
# number. Outside the surrounding lookahead block, \2+1 is
# guaranteed to be the largest number for which this is true
# such that \2 + 5*(\2+1)^2 + 4 fits into the main number.
.*
(?= # tail = (\2+1) * (\2+1) * 5 + 4
x{4}
( # \3 = (\2+1) * 5
x{5}
(\2{5}) # \4 = \2 * 5
)
(?=\3*$)
\4+$
)
(|x{4}) # \5 = parity - determined by whether the index of Fibonacci
# number \2+1 is odd or even
(?=xx (x*)(\6 x?)) # \6 = arithmetic mean of (\2+1) * (\2+1) * 5 and \8 * \8,
# divided by 2
# \7 = the other half, including remainder
\5
# require that the current tail is a perfect square
(x(x*)) # \8 = potential square root, which will be the square root
# outside the surrounding lookahead; \9 = \8-1
(?=(\8*)\9+$) # \10 = must be zero for \8 to be a valid square root
(?=\8*$\10)
\8*
(?=(x\2\9+$)) # \11 = result of multiplying \8 * (\2+1), where \8 is larger
(x*)\12 # \12 = \11 / 2; the remainder will always be the same as it
# is in \7, because \8 is odd iff \2+1 is odd
)
\7\11
(
\6\11
|
\12
)
|
x{0,3}|x{5}|x{8}|x{21} # The Fibonacci numbers 0, 1, 2, 3, 5, 8, 21 cannot be handled
# by our main algorithm, so match them here; note, as it so
# happens the main algorithm does match 13, so that doesn't
# need to be handled here.
)$
गुणन एल्गोरिथ्म को उन टिप्पणियों में नहीं समझाया गया है, लेकिन मेरे प्रचुर संख्या में रेगेक्स पोस्ट के एक अनुच्छेद में संक्षेप में समझाया गया है ।
मैं फाइबोनैचि रेगेक्स के छह अलग-अलग संस्करणों को बनाए रख रहा था: चार जो सबसे कम लंबाई से सबसे तेज गति तक शाफ़्ट और ऊपर वर्णित एल्गोरिथ्म का उपयोग करते हैं, और दो अन्य जो एक अलग, बहुत तेज़ लेकिन बहुत अधिक लंबा एल्गोरिथ्म का उपयोग करते हैं, जैसा कि मैंने पाया है कि वास्तव में वापस आ सकता है मैच के रूप में फाइबोनैचि सूचकांक (यह समझाते हुए कि यहां एल्गोरिथम इस पोस्ट के दायरे से परे है, लेकिन मूल चर्चा गिस्ट में इसकी व्याख्या की गई है )। मुझे नहीं लगता कि मैं रेगेक्स के कई बहुत समान संस्करणों को फिर से बनाए रखूंगा, क्योंकि उस समय मैं पीसीआरई और पर्ल में अपना सारा परीक्षण कर रहा था, लेकिन मेरा रेगेक्स इंजन इतना तेज है कि गति की चिंताएं अब उतनी महत्वपूर्ण नहीं हैं (और यदि कोई विशेष निर्माण एक अड़चन पैदा कर रहा है, तो मैं इसके लिए एक अनुकूलन जोड़ सकता हूं) - हालांकि मैं फिर से एक सबसे तेज संस्करण और एक सबसे छोटा संस्करण बनाए रखूंगा, यदि अंतर हो गति में काफी बड़े थे।
"फाइबोनैचि इंडेक्स माइनस 1 को एक मैच के रूप में लौटाएं" संस्करण (भारी रूप से गोल्फ नहीं):
इसे ऑनलाइन आज़माएं!
गोल्फ अनुकूलन के पूर्ण प्रतिबद्ध इतिहास के साथ सभी संस्करण जीथब पर हैं:
फाइबोनैचि संख्याओं के मिलान के लिए रेगेक्स - छोटी, गति 0.txt (सबसे छोटी लेकिन सबसे धीमी, जैसा कि इस पोस्ट में है)
फाइबोनैचि संख्याओं
के मिलान के लिए रेग्क्स - लघु, गति 1. फाइबोनैचि संख्याओं के मिलान के लिए रेक्सएक्स - लघु, गति 2.txt
रेगेक्स मिलान फिबोनैकी संख्या - छोटा है, गति 3.txt
fastest.txt - फिबोनैकी संख्या मिलान के लिए regex
फिबोनैकी संख्या मिलान के लिए regex - index.txt वापसी