यदि आप इंटरनेट पर ऐसी लाइब्रेरी खोजते हैं जो अनुक्रम उत्पन्न कर सकती है, तो आपको शायद ही कोई मिल सके, हालांकि अनुक्रम अलग गणित और कंप्यूटर विज्ञान की एक मूल अवधारणा है।
इस संक्षिप्त लेख में, हम SeqGen नामक अनुक्रम पीढ़ी के लिए मेरे द्वारा लिखी गई लाइब्रेरी पर एक नज़र डालेंगे।
अनुक्रम (अनौपचारिक रूप से कहें तो) तत्वों (ज्यादातर संख्याएं) का एक सेट है जहां प्रत्येक तत्व का उत्पादन पूर्ववर्ती तत्व पर आधारित होता है।
सबसे बुनियादी उदाहरण सकारात्मक पूर्णांकों का एक सरल रैखिक अनुक्रम है जहां पहला तत्व 0 है और अगला तत्व पूर्ववर्ती तत्व प्लस एक है, इसलिए हम पहले वाले में एक जोड़कर दूसरा तत्व प्राप्त कर सकते हैं, और हम तीसरा प्राप्त कर सकते हैं एक को दूसरे में जोड़कर तत्व, इत्यादि। रैखिक अनुक्रम इस तरह दिखेगा: {0, 1, 2, 3, …, n}
एक अधिक जटिल उदाहरण फाइबोनैचि अनुक्रम हो सकता है जहां पहले दो तत्व 0 और 1 हैं, और अगला तत्व दो पूर्ववर्ती तत्वों का योग है। फाइबोनैचि अनुक्रम इस तरह दिखेगा: {0, 1, 1, 2, 3, 5, 8, 13, 21, …, n}
हम ऊपर से देख सकते हैं कि एक अनुक्रम को दो गुणों से परिभाषित किया गया है:
2.0_
निर्भरताएँ:SeqGen लाइब्रेरी रस्ट प्रोग्रामिंग भाषा में लिखी गई है; अनुवर्ती कार्रवाई के लिए, आपको रस्ट स्थापित करना होगा।
2.1_
एक प्रोजेक्ट बनाना:आइए SeqGen लाइब्रेरी का उपयोग करने के लिए एक नया प्रोजेक्ट बनाएं; हम कार्गो के साथ ऐसा कर सकते हैं:
$ cargo new --bin sequence && cd sequence
अब, आइए लाइब्रेरी को अपने प्रोजेक्ट में निर्भरता के रूप में जोड़ें:
$ cargo add seqgen
अब, हम लाइब्रेरी का उपयोग करने के लिए तैयार हैं।
SeqGen में, अनुक्रम निर्माण प्रक्रिया अनुक्रम के दो गुणों पर सीधे मैप करती है जिसे हमने अनुक्रम क्या है अनुभाग में निष्कर्ष निकाला है; हमें प्रारंभिक तत्वों और अगले तत्व को उत्पन्न करने वाले फ़ंक्शन को परिभाषित करना होगा (जिसे SeqGen में ट्रांज़िशन फ़ंक्शन कहा जाता है)।
आइए रैखिक अनुक्रम बनाएं:
use seqgen::prelude::*; fn main() { let linear_seq = Sequence::new() .initial_elements(vec![0]) .transition_function(|alive_elements, current_element_index| { alive_elements.last_element().unwrap() + 1 }); }
Sequence
प्रकार एक संरचना है जो अनुक्रम का प्रतिनिधित्व करती है; इस प्रकार पर संबंधित फ़ंक्शन new()
को कॉल करके, हमें एक नया उदाहरण मिलता है जो अपरिभाषित है। इस अपरिभाषित उदाहरण पर, हम इसे परिभाषित करने के लिए तरीकों को कॉल कर सकते हैं।
पहली विधि initial_elements()
है जो तत्वों के एक वेक्टर को एक तर्क के रूप में स्वीकार करती है, और इसे उदाहरण के प्रारंभिक तत्वों के रूप में सेट करती है।
दूसरी विधि transition_function()
है जो एक तर्क के रूप में एक क्लोजर लेती है जो वर्तमान में उपलब्ध तत्वों से अगले तत्व में संक्रमण का प्रतिनिधित्व करती है।
इस क्लोजर के पास दो तर्कों तक पहुंच है: पहला है alive_elements
जो वर्तमान में उपलब्ध तत्वों का प्रतिनिधित्व करता है, और दूसरा है current_element_index
( usize
प्रकार का) जो पीढ़ी में वर्तमान तत्व का सूचकांक है। संक्रमण फ़ंक्शन के चित्रण के लिए नीचे दी गई तालिका देखें।
पीढ़ी में वर्तमान तत्व | जीवित_तत्व | current_element_index |
---|---|---|
| | |
| | |
| | |
| | |
alive_elements
SequencePart
प्रकार का है, हम इस आलेख में बाद में SequencePart
प्रकार पर एक नज़र डालेंगे
चूँकि तत्व का सूचकांक रैखिक अनुक्रम में उसका मान भी है, हम उपरोक्त उदाहरण को सरल बना सकते हैं:
use seqgen::prelude::*; fn main() { let linear_seq = Sequence::new().transition_function(|_, i| i); }
यहां, हमें प्रारंभिक तत्वों को परिभाषित करने की आवश्यकता नहीं है, और हमें जीवित तत्वों तक पहुंच की आवश्यकता नहीं है; हमें बस सूचकांक की आवश्यकता है (जिसे इस मामले में i
नाम दिया गया है), और हम बस इसे वापस कर देते हैं।
उसी प्रकार, हम फाइबोनैचि अनुक्रम को परिभाषित कर सकते हैं:
use seqgen::prelude::*; fn main() { let fib_seq = Sequence::new() .initial_elements(vec![0, 1_u128]) .transition_function(|alive_elements, i| { let x = alive_elements.nth_element(i - 1).unwrap(); let y = alive_elements.nth_element(i - 2).unwrap(); x + y }); }
चूँकि फाइबोनैचि अनुक्रम तेजी से बढ़ता है, इस परिभाषा के साथ 187 से अधिक तत्व उत्पन्न करने से u128
अतिप्रवाह हो जाएगा। एक बेहतर परिभाषा में u128
के बजाय big int का उपयोग किया जाएगा।
अपना अनुक्रम परिभाषित करने के बाद, हम इसके तत्वों तक पहुँच सकते हैं:
use seqgen::prelude::*; fn main() { let mut linear_seq = Sequence::new().transition_function(|_, i| i); let some_element = linear_seq.nth_element(111); println!("{some_element}"); }
यहां, हम nth_element()
विधि का उपयोग करके 111वें तत्व तक पहुंच रहे हैं जो तत्व का एक अपरिवर्तनीय संदर्भ देता है (इस मामले में &usize
)।
ध्यान दें कि हमने linear_seq
परिवर्तनशील बना दिया है। ऐसा इसलिए है क्योंकि nth_element()
विधि अनुक्रम के जीवित तत्वों को बदल देगी।
इस तरह, हम अनुक्रम के किसी भी तत्व ( 0
के सूचकांक वाले तत्व से लेकर usize::MAX
के सूचकांक वाले तत्व तक) तक पहुंच सकते हैं।
हम किसी रस्ट इटरेटर की तरह अनुक्रम पर भी पुनरावृति कर सकते हैं:
use seqgen::prelude::*; fn main() { let linear_seq = Sequence::new().transition_function(|_, i| i); linear_seq.for_each(|e| println!("{e}")); }
यह कोड अनुक्रम के सभी तत्वों को प्रिंट करेगा (तत्व 0
से तत्व usize::MAX
तक):
$ cargo run -q 0 1 2 3 4 5 6 7 8 9 10 11 12 13 ...
हम निम्नलिखित कोड का उपयोग करके अनुक्रम से विषम तत्व प्राप्त कर सकते हैं:
use seqgen::prelude::*; fn main() { let linear_seq = Sequence::new().transition_function(|_, i| i); let odd_elements = linear_seq.filter(|e| e % 2 != 0); odd_elements.for_each(|e| println!("{e}")); }
आउटपुट:
$ cargo run -q 1 3 5 7 9 11 13 ...
जिस अनुक्रम को हम परिभाषित करते हैं वह आलसी है, जिसका अर्थ है कि तत्व तब तक उत्पन्न नहीं होंगे जब तक कि आवश्यकता न हो (पुनरावृत्ति के मामले में), या स्पष्ट रूप से अनुरोध न किया जाए ( nth_element()
विधि का उपयोग करके)।
कभी-कभी, हमें केवल अनुक्रम के भागों के साथ काम करने की आवश्यकता होती है, इस मामले में, हमारे पास अनुक्रम भाग होते हैं।
अनुक्रम भाग तीन प्रकार के होते हैं:
AliveElementsPart
ImmutableRangePart
MutableRangePart
जीवित तत्व भाग:
हम अनुक्रम पर alive_elements()
विधि का उपयोग करके जीवित तत्व प्राप्त कर सकते हैं:
use seqgen::prelude::*; fn main() { let linear_seq = Sequence::new() .transition_function(|_, i| i) .pre_generate(111); let alive_elements = linear_seq.alive_elements(); for alive_element in alive_elements { print!("{alive_element} "); } }
यह कोड सभी जीवित तत्वों को प्रिंट करेगा (इस मामले में 0 से 110 क्योंकि हमने 111 तत्वों को पहले से तैयार किया है)।
अपरिवर्तनीय रेंजपार्ट:
अपरिवर्तनीय श्रेणियाँ जीवित तत्वों की श्रेणियाँ हैं; वे अनुक्रम को परिवर्तित नहीं कर सकते. यदि आप एक अपरिवर्तनीय श्रेणी बनाएंगे और उसके सभी तत्व जीवित नहीं हैं, तो आपको एक त्रुटि ( DeadRange
त्रुटि) मिलेगी।
हम range()
विधि का उपयोग करके एक अपरिवर्तनीय रेंज बना सकते हैं जो एक Result
देता है। Ok
वेरिएंट ImmutableRangePart
है, और Err
वेरिएंट RangeError
है। RangeError
InvalidRange
वेरिएंट हो सकता है (यदि रेंज की शुरुआत इसके अंत से अधिक है), या यह DeadRange
वेरिएंट हो सकता है (यदि रेंज के सभी तत्व जीवित नहीं हैं):
use seqgen::prelude::*; fn main() { let linear_seq = Sequence::new().transition_function(|_, i| i); let range = linear_seq.range(0, 3).unwrap(); for e in range { println!("{e}") } }
यह कोड DeadRange
त्रुटि से घबरा जाएगा क्योंकि इसमें कोई जीवित तत्व नहीं है। हम इसे निम्नलिखित से ठीक कर सकते हैं:
use seqgen::prelude::*; fn main() { let mut linear_seq = Sequence::new().transition_function(|_, i| i); linear_seq.generate(3); let range = linear_seq.range(0, 3).unwrap(); for e in range { println!("{e}") } }
यहां, हमने रेंज को वैध बनाने के लिए 3 तत्व तैयार किए हैं।
म्यूटेबलरेंजपार्ट:
एक परिवर्तनशील श्रेणी अनुक्रम को बदल सकती है (तत्व उत्पन्न कर सकती है)।
हम इस प्रकार एक परिवर्तनशील श्रेणी का उपयोग कर सकते हैं:
use seqgen::prelude::*; fn main() { let mut linear_seq = Sequence::new().transition_function(|_, i| i); let mut_range = linear_seq.range_mut(0, 111).unwrap(); for e in mut_range { println!("{e}"); } }
यह कोड 0 से 110 तक तत्वों को प्रिंट करेगा।
इस लेख को अंत तक पढ़ने के लिए धन्यवाद, और मुझे आशा है कि आपको इसमें कुछ उपयोगी मिलेगा। यदि आपके पास कोई सुझाव है जो इस लाइब्रेरी को बेहतर बना सकता है, तो कृपया GitHub पर एक अंक खोलें , और यदि आप लाइब्रेरी में योगदान देना चाहते हैं, तो यह अद्भुत होगा।
यहाँ भी प्रकाशित किया गया