क्लीन में गोल्फिंग के लिए टिप्स


17

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

यदि आपने कभी Clean नहीं सुना है, तो आप यहाँ और अधिक जानकारी प्राप्त कर सकते हैं ।
या, आप चैट रूम से जुड़ सकते हैं

जवाबों:


10

import StdEnvजब संभव हो तो बचें

अंतर्निहित कार्यों तक पहुंचने के लिए, यहां तक ​​कि मूल रूप से जैसे (==)या map, एक आयात विवरण की आवश्यकता होती है, आमतौर पर import StdEnvक्योंकि यह सबसे आम मॉड्यूल को आयात करता है StdInt, StdBoolऔर इसी तरह ( अधिक जानकारी के लिए यहां देखें StdEnv)।

हालांकि कुछ चुनौतियों के लिए इस आयात से बचना संभव है और सूची की समझ और पैटर्न मिलान जैसी मुख्य भाषा सुविधाओं का उपयोग करें।

उदाहरण के लिए, के बजाय

import StdEnv 
map f list

कोई लिख सकता है

[f x\\x<-list]

विकल्पों की सूची:

कुछ फ़ंक्शन या फ़ंक्शन इनवोकेशन की आवश्यकता होती है import StdEnv, एक विकल्प जो आयात की आवश्यकता नहीं है और बाइट्स के किसी न किसी अनुमान को बचाया गया है।

  • hd-> (\[h:_]=h), ~ 6 बाइट्स
  • tl-> (\[_:t]=t), ~ 6 बाइट्स
  • map f list-> [f x\\x<-list], ~ 10 बाइट्स
  • filter p list-> [x\\x<-list|p x], ~ 11 बाइट्स
  • (&&)-> %a b|a=b=a;%, ~ 6 बाइट्स
  • (||)-> %a b|a=a=b;%, ~ 6 बाइट्स
  • not-> %a|a=False=True;%, ~ 1 बाइट
  • and-> %[a:r]|a= %r=a;%_=True, ~ 0 बाइट्स
  • or-> %[a:r]|a=a= %r;%_=False, ~ 0 बाइट्स

अंतिम कुछ वास्तव में बाइट्स को बचाने की संभावना नहीं है, क्योंकि एक सीधा प्रतिस्थापन आयात की तुलना में अधिक बाइट्स देता है, लेकिन यह उन मामलों में संभव हो सकता है जहां सूची में पुनरावृत्ति की आवश्यकता होती है।

इस टिप का सफलतापूर्वक उपयोग यहां किया गया है


