क्या वसा-तीर कार्यों को छोटा करने का एक तरीका है?


15

पीपीसीजी पर मैंने अपने पूरे समय यहाँ जो देखा है, उसमें सबसे अधिक जावास्क्रिप्ट एंट्रीज़ जिनमें फैट एरो फ़ंक्शंस हैं, वे दो कैंपों में से एक हैं:

  1. जो सरल हैं वे एक बयान के रूप में चलने में सक्षम हैं और एक जवाब वापस कर रहे हैं, सीधे बल्ले से, जैसे x=(a,b)=>a*a+b

  2. अधिक जटिल हैं जो आमतौर पर छोरों के उपयोग के कारण घुंघराले ब्रेसिज़ होते हैं, और परिणामस्वरूप एक returnबयान के उपयोग की आवश्यकता होती है जैसे ...p=b=>{m=b;for(a=1;~-m;)--m,a*=m*m;return a%b}

प्रमाण 2 के रूप में घुंघराले ब्रेस की अवधारणा के साथ श्रेणी 2 से उपरोक्त उदाहरण लेते हुए ... क्या इस कोड (या इसी तरह) को फिर से गोल्फ करने का एक तरीका होगा ताकि घुंघराले ब्रेसिज़ को खत्म करने के साथ-साथ return? मैं केवल यह पूछ रहा हूं क्योंकि यह संभावित रूप से हो सकता है (यह कहते हुए कि यह हर समय होगा) जेएस गोल्फर के कोड से 8 बाइट्स को खत्म करें। क्या ऐसी कोई तकनीक है जिसका उपयोग इस उदाहरण में किया जा सकता है? मैंने पुनरावृत्ति की कोशिश की है, लेकिन m=bबयान थोड़ा बगैर साबित हुआ है, क्योंकि मैं इसे हिला नहीं सकता।

उपरोक्त कोड के लिए, एक गोल्फ कैसे आगे बढ़ेगा ताकि returnबयान को खत्म किया जा सके , चाहे वह छोटा हो या नहीं?

जवाबों:


18

पुन: उपयोग करें

मैंने पाया है कि पुनरावृत्ति (लगभग) हमेशा से कम eval+ होती है for। सामान्य से बेदखल करने का तरीका है:

for(a=n;b;c);d
(f=a=>b?f(c):d)(n)

तो आइये देखते हैं आपका उदाहरण:

b=>{m=b;for(a=1;~-m;)--m,a*=m*m;return a%b}

हम पहले इसे सरल कर सकते हैं:

for(m=b,a=1;~-m;--m,a*=m*m)a%b;

हमने यहाँ क्या किया? खैर हम बस forबयान के अंदर सब कुछ चले गए , इससे हमें अर्धविराम की मात्रा को कम करने में मदद मिलती है जो सीधे बेहतर नहीं है लेकिन लगभग हमेशा कुछ गोल्फ की ओर जाता है।


आइए इसे eval में डालें और इसे पुनरावर्तन संस्करण से तुलना करें:

b=>{m=b;for(a=1;~-m;)--m,a*=m*m;return a%b}
b=>eval('for(m=b,a=1;~-m;--m,a*=m*m)a%b')
b=>(f=a=>~-m?(--m,f(a*=m*m)):a%b)(1,m=b)

लूप के लिए पहला भाग ( a=n), हम उन चरों को तर्क के रूप में पारित करके शुरू कर सकते हैं। शर्त बस यह है: रिटर्न वैल्यू b?(c,f(a)):dकहां dहै। आमतौर पर cसिर्फ संशोधित करता है aइसलिए इसे इसमें मिलाया जा सकता है। तो हम इसे और भी अधिक गोल्फ का उपयोग कर सकते हैं जो मैंने उल्लेख किया है:

b=>(f=a=>~-m?(--m,f(a*=m*m)):a%b)(1,m=b)
b=>(f=a=>~-m?f(a*=--m*m):a%b)(1,m=b) // --m moved into a*=
b=>(f=a=>--m?f(a*=m*m):a%b)(1,m=b) // --m moved to condition

उस ने कहा, जैसा कि @Niel ने नोट किया है, आपके एल्गोरिथ्म को सरल बना रहा है। एक भाषा में एक एल्गोरिथ्म गोल्फ एक दूसरे में गोल्फ नहीं हो सकता है इसलिए विभिन्न एल्गोरिदम की कोशिश करना और उनकी तुलना करना सुनिश्चित करें।


1
आपने मूल कोड को सरल बनाने में एक बड़ी बचत को याद किया है। ~-mहै m-1, इसलिए लूप हो सकता है for(m=b,a=1;--m;a*=m*m)a%b;और पुनरावर्ती संस्करण हो सकता है (अप्रयुक्त)b=>(f=a=>--m?f(a*=m*m):a%b)(1,m=b)
पीटर टेलर

1
कभी-कभी आपको बस एक अलग एल्गोरिथ्म का उपयोग करना होता है, लेकिन इस मामले में सबसे अच्छा मैं कर सकता था @ पीटरटायलर के उत्तर के समान लंबाई:b=>b>1&(f=a=>--a<2||b%a&&f(a))(b)
नील

11

दुर्व्यवहार।

यह आसान है। के बजाय:

f=n=>{for(i=c=0;i<n;i++)c+=n;return c}

उपयोग

f=n=>eval("for(i=c=0;i<n;i++)c+=n;c")

ईवैल अंतिम मूल्यांकित कथन लौटाता है। इस मामले में, चूंकि अंतिम मूल्यांकन किया गया कथन होगा c+=n, इसलिए हमें cदो बाइट्स बचाते हुए, किसी भी तरह छोड़ दिया जाएगा ।

f=n=>eval("for(i=c=0;i<n;i++)c+=n")

सामान्य रूप में:

f=n=>eval("code;x")

यह बाइट से छोटा है:

f=n=>{code;return x}

एक नोट के रूप में, कब्रों का उपयोग करके कॉल करने के लिए eval को बचाने के लिए संभवतः बाइट्स बचाने के लिए काम नहीं करता है, क्योंकि:

eval`string`

के बराबर है

["string"]

मोटापे के लिए सहायक! कोड गोल्फ के लिए इतना नहीं।


2
foo`string`हमेशा के बराबर है foo(["string"]), यह सिर्फ इतना है कि कई कार्यों फिर सरणी को वांछित स्ट्रिंग में डाल दिया।
नील

@ नील ओह, कितना दिलचस्प है!
कॉनर ओ'ब्रायन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.