जूलिया में गोल्फ के लिए टिप्स


20

जूलिया में गोल्फ के लिए आपके पास क्या सामान्य सुझाव हैं? मैं उन विचारों की तलाश कर रहा हूं, जो सामान्य तौर पर जूलिया के लिए कुछ हद तक विशिष्ट कोड गोल्फ समस्याओं पर लागू हो सकते हैं (उदाहरण के लिए "टिप्पणियां हटाएं" एक उत्तर नहीं है)।

जवाबों:


19

नोट: नीचे कुछ पुरानी युक्तियां हो सकती हैं, क्योंकि जूलिया संरचना के संदर्भ में अभी तक स्थिर नहीं है।

कुछ पात्रों को बचाने के लिए कुछ टोटके

  1. अक्सर उपयोग किए जाने वाले बाइनरी फ़ंक्शन के साथ ओवरलोड ऑपरेटर । उदाहरण के लिए, यदि आपको बहुत सारे पूर्णांक विभाजन करने की आवश्यकता है, और व्युत्क्रम विभाजन, उपयोग की आवश्यकता नहीं है \ =div, और आप a\bइसके बाद टाइप कर सकते हैं div(a,b)। अंतरिक्ष पर ध्यान दें - इसे "\ =" ऑपरेटर के रूप में पार्स करने से बचने के लिए आवश्यक है। यह भी ध्यान दें कि, यदि REPL के शीघ्र स्तर पर ओवरलोड किया गया है, तो इसका उपयोग करें (\)=Base.(\)या \ =Base. \इसे रीसेट करें। नोट: कुछ कार्यों को UTF-8 ऑपरेटरों, जैसे पूर्व निर्धारित मौजूदा है ÷के लिए div, के रूप में एलेक्स ए द्वारा नोट
  2. सशर्त आउटपुट के लिए स्ट्रिंग्स के साथ ^ का उपयोग करें । यही है, इसके बजाय a>0?"Hi":"", "Hi"^(a>0)एक बाइट को बचाने के लिए उपयोग करें, या बूलियन के लिए, "Hi"^aतीन बाइट को बचाने के लिए उपयोग करें।
  3. (कभी-कभी) छोटे निश्चित आकार के वैक्टर को अलग-अलग चर के रूप में संग्रहीत करें । उदाहरण के लिए, के बजाय a=split("Hi there"," "), आप से बचने के लिए सक्षम हो सकते a[1]और a[2]का उपयोग करके a,b=split("Hi there"," "), जो के रूप में संदर्भित किया जा सकता aहै और b, प्रत्येक उपयोग के लिए तीन बाइट्स बचत, असाइनमेंट पर सिर्फ दो अतिरिक्त वर्ण की कीमत पर। जाहिर है, यदि आप वेक्टर ऑपरेशन के साथ काम कर सकते हैं तो ऐसा न करें।
  4. ऐरे के पहले तत्व को एक्सेस करें[] - सरणियों के लिए, अभिव्यक्ति A[]के बराबर है A[1]। ध्यान दें कि यह स्ट्रिंग्स के लिए काम नहीं करता है यदि आप पहला चरित्र प्राप्त करना चाहते हैं, या ट्यूपल्स के लिए।
  5. Arrays, Tuples या स्ट्रिंग्स के लिए isempty का उपयोग न करें - इसके बजाय, ==[]arrays के लिए और ==()tuples के लिए उपयोग करें ; इसी तरह, नकारात्मक के लिए, का उपयोग करें !=[]और !=()। स्ट्रिंग के लिए, ==""खाली के लिए उपयोग करें , लेकिन >""किसी अन्य स्ट्रिंग से पहले "" जैसा कि "" लेक्सिकोग्राफिक रूप से उपयोग नहीं किया जाता है।
  6. "यदि" के स्थान पर सही शॉर्ट-सर्किट बूलियन ऑपरेटर का उपयोग करें । यह थोड़ा कम जूलिया-विशिष्ट हो सकता है, लेकिन यह ध्यान में रखने योग्य है। एक चरित्र को बचाने के x<=1&&"Hi"रूप में लिखा जा सकता है x>1||"Hi", (जब तक कि बूलियन की वापसी महत्वपूर्ण नहीं है)।
  7. स्ट्रिंग में चरित्र की उपस्थिति की जांच करने के लिए उपयोग न करें - यदि आप मूल ASCII के लिए प्रतिबंधित हैं, तो in('^',s)इसके बजाय का उपयोग करें contains(s,"^")। यदि आप अन्य वर्णों का उपयोग कर सकते हैं, तो आप थोड़ा और अधिक बचा सकते हैं '^'∈s, लेकिन ध्यान दें कि UTF-8 में 3 बाइट्स हैं।
  8. किसी सरणी में न्यूनतम / अधिकतम मान खोज रहे हैं? यदि आप जानते हैं कि आपके कोड से कम से कम दो तत्वों का उपयोग करने के बजाय, न्यूनतम या अधिकतम - का उपयोग minimum(x)या maximum(x)उपयोग, min(x...)या max(x...), एक कोड को दाढ़ी करने के लिए न करें x। वैकल्पिक रूप से, यदि आप जानते हैं कि सभी तत्व xगैर-नकारात्मक होंगे, तो उपयोग करें minabs(x)याmaxabs(x)
  9. जहां संभव हो और चुनौती से अनुमति दी गई हो, \ n के बजाय एक वास्तविक नई लाइन का उपयोग करें - ध्यान दें कि यह आपके कोड को पढ़ने में कठिन बना देगा, और इसका मतलब यह हो सकता है कि आपको लोगों को वास्तव में समझने के लिए "अनऑल्फ़ॉल्ड" संस्करण प्रदान करने की आवश्यकता है। यह।
  10. रेगेक्स स्ट्रिंग के बाद विकल्प रखें - यदि आप मल्टीलाइन मोड में रेगेक्स स्ट्रिंग चाहते हैं, उदाहरण के लिए, टाइप नहीं r"(?m)match^ this", टाइप करें r"match^ this"m, तीन वर्णों को सहेजना।
  11. पल्यूड का उपयोग करके 1-डी सरणियों को उल्टा - reverse(x)एक बाइट की तुलना में अधिक लंबा है flipud(x)और एक ही ऑपरेशन करेगा, इसलिए उत्तरार्द्ध बेहतर है।
  12. जहां संभव हो, पुश के बजाय ऐरे कंसेंटेशन का इस्तेमाल करें !, अनशिफ्ट !, अपेंड !, या प्रीपेन्ड करें। - सामान्य सरणियों के लिए, यह आसानी से किया जा सकता है। प्रकार के सरणियों के लिए सरणी तत्वों के साथ कोई भी, आपको जोड़े गए सरणियों के आसपास घुंघराले ब्रैकेट की आवश्यकता होगी (जो है {[1,2]}, नहीं, {1,2}) जूलिया 0.4 के लिए, आपको आवश्यकता होगी Any[[1,2]]
  13. किसी सरणी या स्ट्रिंग का आकार प्राप्त करने के लिए सरणी अनुक्रमणिका का उपयोग करें - जब आप endसरणी अनुक्रमण के भीतर उपयोग करते हैं, तो यह स्वचालित रूप से सरणी / स्ट्रिंग की लंबाई में परिवर्तित हो जाती है। तो इसके बजाय k=length(A), A[k=end]3 वर्णों को बचाने के लिए उपयोग करें। ध्यान दें कि यदि आप तुरंत k का उपयोग करना चाहते हैं तो यह फायदेमंद नहीं हो सकता है। यह भी एक बहुआयामी मामले में काम करता है - A[k=end,l=end]प्रत्येक आयाम का आकार प्राप्त करेगा A- हालांकि, (k,l)=size(A)इस मामले में एक बाइट से छोटा है, इसलिए इसका उपयोग केवल तभी करें जब आप एक ही समय में अंतिम तत्व तक तुरंत पहुंचना चाहते हैं।
  14. एरे इंडेक्सिंग का उपयोग करके एक इंडेक्स इटरेटर प्राप्त करें - 13 के समान, आप एक ऐरे का भी उपयोग करके ऐरे की लंबाई से मेल खाते हुए प्राप्त कर सकते हैं A[k=1:end], जिस स्थिति में kएक इटरेटर मिलान का आयोजन करेगा 1:length(A)। यह उपयोगी हो सकता है जब आप Aएक ही समय में सरणी का उपयोग करना चाहते हैं ।
  15. एक स्ट्रिंग को चार-सरणी में बदलने के लिए संग्रह का उपयोग न करें - इसके बजाय collect(A), उपयोग करें [A...], जो एक ही काम करेगा और 4 बाइट्स बचाएगा।
  16. एक स्ट्रिंग में परिवर्तित संख्या की आवश्यकता है? का प्रयोग करें "$(s[i])"या dec(s[i])भाव या बहु चरित्र चर के लिए, और "$i"एकल चरित्र चर के लिए।
  17. सशर्त असाइनमेंट के ?:बजाय &&या के ||लिए उपयोग करें - अर्थात, यदि आप केवल कुछ शर्त पर असाइनमेंट करना चाहते हैं, तो आप एक बाइट को लिखने के cond?A=B:1बजाय cond&&(A=B), या के cond?1:A=Bबजाय सहेज सकते हैं cond||(A=B)। ध्यान दें कि 1, यहाँ, एक डमी मूल्य है।
  18. का उपयोग करें unionया के बजायunique - के union(s)रूप में एक ही बात करेंगे unique(s), और इस प्रक्रिया में एक बाइट बचाओ। यदि आप गैर-एएससीआईआई अक्षरों का उपयोग कर सकते हैं, तो ∪(s)वही काम करेंगे, और केवल 5 बाइट्स के बजाय 3 बाइट्स का खर्च होगा union