ना import StdEnv+ a and bकी तुलना में छोटे (21 बाइट्स) %[a:r]|a= %r=a;%_=True, (22 बाइट्स) हालांकि? या यह import StdEnv+ a=True and b=True(31 बाइट्स) होगा, इस मामले में यह वास्तव में निश्चित रूप से छोटा है? (मैंने क्लीन,
बीटीडब्लू

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

4
आह अच्छा। शायद यह बताने के लिए भी उपयोगी हो सकता है कि वैकल्पिक (यानी map f list -> [f x\\x<-list] (11 bytes saved)(या कुछ इसी तरह)) के साथ कितने बाइट बचाए जाते हैं ।
केविन क्रूज़सेन

@ केविनक्रूजसेन किया।
लैकोनी

5

भाषा सीखना सीखें

आखिरकार, कोई भी किसी भाषा में कैसे गोल्फ का उपयोग कर सकता है!

ऑनलाइन

स्वच्छ एक अच्छी तरह से ज्ञात या अच्छी तरह से प्रलेखित भाषा नहीं है, और नाम निश्चित रूप से इन मुद्दों को हल करने के लिए बहुत आवश्यक संसाधनों को ढूंढना आसान नहीं बनाता है ... या करता है?

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

हास्केल में स्वच्छ के अधिक उल्लेखनीय समानताओं में से एक (जिनमें से कई हैं) क्लोग का अस्तित्व है , जो पुस्तकालयों को साफ करने वाले पुस्तकालयों को कवर करने वाला एक फ़ंक्शन खोज-इंजन है।

स्थानीय स्तर पर

पुस्तकालयों में स्वच्छ जहाजों के साथ शालीनतापूर्वक टिप्पणी की जाती है, कुछ स्व-दस्तावेजीकरण स्वच्छ स्रोत फाइलें, जो आईडीई का उपयोग करके ब्राउज़ करने में सक्षम हैं।
(यह पूर्ण उदाहरण कार्यक्रमों के तहत भी आता है $INSTALL/Examples।)

जिसमें से, क्लीन का विंडोज संस्करण एक आईडीई के साथ आता है - जबकि यह आधुनिक मानकों द्वारा काफी सीमित है, यह एक पाठ संपादक और कमांड-लाइन का उपयोग करने से बेहतर है।
दो सबसे उपयोगी विशेषताएं (सीखने के संदर्भ में) हैं:

  • आप यह देखने के लिए कि यह किस लाइन पर है, एक त्रुटि को डबल-क्लिक कर सकते हैं
  • आप एक मॉड्यूल नाम को हाइलाइट कर सकते हैं और [Ctrl]+[D]परिभाषा फ़ाइल खोलने के लिए दबा सकते हैं (या [Ctrl]+[I]कार्यान्वयन फ़ाइल के लिए उपयोग करें ), और परिभाषा फ़ाइल और कार्यान्वयन फ़ाइल के बीच टॉगल करें[Ctrl]+[/]

4

चरित्र एन्कोडिंग के बारे में भूल जाओ

क्लीन कंपाइलर इस बात की परवाह नहीं करता है कि आपको क्या लगता है कि आपने सोर्स फाइल को सेव किया है, बस फाइल में बाइट वैल्यूज के बारे में। इसके कुछ साफ परिणाम हैं।

स्रोत कोड के शरीर में, प्रिंट करने योग्य ASCII वर्णों के अनुरूप कोड-बिंदुओं के साथ केवल बाइट्स की अनुमति दी जाती है, उन लोगों के अलावा \t\r\n

शाब्दिक:

में Stringऔर [Char]शाब्दिक ( "stuff"और ['stuff']क्रमशः), 0 को छोड़कर किसी भी बाइट को अनुमति दी जाती है, इस चेतावनी के साथ "और '( Stringऔर [Char]क्रमशः) से बच जाना चाहिए , और यह कि नए सिरे और कैरिज रिटर्न को क्रमशः \nऔर \r(क्रमशः भी) बदला जाना चाहिए ।

में Charशाब्दिक, 0 को छोड़कर किसी भी बाइट की अनुमति दी है, जिसका अर्थ है कि:

'\n'

'
'

समान हैं, लेकिन दूसरा एक बाइट कम है।

भागने:

स्टैण्डर्ड लेटर \t\r\nएस्केप (आदि) से इतर, क्लीन में सभी नॉन-न्यूमेरिक एस्केप सीक्वेंस या तो स्लैश के लिए होते हैं, या फिर क्वैटल के लिए इस्तेमाल किया जाता है।

न्यूमेरिक एस्केप सीक्वेंस के लिए, संख्या को तीन अंकों के बाद समाप्त हुए एक ऑक्टल मान के रूप में माना जाता है। इसका मतलब यह है कि यदि आप एक चरित्र 1में एक अशक्त होना चाहते हैं String, तो आपको "\0001"(या "\0\61") का उपयोग करने की आवश्यकता है और नहीं "\01" । हालांकि, यदि आप कुछ भी लेकिन संख्याओं के साथ भागने का पालन करते हैं, तो आप अग्रणी शून्य को छोड़ सकते हैं।

परिणाम:

यह क्विक कैसे क्लीन अपनी सोर्स फाइल्स को हैंडल करता है Stringऔर ['Char']बेस-256 सिंगल-डिजिट नंबरों के सीक्वेंस बनने की अनुमति देता है - जिसमें कोड-गोल्फ के लिए उपयोगों की भीड़ होती है, जैसे कि इंडेक्स (255 तक, निश्चित रूप से)।


3

नाम प्रतीकों के साथ कार्य करता है

किसी फ़ंक्शन को परिभाषित करते समय, अक्सर !@$%^&*~-+=<:|>.?/\अल्फ़ान्यूमेरिक वर्णों का उपयोग करने की तुलना में कुछ संयोजन का उपयोग करना कम होता है , क्योंकि यह आपको पहचानकर्ताओं के बीच श्वेत-स्थान को छोड़ने की अनुमति देता है।

उदाहरण के लिए: ?a=a^2की तुलना में कम है f a=a^2, और इसे लागू करने के साथ ही कम है।

हालाँकि :

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

उदाहरण के लिए: ?a+?bपर्स के रूप में? a +? b

इसके अतिरिक्त:

क्लीन में आयातित पहचानकर्ताओं को अधिलेखित करना संभव है, और केवल एकल-वर्ण प्रतीक पहचानकर्ता जो पहले से उपयोग नहीं किए गए StdEnvहैं @$?। ओवरराइट करने ^-+यदि आप और अधिक प्रतीकात्मक पहचानकर्ता की जरूरत है (आदि) उपयोगी हो सकता है, लेकिन सावधान रहना है कि आप अधिलेखित एक प्रयोग कर रहे हैं नहीं है।


3

अपने K नोड्स को जानें

कार्यात्मक भाषाओं में सबसे मजबूत निर्माण (गोल्फ के लिए) हैं let ... in ...
निश्चित रूप से स्वच्छ, इस है, और कुछ बेहतर - #

एक नोड क्या है?

क्लीन #और सर्वव्यापी |(पैटर्न गार्ड) दोनों को 'नोड एक्सप्रेशन' के रूप में जाना जाता है।
विशेष रूप से, वे आपको अनिवार्य रूप से स्वच्छ में ईश का कार्यक्रम करने की अनुमति देते हैं (जो वास्तव में यहाँ अच्छा है!)।

#(जाने-से पहले):

ये दोनों एक स्ट्रिंग के रूप में दिए गए पूर्णांक के मूल्य की गणना करते हैं, इसके वर्णों के योग से गुणा करते हैं

f s=let i=toInt s;n=sum[toInt c\\c<-:s]in n*i

f s#i=toInt s
#s=sum[toInt c\\c<-:s]
=s*i

ध्यान दें कि किस प्रकार का संस्करण #छोटा है, और हम कैसे फिर से परिभाषित कर सकते हैं s। यह उपयोगी है अगर हमें उस मूल्य की आवश्यकता नहीं है जो एक चर है जब हम इसे प्राप्त करते हैं, इसलिए हम केवल नाम का फिर से उपयोग कर सकते हैं। ( letजब आप ऐसा करते हैं तो मुद्दों में भाग सकते हैं)

लेकिन letजब आपको किसी चीज़ की ज़रूरत होती है तो इसका उपयोग करना आसान होता हैflip f = let g x y = f y x in g

|(पैटर्न गार्ड):

क्लीन के पैटर्न गार्ड को कई अन्य कार्यात्मक भाषाओं में उन लोगों की तरह इस्तेमाल किया जा सकता है - हालांकि इसे एक अनिवार्यता की तरह भी इस्तेमाल किया जा सकता है if ... else ...। और टर्नरी अभिव्यक्ति का एक छोटा संस्करण।

उदाहरण के लिए, ये सभी पूर्णांक का संकेत देते हैं:

s n|n<>0|n>0=1= -1
=0

s n=if(n<>0)if(n>0)1(-1)0

s n|n>0=1|n<0= -1=0

बेशक, अंतिम एक जो गार्ड का अधिक परंपरागत रूप से उपयोग करता है वह सबसे छोटा है, लेकिन पहले वाला दिखाता है कि आप उन्हें घोंसला दे सकते हैं (लेकिन लेआउट नियम में केवल दो बिना शर्त वापसी खंड एक ही पंक्ति में दिखाई दे सकते हैं), और दूसरा दिखाता है कि क्या पहले एक तार्किक रूप से करता है।

एक नोट:

आप इन अभिव्यक्तियों का उपयोग मूल रूप से कहीं भी कर सकते हैं। Lambdas में, case ... of, let ... in, आदि


1

यदि आप उपयोग कर रहे हैं तो आपको उपयोग Stringकरना चाहिएText

स्ट्रिंग्स में रूपांतरण, और स्ट्रिंग्स का हेरफेर ( {#Char}/ Stringतरह, न कि [Char]तरह) गोल्फ के लिए काफी लंबा और खराब है। Textमॉड्यूल उपचार इस।

रूपांतरण:

Textपरिभाषित किए गए <+किसी भी दो प्रकार के लिए ऑपरेटर को toStringपरिभाषित करता है।
यह ऑपरेटर, जैसा a<+bकि उपयोग किया जाता है toString a+++toString b- कम से कम 19 बाइट्स की बचत करता है । यहां तक ​​कि अगर आप अतिरिक्त आयात को शामिल करते हैं ,Text, और केवल एक बार इसका उपयोग करते हैं, तो यह अभी भी 14 बाइट बचाता है!

हेरफेर:

Textकुछ स्ट्रिंग-हेरफेर स्टेपल को परिभाषित करता है जो से गायब हैं StdEnv:

  • +तार के लिए ऑपरेटर , जो +++(से StdEnv) की तुलना में बहुत कम है
  • indexOf, विफलता के -1बजाय लौटने के सी-लाइक व्यवहार के साथNothing
  • concat, जो तार की एक सूची को संक्षिप्त करता है
  • join, जो एक विभाजक स्ट्रिंग का उपयोग करके तार की एक सूची में शामिल होता है
  • split, जो एक स्ट्रिंग को स्ट्रिंग पर एक स्ट्रिंग की सूची में विभाजित करता है

1

छोटे लांबडा का प्रयोग करें

कभी-कभी आप खुद को लंबोदर अभिव्यक्ति (पास करने map, या sortBy, आदि) का उपयोग करते हुए पाते हैं । जब आप ऐसा कर रहे हों (लंबोदर लेखन), तो आपके द्वारा इसे करने के तरीकों का एक समूह है।

सही तरीका:

यह sortByएक मुहावरेदार मेमने की छँटाई के साथ सबसे छोटी से छोटी सूची है

sortBy (\a b = length a > length b)

दूसरा सही तरीका:

यदि आप उपयोग कर रहे हैं Data.Func, तो आप भी कर सकते हैं

sortBy (on (>) length)

संक्षिप्त तरीका:

यह एक ही बात है, लेकिन एक गोल्फ सिंटैक्स के साथ

sortBy(\a b=length a>length b)

कोई दूसरा रास्ता:

इस समय रचना का उपयोग कम नहीं है, लेकिन यह कभी-कभी कम हो सकता है

sortBy(\a=(>)(length a)o length)

अन्य तरीके:

जबकि यह यहाँ थोड़ा सा विरोधाभास है, आप लैम्ब्डा में गार्ड का उपयोग कर सकते हैं

sortBy(\a b|length a>length b=True=False)

और नोड-एक्सप्रेशन से पहले भी दें

sortBy(\a b#l=length
=l a>l b)

एक नोट:

लैम्ब्डा के दो और रूप हैं, (\a b . ...)और (\a b -> ...), जिनमें से बाद वाले =संस्करण के समान है , और जिनमें से पूर्व किसी कारण से मौजूद है और अक्सर ऐसा लगता है कि आप एक लैम्ब्डा को परिभाषित करने के बजाय किसी संपत्ति का उपयोग करने की कोशिश कर रहे हैं इसलिए डॉन 'इसका उपयोग न करें।


1
आपके कुछ गोल्फ कार्यक्रमों को देखने के बाद, मुझे यह आभास हो \a=... गया था कि क्लीन का सामान्य लंबोदर सिंटैक्स है: पी
अर्जन जोहान्सन

आप लैम्बडा में गार्ड्स को भी जोड़ सकते हैं, जैसा कि यहाँ इस्तेमाल किया गया है । यह अनिर्दिष्ट है (यह भाषा की रिपोर्ट का भी विरोधाभासी है), लेकिन काम करता है। इसके अलावा, ->और =लंबोदर के लिए समान हैं जहां तक ​​संकलक का संबंध है ( ->पुराना वाक्यविन्यास है)। केवल .अलग है (लेकिन मुझे नहीं पता कि कैसे)।

और इस विशेष उदाहरण में आप उपयोग करने पर विचार कर सकते हैं on(<)length, हालांकि Data.Funcआयात आपको तब तक तोड़ देगा जब तक कि आपको पहले से ही इसकी आवश्यकता न हो।

@ कीलन कूल मैं इसे आज बाद में अपडेट करूंगा। मुझे लगता है कि आप #लेम्बडास में लेट- बिफोर ( ) का उपयोग कर सकते हैं ।
Οसूर्य

हाँ तुम कर सकते हो :-)

0

चरित्र सूची साहित्य का उपयोग करें

एक चरित्र सूची शाब्दिक की तरह कुछ लिखने की एक आशुलिपि तरीका है ['h','e','l','l','o']के रूप में['hello']

उदाहरण के लिए, यह नोटेशन की सीमा नहीं है:

  • repeat'c'बन ['c','c'..]जाता है['cc'..]
  • ['z','y'..'a'] हो जाता है ['zy'..'a']
  • ['beginning']++[a,b,c]++['end'] हो जाता है ['beginning',a,b,c,'end']
  • ['prefix']++suffix हो जाता है ['prefix':suffix]

मिलान में भी ये काम:

  • ['I don't care about the next character',_,'but I do care about these ones!']

0

कभी कभी code छोटा होता है

मानक पुस्तकालयों में स्वच्छ वास्तव में उपयोगी कार्यों का एक गुच्छा है, जिनमें से कुछ का उपयोग करने *World, और उपयोग करने के बिना अविश्वसनीय रूप से क्रिया करने के लिए उपयोग किया जाता है*World कोड-गोल्फ में करना आमतौर पर वैसे भी एक बुरा विचार है।

इस समस्या को हल करने के लिए, अक्सर ccallआप अंदर उपयोग कर सकते हैंcode बजाय ब्लॉक के ।

कुछ उदाहरण:

सिस्टम का समय

import System.Time,System._Unsafe
t=toInt(accUnsafe(time))

उपरोक्त 58 बाइट्स हैं, लेकिन आप 17 बाइट्स (40 से नीचे + 1) बचा सकते हैं:

t::!Int->Int
t _=code{ccall time "I:I"
}

रैंडम नंबर

यह एक बाइट्स को अपने आप नहीं बचाता है, लेकिन एक सूची से पास होने से बचा जाता है genRandInt

s::!Int->Int
s _=code{ccall time "I:I"ccall srand "I:I"
}
r::!Int->Int
r _=code{ccall rand "I:I"
}

अन्य उपयोग

इन दोनों के अलावा, जो शायद कोड-गोल्फ में इसके लिए मुख्य उपयोग हैं, आप किसी भी नामित फ़ंक्शन (सहित हर syscall तक सीमित नहीं) को कॉल कर सकते हैं instruction <byte>, एबीसी मशीन के लिए मनमाना विधानसभा , और एम्बेड कोड एम्बेड कर सकते हैं।

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