पिप में गोल्फिंग के लिए टिप्स
पिप इंफ़िक्स ऑपरेटरों के साथ एक अनिवार्य गोल्फ भाषा है। यह कार्यात्मक और सरणी प्रोग्रामिंग से कुछ सुविधाओं को भी उधार लेता है।
पिप में गोल्फिंग के लिए आपके पास क्या सामान्य सुझाव हैं? मैं दृष्टिकोण और ट्रिक्स की तलाश कर रहा हूं जो आमतौर पर कोड गोल्फ के लिए उपयोगी होते हैं और पिप के लिए विशिष्ट होते हैं (उदाहरण के लिए "टिप्पणियां हटाएं" एक उत्तर नहीं है)।
कृपया प्रति उत्तर एक टिप पोस्ट करें।
जवाब
पहले से तैयार किए गए चरों का उपयोग करें
पिप के कई ग्लोबल वैरिएबल हैं जो प्री-इनिशियलाइज़्ड हैं ताकि आप मैन्युअल रूप से नंबर / स्ट्रिंग / कुछ और लिखने से बच सकें।
यहाँ उनमें से कुछ हैं ( पूरी सूची ):
_पहचान समारोह (=={a})h100i0k", "lखाली सूचीm1000 (महामारी: रोमन अंक एम)nन्यूलाइन चरित्रo1sअंतरिक्ष चरित्रt10v-1wव्हॉट्सएप से मेल खाता है\s+xखाली स्ट्रिंगzलोअरकेस वर्णमाला ए टू जेडBब्लॉक करें जो अपना दूसरा तर्क देता है ({b})Gअपनी तर्क सूची लौटाता है ({g})AZअपरकेस वर्णमाला A से Z तकCZलोअरकेस व्यंजन b से zPAसभी पी rintable एक SCII वर्ण, 32 126 के माध्यम सेPI\$\pi\$ (3.141592653589793)VWलोअरकेस स्वर को a से uVYलोअरकेस स्वर को ए से वाईXAएक लैटिन पत्र से मेल खाता है[A-Za-z](अधिकX*आदेश हैं)
Yऑपरेटर का उपयोग करें
एक त्वरित सर्वेक्षण से, ऐसा लगता है कि मैं प्रत्येक तीन पिप के उत्तर में से एक में Y(या इसके एक संस्करण, YPऔर YO) का उपयोग करता हूं - और इसलिए कि उत्तर अधिक जटिल हो जाते हैं।
मान जमा करना
Y"यैंक" के लिए खड़ा है, जो विम उपयोगकर्ताओं को एक कमांड के रूप में परिचित करेगा जो वर्तमान लाइन या चयन को एक बफर में कॉपी करता है। Yपिप में संयुक्त संचालक कुछ इसी तरह का काम करता है: यह yवैश्विक रूप में अपने ऑपरेंड की एक प्रति बचाता है और ऑपरेंड को अपरिवर्तित लौटाता है। अनिवार्य रूप से, Y<expr>इसके बराबर है y:<expr>, लेकिन कम है।
यह अकेला कई मामलों में उपयोगी Y(और yचर) बनाता है । एक चर में कुछ स्टोर करने की आवश्यकता है और परवाह नहीं है कि आप किसका उपयोग करते हैं? Yअसाइनमेंट से बाइट बचाता है। दो बार अभिव्यक्ति का उपयोग करने की आवश्यकता है? इसे डुबोएं और yइसके बजाय दो बार उपयोग करें । यदि अभिव्यक्ति दो बाइट्स से अधिक लंबी है, तो आप बचा लेंगे।
लेकिन Yदूसरे तरीके से भी उपयोगी है:
मैनिपुलेटिंग ऑपरेटर पूर्वता
मान लीजिए कि हम इनपुट में 0s की संख्या गिनना चाहते हैं और फिर उस इनपुट के अंत में गिनती से निपटते हैं। (उदाहरण के लिए, इनपुट का 1001101परिणाम होना चाहिए 1001101 3।) गिनती 0s है 0Na, और इसलिए हम करना चाहते हैं a.s.0Na। लेकिन इससे काम नहीं चलेगा क्योंकि पहले Nकी तुलना में कम है ., और अभिव्यक्ति के रूप में होगा ((a.s).0)Na। पूर्ववर्ती व्यवस्था को लागू करने के लिए, हम कोष्ठक का उपयोग कर सकते हैं a.s.(0Na):। यह हमेशा काम करता है, और कभी-कभी यह एकमात्र विकल्प होता है।
लेकिन अक्सर, हम Yइसके बजाय उपयोग कर सकते हैं । चाल यह है कि Yबहुत कम पूर्वता है - सबसे कम, वास्तव में, साथ में Pऔर O। तो किसी भी अभिव्यक्ति के अधिकार के Yरूप में पार्स करेंगे Y, जबकि पूरी Yअभिव्यक्ति को इसके बाईं ओर जो भी आता है उसका सही संचालन होगा। और Yअपरिवर्तित के माध्यम से इसके संचालन को पारित करेगा (इसके अलावा इसे असाइन करें y, लेकिन हम इस बारे में परवाह नहीं करते हैं कि जब तक हम yकिसी और चीज के लिए उपयोग नहीं कर रहे हैं )। यदि हम लिखते हैं a.s.Y0Na, तो यह इस तरह से पार्स करता है (a.s).(Y(0Na)), जैसे कि हमने कोष्ठक किया था 0Na। लेकिन इसमें केवल एक बाइट खर्च होती है, जबकि कोष्ठक में दो खर्च होते हैं।
चेतावनियां
एक Yअभिव्यक्ति केवल एक बाइनरी ऑपरेटर के दाईं ओर इस्तेमाल की जा सकती है, न कि बाईं ओर, क्योंकि इसके ऑपरेंड के रूप में सब कुछ इसे दाईं ओर Yले जाएगा । उदाहरण के लिए, यदि हम इसे अप्वाइंट करने के बजाय 0s की गिनती को रोकना चाहते थे, तो हम ऐसा नहीं कर सकते थे - जैसे कि यह पार्स करेगा । इसके बजाय, हमें कोष्ठक या किसी अन्य रणनीति पर वापस आना होगा।Y0Na.s.aY(0N(a.s.a))
केवल एक ही yचर है, इसलिए आप एक ही कार्यक्रम में दो अलग-अलग मानों को जमा नहीं कर सकते हैं (जब तक कि आप अपने कोड को संरचना नहीं दे सकते ताकि आपको एक ही समय में दोनों की आवश्यकता न हो)। आपको किसी भिन्न चर पर असाइन करने के लिए एक चुनना होगा। इसे दोनों तरीकों से आज़माएं और देखें कि कौन सा आपको अधिक बाइट्स बचाता है।
पिप में बाइनरी ऑपरेटर हमेशा अपने बाएं हाथ के पहले पक्ष का मूल्यांकन करते हैं, जिसका अर्थ है कि आप आम तौर पर yउसी अभिव्यक्ति के नए मूल्य का उपयोग नहीं कर सकते हैं जहां आपने इसे भुनाया था: यदि आप के वर्ग की गणना करना चाहते हैं a+1, तो आप ऐसा नहीं कर सकते y*Ya+1( इसका मूल्यांकन yहोने a+1पर नहीं होगा , क्योंकि a+1अभी तक नहीं लगाया गया है); और आप ऐसा नहीं कर सकते हैं Ya+1*a(जो कि पार्स होगा Y(a+(1*a)))। इस तरह की स्थितियों में, आप संभवत: पहले मूल्य को एक अलग अभिव्यक्ति में डालना चाहते हैं Ya+1y*y:। यदि आपको इसे एक अभिव्यक्ति में करने की आवश्यकता है, तो आप इस Yभाग को संक्षिप्त कर सकते हैं (Ya+1)*y:। यह काम करता है क्योंकि बाएं हाथ की ओर का *मूल्यांकन पहले किया जाता है, इसलिए yसही मूल्य का मूल्यांकन तब किया जाता है जब दाहिने हाथ की तरफ का मूल्यांकन किया जाता है।
सरल कार्यों को लैम्ब्डा से बदलें
लैंबडास एक नियमित रूप से फ़ंक्शन की तुलना में 2 बाइट्स (बहुत कम से कम) को बचाने के लिए एक अच्छा तरीका है, जिसके लिए ब्रेस की आवश्यकता होती है।
पिप के लंबोदर, हालांकि, पायथन में एक मेमने की सामान्य विशेषताओं की नकल नहीं करते हैं। आप सभी स्टैंडअलोन कार्यों को लैम्ब्डा में छोटा नहीं कर सकते।
वे पहचान समारोह का विस्तार कर रहे हैं _, जहां _ = {a}। इसका मतलब यह है कि आप किसी फ़ंक्शन से एक लैम्ब्डा बना सकते हैं केवल अगर आप किसी एकल अभिव्यक्ति के साथ फ़ंक्शन लिख रहे हैं।
पिप में लैम्बदास के एकल भावों के अलावा कुछ रोचक उपयोग हैं। उदाहरण के लिए, आप मुख्य फ़ंक्शन के तर्कों को बिना उन्हें कॉपी / कॉपी किए संदर्भित कर सकते हैं।
से कार्यों पर Dlosc के ट्यूटोरियल :
फ़ंक्शन
_+aप्रोग्राम के पहले कमांड-लाइन तर्क में अपना तर्क जोड़ता है।aअभी भी इसका शीर्ष-स्तरीय मूल्य है क्योंकि यह घुंघराले ब्रेसिज़ के अंदर नहीं है।
पकड़ यह है कि आप आदेशों का उपयोग नहीं कर सकते हैं (यदि, यदि, लूप्स) और सब कुछ एक बयान में नीचे आना चाहिए, क्योंकि यह आमतौर पर कार्यों पर ऑपरेटरों को लागू करने के साथ होता है।
उन प्रतिबंधों के कारण, पिप लंब्दा आम तौर पर छोटे मानचित्रण या फ़िल्टरिंग कार्यों के लिए बेहतर अनुकूल होते हैं। हैप्पी गोल्फिंग!
यदि आपको कोई दिलचस्प उपयोग मामला लगता है, तो मुझे बताएं।
M एक फ़ंक्शन के बजाय एक मान मैप कर सकते हैं
आम तौर पर, आप Mइस तरह का उपयोग करेंगे :
UC_M"abc"
बायीं ओर एक फंक्शन होने के साथ-साथ राईट-हैंड साइड कुछ चलने योग्य होने के कारण आप इसे मैप करना चाहते हैं। यदि आपको तर्कों को स्वैप करने की आवश्यकता है, तो "abc"MUC_काम भी करता है।
लेकिन उस मामले में जहां आप हर वस्तु को एक निरंतर मूल्य के साथ पुनरावृत्ति में बदलना चाहते हैं, Mवह भी कर सकते हैं - बस इसे एक गैर-फ़ंक्शन को इसके बाएं-हाथ के रूप में दें:
42M"abc"
यह लौटेगा [42;42;42]: 42हर पात्र के लिए "abc"। यदि आपको कोई आपत्ति नहीं है कि आपको सूची मिल रही है और स्ट्रिंग नहीं है, तो यह एक बाइट से छोटी है 42X#"abc", और यह सूची के समकक्ष दो बाइट्स है 42RL#"abc"।
मूल्य शाब्दिक रूप से कुछ भी हो सकता है * यह एक फ़ंक्शन नहीं है: स्केलर, पैटर्न, सूची, रेंज, या यहां तक कि नील भी।
यह चाल कुछ अन्य मानचित्र ऑपरेटरों के साथ भी काम करती है:
aMJbमैपिंग के बाद परिणामों को एक स्ट्रिंग में शामिल करता है (विशेष रूप से तब उपयोगी हो सकता है, जबaशुरू करने के लिए स्केलर नहीं हो)aMMbआपको सूचियों की एक सूची प्रदान करेगाa, जिसमें वस्तुओं की लंबाई मिलान करने वाले उपनल की लंबाईbaMCbआपको एकbxbग्रिड (नेस्टेड सूची) देगाa
ZGजब आप 0 ( उदाहरण के लिए ) के अलावा कोई मान चाहते हैं तो वह अंतिम उपयोगी विकल्प है ।
* तकनीकी रूप से, यह एक सूची है कि एक समारोह में दिया जाता है, तो अलग तरह से व्यवहार करेंगे।
कुछ सूचियों के शॉर्टकट
आम तौर पर, यदि आपको स्थिरांक की सूची की आवश्यकता होती है, तो आप आवश्यक के रूप में विभाजकों के साथ वर्ग कोष्ठक में आइटम संलग्न करते हैं [4 8 15 16 23 42]। लेकिन कुछ सामान्य रूप से उपयोग की जाने वाली सूचियों के निर्माण के छोटे तरीके हैं:
- सबसे पहले, यदि आप उन्हें पुन: असाइन नहीं किया है, तो आप पूर्व निर्धारित चर का उपयोग नहीं कर सकते। खाली सूची
lइसके बजाय हो सकती है[]। का उपयोगiकरने के लिए0औरoके लिए1एक सूची में एक बाइट (या दो) को बचा सकता है अगर वे एक और नंबर के बगल में हैं, क्योंकि लोअरकेस चर एक विभाजक की आवश्यकता नहीं है:[0 5]→[i5]। का उपयोगvकरने के लिए-1,tके लिए10,hके लिए100, याmके लिए1000भी बचत होती है सीधे बाइट्स, के बाद से चर नाम संख्या वे प्रतिनिधित्व करते हैं की तुलना में कम कर रहे हैं। - यदि संभव हो तो एक सीमा का उपयोग करें:
[0 1]→[io]→,2। यह अभी भी एक बाइट बचाता है अगर यह 1-आधारित ([o2]→\,2) है या किसी अन्य नंबर ([v0]→v,1) पर शुरू होता है । - अंकों की सूची के लिए, एक संख्या को विभाजित करें:
[1]→^1;[3o4o5 9]→^314159;[oi]→^t। यह भी पात्रों के लिए काम करता है:['#]→^'#;['h'i]→^"hi"।
ध्यान दें कि बाद के दो तरीकों में अलग-अलग प्राथमिकताओं वाले ऑपरेटर शामिल हैं, जिन्हें आपको ध्यान में रखना होगा। यदि पूर्ववर्ती के आसपास काम करना बहुत अधिक परेशानी है, तो आप हमेशा मानक सूची सिंटैक्स पर वापस आ सकते हैं।