2
ओह, मैं पायथन में उस पहली चाल को कैसे पसंद करूंगा।
देखिए 18

आप स्पेस का उपयोग करके रिक्त स्थान पर विभाजन कर सकते हैं split("Hi there")क्योंकि पैटर्न तर्क अंतरिक्ष में चूक जाता है।
एलेक्स ए।

@AlexA। - मुझे पता है, लेकिन यह टिप की बात नहीं है, और टिप समान रूप से अच्छी तरह से लागू होता है।
ग्लेन ओ

प्वाइंट 12 0.5 में बदल गया है।
लिंडन व्हाइट

@ ऑक्साबॉक्स - मुझे आश्चर्य नहीं है, मुझे पूरा यकीन है कि उनमें से कुछ अब तक पुराने हो चुके हैं। मैंने मूल रूप से 0.3 के लिए अधिकांश युक्तियां लिखी हैं, मुझे लगता है।
ग्लेन ओ

15

कार्यों को परिभाषित करने के लिए ऑपरेटरों को फिर से परिभाषित करें

पुनर्परिभाषित संचालक कोष्ठक और अल्पविराम में बहुत से बाइट बचा सकते हैं।

पुनरावर्ती एकरी संचालक

एक उदाहरण के लिए, फाइबोनैचि अनुक्रम के निम्नलिखित पुनरावर्ती कार्यान्वयन की तुलना करें:

