जूलिया में गोल्फ के लिए आपके पास क्या सामान्य सुझाव हैं? मैं उन विचारों की तलाश कर रहा हूं, जो सामान्य तौर पर जूलिया के लिए कुछ हद तक विशिष्ट कोड गोल्फ समस्याओं पर लागू हो सकते हैं (उदाहरण के लिए "टिप्पणियां हटाएं" एक उत्तर नहीं है)।
जूलिया में गोल्फ के लिए आपके पास क्या सामान्य सुझाव हैं? मैं उन विचारों की तलाश कर रहा हूं, जो सामान्य तौर पर जूलिया के लिए कुछ हद तक विशिष्ट कोड गोल्फ समस्याओं पर लागू हो सकते हैं (उदाहरण के लिए "टिप्पणियां हटाएं" एक उत्तर नहीं है)।
जवाबों:
नोट: नीचे कुछ पुरानी युक्तियां हो सकती हैं, क्योंकि जूलिया संरचना के संदर्भ में अभी तक स्थिर नहीं है।
कुछ पात्रों को बचाने के लिए कुछ टोटके
\ =div
, और आप a\b
इसके बाद टाइप कर सकते हैं div(a,b)
। अंतरिक्ष पर ध्यान दें - इसे "\ =" ऑपरेटर के रूप में पार्स करने से बचने के लिए आवश्यक है। यह भी ध्यान दें कि, यदि REPL के शीघ्र स्तर पर ओवरलोड किया गया है, तो इसका उपयोग करें (\)=Base.(\)
या \ =Base. \
इसे रीसेट करें। नोट: कुछ कार्यों को UTF-8 ऑपरेटरों, जैसे पूर्व निर्धारित मौजूदा है ÷
के लिए div
, के रूप में एलेक्स ए द्वारा नोटa>0?"Hi":""
, "Hi"^(a>0)
एक बाइट को बचाने के लिए उपयोग करें, या बूलियन के लिए, "Hi"^a
तीन बाइट को बचाने के लिए उपयोग करें।a=split("Hi there"," ")
, आप से बचने के लिए सक्षम हो सकते a[1]
और a[2]
का उपयोग करके a,b=split("Hi there"," ")
, जो के रूप में संदर्भित किया जा सकता a
है और b
, प्रत्येक उपयोग के लिए तीन बाइट्स बचत, असाइनमेंट पर सिर्फ दो अतिरिक्त वर्ण की कीमत पर। जाहिर है, यदि आप वेक्टर ऑपरेशन के साथ काम कर सकते हैं तो ऐसा न करें।[]
- सरणियों के लिए, अभिव्यक्ति A[]
के बराबर है A[1]
। ध्यान दें कि यह स्ट्रिंग्स के लिए काम नहीं करता है यदि आप पहला चरित्र प्राप्त करना चाहते हैं, या ट्यूपल्स के लिए।==[]
arrays के लिए और ==()
tuples के लिए उपयोग करें ; इसी तरह, नकारात्मक के लिए, का उपयोग करें !=[]
और !=()
। स्ट्रिंग के लिए, ==""
खाली के लिए उपयोग करें , लेकिन >""
किसी अन्य स्ट्रिंग से पहले "" जैसा कि "" लेक्सिकोग्राफिक रूप से उपयोग नहीं किया जाता है।x<=1&&"Hi"
रूप में लिखा जा सकता है x>1||"Hi"
, (जब तक कि बूलियन की वापसी महत्वपूर्ण नहीं है)।in('^',s)
इसके बजाय का उपयोग करें contains(s,"^")
। यदि आप अन्य वर्णों का उपयोग कर सकते हैं, तो आप थोड़ा और अधिक बचा सकते हैं '^'∈s
, लेकिन ध्यान दें कि ∈
UTF-8 में 3 बाइट्स हैं।minimum(x)
या maximum(x)
उपयोग, min(x...)
या max(x...)
, एक कोड को दाढ़ी करने के लिए न करें x
। वैकल्पिक रूप से, यदि आप जानते हैं कि सभी तत्व x
गैर-नकारात्मक होंगे, तो उपयोग करें minabs(x)
याmaxabs(x)
r"(?m)match^ this"
, टाइप करें r"match^ this"m
, तीन वर्णों को सहेजना।reverse(x)
एक बाइट की तुलना में अधिक लंबा है flipud(x)
और एक ही ऑपरेशन करेगा, इसलिए उत्तरार्द्ध बेहतर है।{[1,2]}
, नहीं, {1,2}
) जूलिया 0.4 के लिए, आपको आवश्यकता होगी Any[[1,2]]
।end
सरणी अनुक्रमण के भीतर उपयोग करते हैं, तो यह स्वचालित रूप से सरणी / स्ट्रिंग की लंबाई में परिवर्तित हो जाती है। तो इसके बजाय k=length(A)
, A[k=end]
3 वर्णों को बचाने के लिए उपयोग करें। ध्यान दें कि यदि आप तुरंत k का उपयोग करना चाहते हैं तो यह फायदेमंद नहीं हो सकता है। यह भी एक बहुआयामी मामले में काम करता है - A[k=end,l=end]
प्रत्येक आयाम का आकार प्राप्त करेगा A
- हालांकि, (k,l)=size(A)
इस मामले में एक बाइट से छोटा है, इसलिए इसका उपयोग केवल तभी करें जब आप एक ही समय में अंतिम तत्व तक तुरंत पहुंचना चाहते हैं।A[k=1:end]
, जिस स्थिति में k
एक इटरेटर मिलान का आयोजन करेगा 1:length(A)
। यह उपयोगी हो सकता है जब आप A
एक ही समय में सरणी का उपयोग करना चाहते हैं ।collect(A)
, उपयोग करें [A...]
, जो एक ही काम करेगा और 4 बाइट्स बचाएगा।"$(s[i])"
या dec(s[i])
भाव या बहु चरित्र चर के लिए, और "$i"
एकल चरित्र चर के लिए।?:
बजाय &&
या के ||
लिए उपयोग करें - अर्थात, यदि आप केवल कुछ शर्त पर असाइनमेंट करना चाहते हैं, तो आप एक बाइट को लिखने के cond?A=B:1
बजाय cond&&(A=B)
, या के cond?1:A=B
बजाय सहेज सकते हैं cond||(A=B)
। ध्यान दें कि 1
, यहाँ, एक डमी मूल्य है।union
या के ∪
बजायunique
- के union(s)
रूप में एक ही बात करेंगे unique(s)
, और इस प्रक्रिया में एक बाइट बचाओ। यदि आप गैर-एएससीआईआई अक्षरों का उपयोग कर सकते हैं, तो ∪(s)
वही काम करेंगे, और ∪
केवल 5 बाइट्स के बजाय 3 बाइट्स का खर्च होगा union
।split("Hi there")
क्योंकि पैटर्न तर्क अंतरिक्ष में चूक जाता है।
पुनर्परिभाषित संचालक कोष्ठक और अल्पविराम में बहुत से बाइट बचा सकते हैं।
एक उदाहरण के लिए, फाइबोनैचि अनुक्रम के निम्नलिखित पुनरावर्ती कार्यान्वयन की तुलना करें:
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
लेकिन यह बहुत लंबा है। हालाँकि, यह काम करता है यदि हम एक फ्लोट को बाएं तर्क के रूप में और एक पूर्णांक को सही तर्क के रूप में पास करते हैं।
फैक्टर द्वारा आसानी से बहकाया नहीं जा सकता है (n) प्रलोभन बेस लाइब्रेरी फ़ंक्शन factor(n)
में एक घातक दोष है: यह आपके पूर्णांक के फ़ैक्टर को एक अनियंत्रित Dict
प्रकार में लौटाता है । इस प्रकार, यह महंगा collect(keys())
और collect(values())
संभावित रूप से भी आवश्यक है cat
और sort
उस डेटा को प्राप्त करने के लिए जिसे आप इससे बाहर चाहते थे। कई मामलों में, यह परीक्षण प्रभाग द्वारा सिर्फ कारक के लिए सस्ता हो सकता है। दुखद लेकिन सत्य।
उपयोग मानचित्र map
लूपिंग के लिए एक बढ़िया विकल्प है। के बीच अंतर के प्रति सचेत रहें map
और map!
और बाद के यथा-स्थान कार्यक्षमता जब आप कर सकते हैं शोषण करते हैं।
मैप्रेड्यूस का उपयोग mapreduce
मानचित्र की कार्यक्षमता को और भी अधिक बढ़ाता है और एक महत्वपूर्ण बाइट-सेवर हो सकता है।
अनाम कार्य महान हैं! .. जब उपरोक्त map
कार्यों के लिए पारित किया गया ।
संचयी सरणी फ़ंक्शंस cumprod
,, cumsum
स्वादिष्ट cummin
और अन्य समान रूप से नामित फ़ंक्शंस संचयी परिचालनों को n-आयामी सरणी के निर्दिष्ट आयाम के साथ सक्षम करते हैं। (या यदि un 1-d निर्दिष्ट है तो)
किसी के लिए लघु संकेतन जब आप किसी बहु-आयामी सरणी (या डिक्ट) के किसी विशेष आयाम का चयन करना चाहते हैं, उदाहरण के लिए A[Any,2]
, आप बाइट्स का उपयोग करके बचा सकते हैंA[:,2]
कार्यों के लिए सिंगल-लाइन नोटेशन का उपयोग करें इसके बजाय function f(x) begin ... end
आप अक्सर सरल कर सकते हैंf(x)=(...)
टर्नरी ऑपरेटर का उपयोग करें यह एकल-अभिव्यक्ति इफ-तब-एल्स निर्माणों के लिए एक अंतरिक्ष-सेवर हो सकता है। कैविट्स: जबकि कुछ अन्य भाषाओं में संभव है, आप जूलिया में बृहदान्त्र के बाद भाग को छोड़ नहीं सकते। इसके अलावा, ऑपरेटर जूलिया में अभिव्यक्ति-स्तर है, इसलिए आप इसे कोड के पूरे ब्लॉकों के सशर्त निष्पादन के लिए उपयोग नहीं कर सकते।
if x<10 then true else false end
बनाम
x<10?true:false
यह अन्य भाषाओं में भी संभव है, लेकिन आमतौर पर सीधी विधि की तुलना में अधिक लंबा है। हालांकि, जूलिया की अपनी एकता और द्विआधारी ऑपरेटरों को फिर से परिभाषित करने की क्षमता इसे काफी गोल्फ बनाती है।
उदाहरण के लिए, 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)]
जो के रूप में , और , और फिर सभी वांछित जटिल संख्याओं के लिए गणना करता है , यूनिरी ऑपरेटर ~
को फिर से परिभाषित करता है ।+
-
conj
inv
~x
महिला और पुरुष अनुक्रम (बाइनरी)
केस क्रमोन्नति (एकात्मक)
कीवर्ड कभी-कभी किसी स्थान या अर्धविराम की आवश्यकता के बिना लगातार स्थिरांक का पालन कर सकते हैं। उदाहरण के लिए:
n->(for i=1:n n-=1end;n)
के बीच एक जगह की कमी पर ध्यान दें 1
और end
। यह end
एक करीबी पार्न के बाद होने के लिए भी सही है , अर्थात )end
।
एक ऑपरेटर के ÷
बजाय div()
या ओवरलोडिंग का उपयोग करके पूर्णांक विभाजन करें । ध्यान दें कि ÷
UTF-8 में 2 बाइट्स हैं।
का प्रयोग करें vec()
या A[:]
(कुछ सरणी के लिए A
) के बजाय reshape()
जब भी संभव हो।
चुनौती के नियमों में अनुमति मिलने पर पूर्ण कार्यक्रमों के बजाय कार्य बनाएं। यह एक फ़ंक्शन को परिभाषित करने के लिए कम है जो स्टड से पढ़कर चर को परिभाषित करने के बजाय इनपुट को स्वीकार करता है। उदाहरण के लिए:
n->(n^2-1)
n=read(STDIN,Int);n^2-1
किसी फ़ंक्शन के लिए वेरिएबल्स को तर्क के अंदर बढ़ाया जा सकता है। उदाहरण के लिए, अगले 1-विरल बाइनरी नंबर चुनौती को खोजने के लिए मेरा जवाब निम्नलिखित है :
n->(while contains(bin(n+=1),"11")end;n)
यह n
लूप के अंदर वृद्धि से छोटा है ।
जूलिया 0.5 में पेश किया गया। यह मानचित्र की तरह है, लेकिन कम वर्णों का उपयोग करता है, और इसके आर्गन पर व्यवहार को प्रसारित करता है - जिसका अर्थ है कि आप चीजों से निपटने के लिए कम लंबोदा लिख सकते हैं।
बजाय:
map(f,x)
- 8 अक्षर।f.(x)
- 5 अक्षरफिर भी बेहतर:
map(a->g(a,y),x)
- 16 अक्षरg.(x,[y])
- 9 अक्षर