F(n)=n>1?F(n-1)+F(n-2):n # 24 bytes
!n=n>1?!~-n+!(n-2):n     # 20 bytes
!n=n>1?!~-n+!~-~-n:n     # 20 bytes

इसे ऑनलाइन आज़माएं!

पुनर्परिभाषित ऑपरेटर अपनी प्रारंभिक वरीयता को बरकरार रखता है।

ध्यान दें कि हम केवल इसके !पक्ष में स्वैप नहीं कर सकते ~, क्योंकि ~पहले से ही पूर्णांकों के लिए परिभाषित किया गया है, जबकि !केवल बूलियंस के लिए परिभाषित किया गया है।

बाइनरी ऑपरेटर्स

पुनरावृत्ति के बिना भी, एक ऑपरेटर को पुनर्परिभाषित करना बाइनरी फ़ंक्शन को परिभाषित करने से कम है। एक साधारण विभाज्यता परीक्षण की निम्नलिखित परिभाषाओं की तुलना करें।

f(x,y)=x==0?y==0:y%x==0 # 23 bytes
(x,y)->x==0?y==0:y%x==0 # 23 bytes
x->y->x==0?y==0:y%x==0  # 22 bytes
x\y=x==0?y==0:y%x==0    # 20 bytes

इसे ऑनलाइन आज़माएं!

पुनरावर्ती बाइनरी ऑपरेटरों

निम्नलिखित यह दर्शाता है कि एक बाइनरी ऑपरेटर को एकरमैन फ़ंक्शन की गणना करने के लिए कैसे फिर से परिभाषित करना है:

A(m,n)=m>0?A(m-1,n<1||A(m,n-1)):n+1    # 35 bytes
^ =(m,n)->m>0?(m-1)^(n<1||m^~-n):n+1   # 36 bytes
| =(m,n)->m>0?m-1|(n<1||m|~-n):n+1     # 34 bytes
m\n=m>0?~-m\(n<1||m\~-n):n+1           # 28 bytes

इसे ऑनलाइन आज़माएं!

ध्यान दें कि ^एक नियमित पहचानकर्ता का उपयोग करने से भी अधिक लंबा है, क्योंकि इसकी पूर्ववर्तीता बहुत अधिक है।

जैसा पहले बताया गया है

m|n=m>0?m-1|(n<1||m|~-n):n+1           # 28 bytes

पूर्णांक तर्कों के लिए काम नहीं करेगा, क्योंकि |पहले से ही इस मामले में परिभाषित किया गया है। पूर्णांकों के लिए परिभाषा के साथ बदला जा सकता है

m::Int|n::Int=m>0?m-1|(n<1||m|~-n):n+1 # 38 bytes

लेकिन यह बहुत लंबा है। हालाँकि, यह काम करता है यदि हम एक फ्लोट को बाएं तर्क के रूप में और एक पूर्णांक को सही तर्क के रूप में पास करते हैं।


11
  1. फैक्टर द्वारा आसानी से बहकाया नहीं जा सकता है (n) प्रलोभन बेस लाइब्रेरी फ़ंक्शन factor(n)में एक घातक दोष है: यह आपके पूर्णांक के फ़ैक्टर को एक अनियंत्रित Dictप्रकार में लौटाता है । इस प्रकार, यह महंगा collect(keys())और collect(values())संभावित रूप से भी आवश्यक है catऔर sortउस डेटा को प्राप्त करने के लिए जिसे आप इससे बाहर चाहते थे। कई मामलों में, यह परीक्षण प्रभाग द्वारा सिर्फ कारक के लिए सस्ता हो सकता है। दुखद लेकिन सत्य।

  2. उपयोग मानचित्र map लूपिंग के लिए एक बढ़िया विकल्प है। के बीच अंतर के प्रति सचेत रहें mapऔर map!और बाद के यथा-स्थान कार्यक्षमता जब आप कर सकते हैं शोषण करते हैं।

  3. मैप्रेड्यूस का उपयोग mapreduce मानचित्र की कार्यक्षमता को और भी अधिक बढ़ाता है और एक महत्वपूर्ण बाइट-सेवर हो सकता है।

  4. अनाम कार्य महान हैं! .. जब उपरोक्त mapकार्यों के लिए पारित किया गया ।

  5. संचयी सरणी फ़ंक्शंस cumprod ,, cumsumस्वादिष्ट cumminऔर अन्य समान रूप से नामित फ़ंक्शंस संचयी परिचालनों को n-आयामी सरणी के निर्दिष्ट आयाम के साथ सक्षम करते हैं। (या यदि un 1-d निर्दिष्ट है तो)

  6. किसी के लिए लघु संकेतन जब आप किसी बहु-आयामी सरणी (या डिक्ट) के किसी विशेष आयाम का चयन करना चाहते हैं, उदाहरण के लिए A[Any,2], आप बाइट्स का उपयोग करके बचा सकते हैंA[:,2]

  7. कार्यों के लिए सिंगल-लाइन नोटेशन का उपयोग करें इसके बजाय function f(x) begin ... endआप अक्सर सरल कर सकते हैंf(x)=(...)

  8. टर्नरी ऑपरेटर का उपयोग करें यह एकल-अभिव्यक्ति इफ-तब-एल्स निर्माणों के लिए एक अंतरिक्ष-सेवर हो सकता है। कैविट्स: जबकि कुछ अन्य भाषाओं में संभव है, आप जूलिया में बृहदान्त्र के बाद भाग को छोड़ नहीं सकते। इसके अलावा, ऑपरेटर जूलिया में अभिव्यक्ति-स्तर है, इसलिए आप इसे कोड के पूरे ब्लॉकों के सशर्त निष्पादन के लिए उपयोग नहीं कर सकते।
    if x<10 then true else false endबनाम
    x<10?true:false


3
जूलिया के लिए कुछ हद तक विशिष्ट "टर्नरी ऑपरेटर का उपयोग करें" पृथ्वी पर कैसे है? यह हर भाषा के लिए प्रासंगिक है, जिसमें यह है।
पीटर टेलर

5
यह प्रासंगिक है कि यह इसके पास है। कई भाषाओं में नक्शा, अनाम या शुद्ध कार्य, किसी / सभी के लिए किसी प्रकार का आशुलिपि, संचयी कार्य आदि होते हैं। अगर हम हर टिप्स थ्रेड को केवल उस भाषा के लिए विशिष्ट विशेषताओं को कम करने के लिए थे, तो बहुत कम टिप्स सामग्री होगी ।
जोनाथन वान मैट्रे

3
गोश, शुरुआत के लिए केवल सभी कार्यात्मक हैं, जहां सब कुछ एक मूल्य देता है इसलिए एक टर्नरी ऑप निरर्थक होगा। यदि आपके पास विशिष्ट उदाहरण हैं: गो, हास्केल, स्काला, लुआ, वीबी, प्रोलॉग, पीएल / एसक्यूएल ... यहां तक ​​कि पायथन कई संस्करणों के लिए नहीं था। लगभग दर्जन भर भाषाओं में से, जिनकी युक्तियाँ सूत्र उनके टर्नरी ऑपरेटर का उल्लेख करते हैं, क्या कोई कारण है जो आपने केवल प्रांतीय होने के लिए चुना है?
जोनाथन वान मैट्रे

3
ठीक है, हे, कम से कम तुम एक समान अवसर curmudgeon। ー (Jon ー  ̄ ヘ)
जोनाथन वान मैटर

1
क्या मैं टिप 3 को समायोजित करने का सुझाव दूंगा? mapreduce या तो mapfoldl या mapfoldr की तुलना में लंबा है, और कार्यान्वयन के आधार पर अलग-अलग व्यवहार हो सकता है। मैपफॉल्ड और मैपफॉल्डर बाएं- और दाएं-सहयोगी (क्रमशः) लगातार हैं, और इस तरह एक बेहतर विकल्प हैं। यह आम तौर पर कम करने के लिए भी लागू होता है (फोल्ड या फोल्ड का उपयोग करें)।
ग्लेन ओ

9

कार्यों पर अधिक जानकारी

यह अन्य भाषाओं में भी संभव है, लेकिन आमतौर पर सीधी विधि की तुलना में अधिक लंबा है। हालांकि, जूलिया की अपनी एकता और द्विआधारी ऑपरेटरों को फिर से परिभाषित करने की क्षमता इसे काफी गोल्फ बनाती है।

उदाहरण के लिए, 1 से 10 तक प्राकृतिक संख्याओं के लिए जोड़, घटाव, गुणा और भाग तालिका बनाने के लिए, कोई भी उपयोग कर सकता है

[x|y for x=1:10,y=1:10,| =(+,-,*,÷)]

जो पुनर्परिभाषित द्विआधारी ऑपरेटर |के रूप में +, -, *और ÷, तो गणना करता है x|yप्रत्येक ऑपरेशन के लिए और xऔर yवांछित श्रेणियों में।

यह साथ ही साथ ऑपरेटरों के लिए भी काम करता है। उदाहरण के लिए, जटिल संख्याओं की गणना करने के लिए 1 + 2i , 3-4i , -5 + 6i और -7-8i , उनके नकारात्मक, उनके जटिल संयुग्म और उनके गुणक व्युत्क्रम, एक का उपयोग कर सकते हैं

[~x for~=(+,-,conj,inv),x=(1+2im,3-4im,-5+6im,-7-8im)]

जो के रूप में , और , और फिर सभी वांछित जटिल संख्याओं के लिए गणना करता है , यूनिरी ऑपरेटर ~को फिर से परिभाषित करता है ।+-conjinv~x

वास्तविक प्रतियोगिताओं में उदाहरण


6
  1. कीवर्ड कभी-कभी किसी स्थान या अर्धविराम की आवश्यकता के बिना लगातार स्थिरांक का पालन कर सकते हैं। उदाहरण के लिए:

    n->(for i=1:n n-=1end;n)

    के बीच एक जगह की कमी पर ध्यान दें 1और end। यह endएक करीबी पार्न के बाद होने के लिए भी सही है , अर्थात )end

  2. एक ऑपरेटर के ÷बजाय div()या ओवरलोडिंग का उपयोग करके पूर्णांक विभाजन करें । ध्यान दें कि ÷UTF-8 में 2 बाइट्स हैं।

  3. का प्रयोग करें vec()या A[:](कुछ सरणी के लिए A) के बजाय reshape()जब भी संभव हो।

  4. चुनौती के नियमों में अनुमति मिलने पर पूर्ण कार्यक्रमों के बजाय कार्य बनाएं। यह एक फ़ंक्शन को परिभाषित करने के लिए कम है जो स्टड से पढ़कर चर को परिभाषित करने के बजाय इनपुट को स्वीकार करता है। उदाहरण के लिए:

    n->(n^2-1)
    n=read(STDIN,Int);n^2-1
  5. किसी फ़ंक्शन के लिए वेरिएबल्स को तर्क के अंदर बढ़ाया जा सकता है। उदाहरण के लिए, अगले 1-विरल बाइनरी नंबर चुनौती को खोजने के लिए मेरा जवाब निम्नलिखित है :

    n->(while contains(bin(n+=1),"11")end;n)

    यह nलूप के अंदर वृद्धि से छोटा है ।


6
  1. टाइप न करेंreturn f(x)=x+4 , बल्कि इससे छोटा है f(x)=return x+4। जूलिया हमेशा अंतिम कथन का परिणाम देती है।
  2. के बजाय का उपयोग करें[x for x in 1:4]की तुलना में 3 अक्षर लंबा है, लेकिन इसके बराबर है[x for x=1:4]

5

ब्रॉडकास्टिंग फ़ंक्शन कॉल का उपयोग करें।

जूलिया 0.5 में पेश किया गया। यह मानचित्र की तरह है, लेकिन कम वर्णों का उपयोग करता है, और इसके आर्गन पर व्यवहार को प्रसारित करता है - जिसका अर्थ है कि आप चीजों से निपटने के लिए कम लंबोदा लिख ​​सकते हैं।

बजाय:

  • map(f,x) - 8 अक्षर।
  • f.(x) - 5 अक्षर

फिर भी बेहतर:

  • map(a->g(a,y),x) - 16 अक्षर
  • g.(x,[y]) - 9 अक्षर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.