रूबी में गोल्फ के लिए टिप्स


62

रूबी में गोल्फिंग के लिए आप क्या सामान्य सुझाव दे सकते हैं?

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

कृपया प्रति उत्तर एक टिप पोस्ट करें।


किसी को रूब नामक एक भाषा लिखने की ज़रूरत है, जो हर रूबी टोकन के लिए एक एकल यूनिकोड चरित्र का उपयोग करता है, जेली और अजगर की तरह थोड़े :)
मार्क थॉमस

जवाबों:


46
  • 126 के लिए संख्या 100 के रूप में लिखा जा सकता है ?dके लिए ?~1.8 में।
  • एक समान नोट पर अगर आपको 1.9 में एकल-वर्ण स्ट्रिंग की आवश्यकता है? X "x" से छोटा है।
  • यदि आपको एक नई लाइन को लागू किए बिना एक स्ट्रिंग प्रिंट करने की आवश्यकता है, $><<"string"तो इससे कम है print"string"
  • यदि आपको पढ़ने की आवश्यकता है तो इनपुट की कई पंक्तियों की $<.map{|l|...}तुलना में कम है while l=gets;...;end। इसके अलावा, आप $<.readइसे एक ही बार में पढ़ने के लिए उपयोग कर सकते हैं ।
  • यदि आप किसी फ़ाइल से पढ़ने वाले हैं, $<और getsफ़ाइल नाम होने पर स्टडिन के बजाय किसी फ़ाइल से पढ़ा जाएगा ARGV। तो फिर से लागू करने का गोल्फ का तरीका catहोगा $><<$<.read:।

1
x सामान्य रूप से एससीआई कोड का उत्पादन करता है, जिससे आप वास्तविक रूप से दो अक्षरों में अंकों के सभी प्रिंट प्राप्त कर सकते हैं। 1.9 अलग है, 'a'.ord से एससीआई नंबर मिलता है, लेकिन दशमलव संस्करण की तुलना में चार बाइट्स लंबा है।
हयातो

8
लागू करने के लिए एक गोल्फर तरीका catयह है कि रूबी फ़ाइल को पूरी तरह से खाली (0 बाइट्स) छोड़ दें और जोर दें कि इसे -pध्वज के साथ कमांड लाइन से चलाया जाना चाहिए ।
डानिएरो

1
या, @ daniero के स्वयं के उत्तर से ,puts *$<
नहीं कि चार्ल्स

1
तो 1.8 में, मुझे बस इतना करना है? ~ और यह 126 वापस आ जाएगी।
ब्यूटीफुल आर्ट

5
आप की तरह सोचता है का उपयोग करते हुए 126 के पार जा सकते या , या आप पर्याप्त पागल हो तो:?﷽.ord=65021
आप सुंदर कला

32

एरे की पूंछ और सिर पाने के लिए स्पैट ऑपरेटर का उपयोग करें:

head, *tail = [1,2,3]
head => 1
tail => [2,3]

यह दूसरे तरीके से भी काम करता है:

*head, tail = [1,2,3]
head => [1,2]
tail => 3

*तत्वों से जुड़ने के लिए एक स्ट्रिंग पर स्ट्रिंग के साथ विधि का उपयोग करें :

[1,2,3]*?,
=> "1,2,3"

27
  • abortकार्यक्रम को समाप्त करने और STDERR को एक स्ट्रिंग प्रिंट करने के लिए उपयोग करें - putsइसके बाद की तुलना में कमexit
  • यदि आप एक पंक्ति पढ़ते हैं gets, तो आप ~/$/इसकी लंबाई ज्ञात करने के लिए उपयोग कर सकते हैं (यदि यह मौजूद है तो एक अनुगामी न्यूलाइन की गणना नहीं करता है)
  • []यह जांचने के लिए उपयोग करें कि क्या एक स्ट्रिंग में दूसरा है:'foo'['f'] #=> 'f'
  • वर्ण-वार प्रतिस्थापन trके gsubलिए उपयोग करें :'01011'.tr('01','AB') #=> 'ABABB'
  • यदि आपको अनुगामी newlines को निकालने की आवश्यकता है, तो chopइसके बजाय का उपयोग करेंchomp

2
+1 के लिए abortऔर~/$/
जे -_- एल

कृपया उपयोग करने का तरीका बताएं~/$/
मैथ्यू CAROFF

@MathieuCAROFF हर बार जब आप कॉल करते हैं gets, तो इसका परिणाम $_चर में संग्रहीत होता है । /regex/ ~= stringपहले मैच का इंडेक्स लौटाता है। रेक्सक्स ~पर कॉल करना इसके बराबर है /regex/ ~= $_। तो यह कुछ इस तरह होगाs=gets;l= ~/$/
Cyoce

20

अपने को समाप्त करो end

endअपने कोड से निकालने का प्रयास करें ।

def...endकार्यों को परिभाषित करने के लिए उपयोग न करें । रूबी 1.9 में नए -> ऑपरेटर के साथ एक लैम्ब्डा बनाएं। (- -> ऑपरेटर "स्टैबी लैम्ब्डा", या "डैश रॉकेट" है ।) यह प्रति फ़ंक्शन 5 वर्ण बचाता है।

# 28 characters
def c n
/(\d)\1/=~n.to_s
end

# 23 characters, saves 5
c=->n{/(\d)\1/=~n.to_s}

विधि कॉल c nया हैं c(n)। लैंबडा कॉल हैं c[n]। प्रत्येक c nको बदलने में c[n]1 वर्ण खर्च होता है, इसलिए यदि आप c n5 से अधिक बार उपयोग कर सकते हैं , तो विधि रखें।

do...endब्लॉक लेने वाले सभी तरीकों के {...}बजाय ब्लॉक ले सकते हैं । यह 3 से 5 अक्षर बचाता है। यदि पूर्वता {...}बहुत अधिक है, तो इसे ठीक करने के लिए कोष्ठक का उपयोग करें।

# 48 characters
(?a..?m).zip (1..5).cycle do|a|puts a.join','end

# WRONG: passes block to cycle, not zip
(?a..?m).zip (1..5).cycle{|a|puts a.join','}

# 45 characters, saves 3
(?a..?m).zip((1..5).cycle){|a|puts a.join','}

टर्नरी ऑपरेटर केif...else...end साथ बदलें । यदि किसी शाखा में दो या अधिक कथन हैं, तो उन्हें कोष्ठक में लपेटें। ?:

# 67 characters
if a<b
puts'statement 1'
puts'statement 2'else
puts'statement 3'end

# 62 characters, saves 5
a<b ?(puts'statement 1'
puts'statement 2'):(puts'statement 3')

आपके पास शायद नहीं है whileया untilलूप नहीं है , लेकिन यदि आप करते हैं, तो उन्हें संशोधक रूप में लिखें।

(a+=1
b-=1)while a<b

क्या कोष्ठक puts'statement 3'आवश्यक हैं?
Cyoce

15

W0lf को जोड़ना

जब सरणियों के साथ काम करते हैं, तो 2 वर्णों को बचाने के लिए .compactप्रतिस्थापित किया जा सकता है -[nil]

ऊपर से संयुक्त -> आप इसे -[p]2 अन्य वर्णों को सहेजने के साथ छोटा भी कर सकते हैं ।


14

जहाँ भी संभव हो, छोटे पूर्वनिर्धारित चर का उपयोग करें, जैसे कि $*इसके बजाय ARGV। यहां उनकी एक अच्छी सूची है , साथ में बहुत सी अन्य उपयोगी जानकारी भी है।


12

जब आप स्ट्रिंग इंटरपोलेशन का उपयोग कर रहे हैं, (जैसा कि आपको मार्टिन बंटनर के पद पर होना चाहिए ), तो आपको घुंघराले कोष्ठक की आवश्यकता नहीं है यदि आपकी वस्तु के सामने एक सतर्क ( $, @) है। की तरह जादुई चर के लिए उपयोगी $_, $&, $1आदि:

puts "this program has read #$. lines of input"

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

a=42; puts "here is a: #{a}"; puts "here is a again: #{a}"
$b=43; puts "here is b: #$b"; puts "here is b again: #$b"

11

यदि आपको यह खोजने की आवश्यकता है कि क्या कोई विशेष तत्व eएक सीमा के अंदर है r, तो आप उपयोग कर सकते हैं

r===e

इसके बजाय लंबे समय तक:

r.cover?(e) # only works if `r.exclude_end?` is false

या

r.member?(e)

या

r.include?(e)

3
r===eकम भी नहीं है?
एकुहन

@akuhn हाँ, यह है। बहुत छोटा। इस ओर इशारा करने के लिए धन्यवाद, इसने मेरे कोड को 10 वर्णों से छोटा करने में मदद की, जो बहुत बड़ा है: codegolf.stackexchange.com/a/6125/3527
क्रिस्टियन

1
आपका स्वागत है। सब कुछ जो एक स्विच स्टेटमेंट में इस्तेमाल किया जा सकता है, ===लागू किया गया है।
आखुण

10

$_ अंतिम पठन लाइन है।

  • print - यदि कोई तर्क नहीं दिया प्रिंट सामग्री $_
  • ~/regexp/ - के लिए कम $_=~/regexp/

रूबी 1.8 में, आपके पास Kernelउस पर काम करने के चार तरीके हैं $_:

  • chop
  • chomp
  • sub
  • gsub

रूबी 1.9 में, ये चार विधियाँ केवल तभी मौजूद हैं जब आपकी लिपि उपयोग करती है -nया -p

यदि आप कुछ चर को अक्सर प्रिंट करना चाहते हैं तो उपयोग करें trace_var(:var_name){|a|p a}


2
ये केवल तब उपलब्ध होते हैं जब आप रूबी को -pया -nविकल्प के साथ चलाते हैं । संदर्भ।
डैरेन स्टोन

1
ऐसा लगता है कि trace_varकेवल वैश्विक $ चर के साथ काम करता है
daniero

10

स्ट्रिंग प्रक्षेप का उपयोग करें!

  1. बदलने के लिए to_s। यदि आप एक स्ट्रिंग में बदलना चाहते हैं, तो चारों ओर कोष्ठकों की आवश्यकता होती है, to_sयह स्ट्रिंग प्रक्षेप से दो बाइट्स लंबा है:

    (n+10**i).to_s
    "#{n+10**i}"
    
  2. संघटन को प्रतिस्थापित करने के लिए। यदि आप किसी चीज को दो अन्य तारों से घेरते हैं, तो प्रक्षेप आपको एक बाइट बचा सकता है:

    "foo"+c+"bar"
    "foo#{c}bar"
    

    यह भी काम करता है कि अगर बीच की चीज़ खुद ही समाप्‍त हो जाती है, अगर आप सिर्फ संघनन को प्रक्षेप के अंदर ले जाते हैं (एकाधिक प्रक्षेपों का उपयोग करने के बजाय):

    "foo"+c+d+e+"bar"
    "foo#{c+d+e}bar"
    

10

बचें lengthमेंif a.length<n

length6 बाइट्स है, कोड गोल्फ में थोड़ा महंगा है। कई स्थितियों में, आप यह देख सकते हैं कि किसी दिए गए बिंदु पर सरणी में कुछ भी है या नहीं। यदि आप पिछले सूचकांक को प्राप्त करते हैं nil, तो आपको एक गलत मूल्य मिलेगा ।

तो आप बदल सकते हैं:

if a.length<5करने के लिए if !a[4]-5 बाइट्स के लिए

या

if a.length>5to if a[5]-6 बाइट्स के लिए

या

if a.length<nकरने के लिए if !a[n-1]-3 बाइट्स के लिए

या

if a.length>nto if a[n]-6 बाइट्स के लिए

नोट : केवल सभी सत्य मूल्यों की एक सरणी के साथ काम करेगा। सरणी के भीतर nilया होने से falseसमस्याएँ हो सकती हैं।


4
मैं हमेशा उपयोग करता हूं size... लेकिन यह निश्चित रूप से बेहतर है। BTW, के लिए Stringभी काम करता है।
17

10

का प्रयोग न करें trueऔर falseकीवर्ड।

उपयोग:

  • !pके लिए true(धन्यवाद, हिस्टोक्रेट!)
  • !0के लिए false। यदि आप सभी की जरूरत है एक मिथ्या मूल्य है, तो आप बस p(जो रिटर्न nil) का उपयोग कर सकते हैं ।

कुछ वर्णों को बचाने के लिए।


1
जब तक आपको वास्तव में ज़रूरत नहीं है true(यानी यदि एक सत्य मान पर्याप्त है, जैसे कि अगर एक शर्त में), तो आपको भी ज़रूरत नहीं है !!
मार्टिन एंडर

4
और इसी तरह, p(जो मूल्यांकन करता है nil) एक छोटा फाल्सी मूल्य है। जिसका मतलब है सबसे छोटा रास्ता trueहै !p
histocrat

@ हिस्टोक्रेट अच्छी बात! मैंने अपना उत्तर संपादित कर दिया है।
क्रिस्टियन लुपस्कू

9

a=i,*aरिवर्स ऑर्डर में उन्हें प्राप्त करने के लिए एरे का उपयोग करें। आपको इनिशियलाइज़ करने की भी ज़रूरत नहीं है a, और यदि आप ऐसा करते हैं तो आपको एरे होने की ज़रूरत नहीं है


9

क्या तुमने कभी से एक नंबर पाने के लिए की जरूरत है ARGV, get, या कुछ इसी तरह कुछ है कि कई बार, बजाय बुलाने की क्या करने के लिए to_iउस पर, तुम बस का उपयोग कर सकते ?1.upto x{do something x times}हैं जहां एक्स एक श्रृंखला है।

इसलिए ?1.upto(a){}इसके बजाय का उपयोग करने से x.to_i.times{}आपके 2 वर्ण बच जाएंगे।

तुम भी तरह बातें फिर से लिख सकते हैं p 1 while 1या p 1 if 1के रूप में p 1while 1याp 1if 1

यह उदाहरण बहुत उपयोगी नहीं है, लेकिन इसका उपयोग अन्य चीजों के लिए किया जा सकता है।

इसके अलावा, अगर आपको किसी चर के पहले तत्व को एक चर में निर्दिष्ट करने की आवश्यकता है, तो a,=cविरोध के रूप में दो वर्णों को बचाएगाa=c[0]


9

रूबी 2.3 और 2.4 में नई सुविधाएँ

नई भाषा सुविधाओं के साथ रहना अच्छा है जो आपके गोल्फ खेल में मदद करेंगे। नवीनतम रूबी में कुछ महान हैं।

रूबी 2.3

सुरक्षित नेविगेशन ऑपरेटर: &.

जब आप एक विधि कहते हैं जो वापस आ सकती है nilलेकिन आप अतिरिक्त विधि कॉल को चेन करना चाहते हैं यदि यह नहीं है, तो आप nilमामले को संभालने वाले बाइट्स को बर्बाद करते हैं :

arr = ["zero", "one", "two"]
x = arr[5].size
# => NoMethodError: undefined method `size' for nil:NilClass

x = arr[5].size rescue 0
# => 0

"सुरक्षित नेविगेशन ऑपरेटर" अगर पूरी तरह से अभिव्यक्ति के लिए एक रिटर्न nilऔर रिटर्न देता है तो विधि कॉल की श्रृंखला को रोक देता है nil:

x = arr[5]&.size || 0
# => 0

Array#dig और Hash#dig

नेस्टेड तत्वों तक गहरी पहुंच, एक अच्छा संक्षिप्त नाम:

o = { foo: [{ bar: ["baz", "qux"] }] }
o.dig(:foo, 0, :bar, 1) # => "qux"

रिटर्न nilअगर यह एक मृत अंत हिट:

o.dig(:foo, 99, :bar, 1) # => nil

Enumerable#grep_v

Enumerable#grepसभी तत्वों का व्युत्क्रम सभी तत्वों से मिलता है जो दिए गए तर्क से मेल नहीं खाता (तुलना में ===)। जैसे grep, अगर किसी ब्लॉक को दिया जाता है तो उसका परिणाम बदले में दिया जाता है।

(1..10).grep_v 2..5 # => [1, 6, 7, 8, 9, 10]
(1..10).grep_v(2..5){|v|v*2} # => [2, 12, 14, 16, 18, 20]

Hash#to_proc

एक प्रोक लौटाता है जो दी गई कुंजी के लिए मान देता है, जो बहुत काम आ सकता है:

h = { N: 0, E: 1, S: 2, W: 3 }
%i[N N E S E S W].map(&h)
# => [0, 0, 1, 2, 1, 2, 3]

रूबी 2.4

रूबी 2.4 अभी तक बाहर नहीं है, लेकिन यह जल्द ही होगा और इसमें कुछ शानदार फीचर होंगे। (जब यह रिलीज़ हो जाएगा तो मैं इस पोस्ट को डॉक्स के कुछ लिंक के साथ अपडेट करूंगा।) मैंने इस महान ब्लॉग पोस्ट में इनमें से अधिकांश के बारे में सीखा ।

Enumerable#sum

अब और नहीं arr.reduce(:+)। अब आप बस कर सकते हैं arr.sum। यह एक वैकल्पिक प्रारंभिक मान तर्क लेता है, जो न्यूमेरिक तत्वों ( [].sum == 0) के लिए 0 से चूकता है । अन्य प्रकारों के लिए आपको एक प्रारंभिक मूल्य प्रदान करना होगा। यह एक ब्लॉक को भी स्वीकार करता है जो प्रत्येक तत्व को जोड़ने से पहले लागू किया जाएगा:

[[1, 10], [2, 20], [3, 30]].sum {|a,b| a + b }
# => 66

Integer#digits

यह कम से कम सबसे बड़ी महत्व के क्रम में संख्या के अंकों की एक सरणी देता है:

123.digits # => [3, 2, 1]

की तुलना में, कहते हैं 123.to_s.chars.map(&:to_i).reverse, यह बहुत अच्छा है।

एक बोनस के रूप में, यह एक वैकल्पिक मूलांक तर्क लेता है:

a = 0x7b.digits(16) # => [11, 7]
a.map{|d|"%x"%d} # => ["b", "7"]

Comparable#clamp

टिन पर दिये गये निर्देशों का पालन करो:

v = 15
v.clamp(10, 20) # => 15
v.clamp(0, 10) # => 10
v.clamp(20, 30) # => 20

चूंकि यह तुलनीय है, आप इसे किसी भी वर्ग के साथ उपयोग कर सकते हैं जिसमें तुलना, उदाहरण के लिए:

?~.clamp(?A, ?Z) # => "Z"

String#unpack1

2-बाइट से अधिक बचत .unpack(...)[0]:

"👻💩".unpack(?U)    # => [128123]
"👻💩".unpack(?U)[0] # => 128123
"👻💩".unpack1(?U)   # => 128123

के लिए प्रेसिजन तर्क Numeric#ceil, floorऔरtruncate

Math::E.ceil(1) # => 2.8
Math::E.floor(1) # => 2.7
(-Math::E).truncate(1) # => -2.7

सशर्त में कई कार्य

यह रूबी के पुराने संस्करणों में एक त्रुटि उठाता है, लेकिन 2.4 में अनुमति है।

(a,b=1,2) ? "yes" : "no" # => "yes"
(a,b=nil) ? "yes" : "no" # => "no"

गोल्फ Math::E.ceil(1)के लिए Math::E.ceil 1, और इसी तरह के लिए floorऔर truncate
बस सुंदर कला

1
@SimplyBeautifulArt मुझे उम्मीद है कि रूबी में गोल्फ खेलने वाला कोई व्यक्ति खुद उस छलांग को लगा सकेगा।
जॉर्डन

के लिए Enumerable#sum, .flatten.sum2 बाइट्स से कम है.sum{|a,b|a+b}
Asone Tuhid

(-Math::E).truncate(1)के बराबर है -Math::E.truncate(1)जो 1 बाइट से छोटा है
असोन तुहिद

1
&.इस तरह सबस्क्रिप्टिंग के साथ इस्तेमाल किया जा सकता है a&.[]i(1 बाइट से कम a&.at i)। हालाँकि, यदि कोष्ठक की आवश्यकता होती है, a||a[i]तो 1 बाइट इससे छोटा है a&.[](i)याa&.at(i)
Asone Tuhid

7

वैज्ञानिक अंकन का उपयोग अक्सर एक चार या दो से दाढ़ी बनाने के लिए किया जा सकता है:

x=1000
#versus
x=1e3

9
नोट: यह एक पूर्णांक के बजाय एक फ्लोट मान (1000.0) लौटाएगा, जिसके कारण बड़ी संख्या में गलत परिणाम हो सकते हैं।
डॉगबर्ट

4
जब प्रतिशत की आवश्यकता होती है 1e2तो आह, अच्छा है 100.0
मेंढक

इस सिद्धांत के समान, 1.0*1 char से कम है.to_f
Unihedron

7

कोष्ठक के बजाय ऑपरेटर विधियों का उपयोग करें

मान लीजिए कि आप व्यक्त करना चाहते हैं a*(b+c)। पूर्वता के कारण, a*b+c(स्पष्ट रूप से) काम नहीं करेगा। ऑपरेटरों के बचाव में आते ही रूबी का शांत तरीका! आप a.*b+cकी *तुलना में कम की पूर्वता बनाने के लिए उपयोग कर सकते हैं +

a*(b+c) # too long
a*b+c   # wrong
a.*b+c  # 1 byte saved!

यह !और ~ऑपरेटरों के साथ भी काम कर सकता है (एकात्मक +या अनुपयोगी जैसी चीजें -काम नहीं करती हैं क्योंकि उनके तरीके हैं -@और +@, बचत ()लेकिन जोड़ना .@)

(~x).to_s # too long
~x.to_s   # error
x.~.to_s  # 1 byte saved!

6

का प्रयोग करें ||बजाय orऔर &&बजाय and

andऑपरेटर के चारों ओर रिक्त स्थान (और शायद ब्रैकेट) को बचाने के लिए आप में से एक चरित्र के अलावा ।

p true and false ? 'yes' :'no'   #-> true (wrong result)
p (true and false) ? 'yes' :'no' #-> 'no'
p true&&false ? 'yes' :'no'      #-> 'no', saved 5 characters


p true or false ? 'yes' :'no'   #-> true (wrong result)
p (true or false) ? 'yes' :'no' #-> 'yes'
p true||false ? 'yes' :'no'      #-> 'yes', saved 4 characters

यदि आप एक सरणी पर लूप करते हैं जो आप सामान्य रूप से उपयोग करते हैं each। लेकिन mapएक सरणी पर लूप भी होता है और यह एक वर्ण छोटा होता है।


6

मैंने सिर्फ एक TDD कोड-गोल्फ चैलेंज का प्रयास किया है, जिसमें चश्मा पास बनाने के लिए सबसे छोटा कोड लिखें। ऐनक कुछ इस तरह थे

describe PigLatin do
  describe '.translate' do
    it 'translates "cat" to "atcay"' do
      expect(PigLatin.translate('cat')).to eq('atcay')
    end
    # And similar examples for .translate
  end
end

कोड-गोल्फ के लिए, एक मॉड्यूल या वर्ग बनाने की आवश्यकता नहीं है।

के बजाय

module PigLatin def self.translate s;'some code'end;end

कोई भी कर सकता है

def(PigLatin=p).translate s;'some code'end

13 अक्षर बचाता है!


7
हा, बहुत गहन। न केवल आपने आवश्यक व्यवहार को PigLatin, बल्कि , और @pig_latin, से भी जोड़ा । $pig_latin'pig'['latin']
हिस्टोक्रेट

@ हिस्टोक्रेट: अब मैं समझ गया। ऐसा इसलिए translateहै क्योंकि इसे परिभाषित किया गया है nil
एरिक डुमिनील

6

कर्नेल # पी एक मजेदार विधि है।

के p varबजाय का उपयोग करें puts var। यह पूर्णांक और फ्लोट के साथ पूरी तरह से काम करता है, लेकिन सभी प्रकार के साथ नहीं। यह स्ट्रिंग्स के चारों ओर उद्धरण चिह्नों को छापता है, जो संभवतः वह नहीं है जो आप चाहते हैं।

एक तर्क के साथ प्रयोग किया जाता है, pइसे मुद्रित करने के बाद तर्क देता है।

कई तर्कों के साथ उपयोग किया जाता है, pएक सरणी में तर्कों को लौटाता है।

के pबजाय (कोई तर्क के साथ) का उपयोग करें nil


10
दुर्भाग्य से p 'some string'प्रिंट करता है "some string"और न केवल some stringजो अक्सर दूसरों द्वारा आलोचना की जाती है।
पैट्रिक ऑसिटी

1
मूल रूप p sसे के रूप में ही है puts s.inspect, लेकिन यह रिटर्नs
साइओस

6

# उपयोग न करें। आप सभी तत्वों पर # ठीक से ठीक से लूप कर सकते हैं। इसलिए इसके बजाय

ARGV.each{|x|puts x}

आप कम बाइट्स में भी ऐसा कर सकते हैं।

ARGV.map{|x|puts x}

बेशक, इस मामले में puts $*भी कम होगा।


तर्कसंगत और जटिल संख्या के लिए शाब्दिक हैं:

puts 3/11r == Rational(3,11)
puts 3.3r == Rational(66,20)
puts 1-1.i == Complex(1,-1)

=> true
true
true

आप स्ट्रिंग के भीतर अधिकांश बाइट्स का उपयोग कर सकते हैं। "\x01"(6 बाइट्स) को छोटा किया जा सकता है ""(3 बाइट्स)। यदि आपको केवल इस एक बाइट की आवश्यकता है, तो इसे और भी छोटा किया जा सकता है ?(2 बाइट्स)।

एक ही टोकन के द्वारा, आप इस तरह से छोटी नई पंक्तियाँ प्राप्त कर सकते हैं:

(0..10).to_a.join'
'

 => "0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10"

आप उपयोग कर सकते हैं ?\nऔर ?\tसाथ ही, जो एक बाइट से छोटा है "\n"और "\t"। स्थगन के लिए, वहाँ भी? \ S, एक स्थान।


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

A=C+B=7+C=9

=> A=17, B=16, C=9

इससे कम C=9;B=16;A=17या अधिक है C=0;B=C+7;A=C+B


यदि आपको एक अनंत लूप की आवश्यकता है, तो उपयोग करें loop{...}। अज्ञात छोरों के छोर अन्य छोरों से छोटे हो सकते हैं:

loop{break if'
'==f(gets)}

while'
'!=f(gets);end

कुछ और gsub / regexp ट्रिक। '\1'ब्लॉक के बजाय विशेष एस्केप वर्णों का उपयोग करें :

"golf=great short=awesome".gsub(/(\w+)=(\w+)/,'(\1~>\2)')

"golf=great short=awesome".gsub(/(\w+)=(\w+)/){"(#{$1}~>#{$2})")

और विशेष चर $1आदि यदि आपको ऑपरेशन करने की आवश्यकता है। ध्यान रखें कि वे न केवल ब्लॉक के अंदर परिभाषित हैं:

"A code-golf challenge." =~ /(\w+)-(\w+)/
p [$1,$2,$`,$']

=> ["code", "golf", "A ", " challenge."] 

रिक्त स्थान, newlines और कोष्ठक से छुटकारा पाएं। माणिक में आप काफी कुछ छोड़ सकते हैं। यदि संदेह है, तो हमेशा कोशिश करें अगर यह बिना काम करता है, और ध्यान रखें कि यह कुछ संपादक वाक्यविन्यास को उजागर कर सकता है ...

x+=1if$*<<A==????::??==??

"कृपया प्रति उत्तर एक टिप पोस्ट करें।" यह ?\nभी अच्छा है, लेकिन वास्तव में उद्धरण के अंदर एक नया चरित्र डालने से कम नहीं है। (टैब के लिए भी यही)
मार्टिन एंडर

और puts$*उससे भी छोटा है।
साइओस

मुझे पता है कि आप एक बिंदु को साबित करने की कोशिश कर रहे थे, लेकिन मुझे पूरा यकीन है कि अंतिम उदाहरण के रूप में एक ही हैx+=1;$*<<A
असोन तुहिद

6

फिर भी स्पैट ऑपरेटर का उपयोग करने का एक और तरीका: यदि आप एकल सरणी शाब्दिक असाइन करना चाहते हैं, *तो बाएं हाथ की तरफ दाईं ओर कोष्ठक की तुलना में छोटा है:

a=[0]
*a=0

कई मूल्यों के साथ आपको स्पैट ऑपरेटर (उस पर मुझे सही करने के लिए हिस्टोक्रेट के लिए धन्यवाद) की भी आवश्यकता नहीं है:

a=[1,2]
a=1,2

बाद वाले मामले को वास्तव में स्पैट की जरूरत नहीं है।
हिस्टोक्रेट

@histocrat ओह वाह, मैंने सोचा था कि उस मामले में दूसरा मूल्य छोड़ दिया जाएगा।
मार्टिन एंडर

1
मुझे विश्वास नहीं हो रहा है कि मैंने रूबी में गोल्फिंग में जो समय बिताया है, मैं उन्हें नहीं जानता हूं।
दरवाज़े

6

जब एक चुनौती की आवश्यकता होती है कि आप कई लाइनों का उत्पादन करते हैं, तो आपको अपने परिणामों के माध्यम से लूप करने की आवश्यकता नहीं होती है , जैसे कि एक सरणी की प्रत्येक पंक्ति को प्रिंट करने के लिए। putsविधि एक सरणी समतल और एक अलग लाइन पर प्रत्येक तत्व प्रिंट होगा।

> a = %w(testing one two three)
> puts a
testing
one
two
three

#pआपके साथ स्पैट ऑपरेटर को मिलाकर इसे और भी छोटा बना सकते हैं:

p *a

स्पैट ऑपरेटर (तकनीकी रूप से *@विधि, मुझे लगता है) आपके गैर-सरणी एन्यूमरैबल्स को सरणियों के लिए भी रखता है:

> p a.lazy.map{|x|x*2}
#<Enumerator::Lazy: #<Enumerator::Lazy: [1, 2, 3]>:map>

बनाम

> p *a.lazy.map{|x|x*2}
2
4
6

1
*@एक विधि नहीं है,
स्प्लैट सिंथैटिक

6

किसी सरणी के दोहराए गए तत्वों को हटाते समय कुछ बाइट्स सहेजें

a.uniq # before
a|[]   # after
    ^^

यदि आप []किसी चर में खाली सरणी का उपयोग कर रहे हैं, तो आप और भी बाइट्स बचा सकते हैं:

a.uniq;b=[] # before
a|b=[]      # after
      ^^^^^

2
पहले मामले के लिए, a&a1 बाइट छोटी है
असोन तुहिद

5

रूबी के बजाय गोरबी का उपयोग करें, जो रूबी के संक्षिप्त संस्करण की तरह है। आप इसे आरवीएम के माध्यम से स्थापित कर सकते हैं

rvm install goruby

गोरबी आपको अपना अधिकांश कोड लिखने की अनुमति देती है जैसा कि आप रूबी लिख रहे होंगे, लेकिन अतिरिक्त संक्षिप्त रूप में बनाया गया है। किसी चीज के लिए सबसे कम उपलब्ध संक्षिप्त नाम जानने के लिए, आप सहायक विधि का उपयोग कर सकते हैं shortest_abbreviation, उदाहरण के लिए:

shortest_abbreviation :puts
#=> "pts"

Array.new.shortest_abbreviation :map
#=> "m"

String.new.shortest_abbreviation :capitalize
#=> "cp"

Array.new.shortest_abbreviation :join
#=> "j"

इसके अलावा बहुत आसान उपनाम sayहै putsजिसके लिए खुद को संक्षिप्त किया जा सकता है s। इसलिए इसके बजाय

puts [*?a..?z].map(&:capitalize).join

अब आप लिख सकते हैं

s [*?a..?z].m(&:cp).j

राजधानियों में वर्णमाला को मुद्रित करने के लिए (जो कि अच्छा उदाहरण नहीं है)। यह ब्लॉग पोस्ट अधिक सामान और कुछ आंतरिक कामकाज की व्याख्या करता है यदि आप आगे पढ़ने में रुचि रखते हैं।

पुनश्च: hविधि पर याद नहीं है ;;


अधिक से अधिक 2 साल बाद और मैं अंत में पता लगा है कि इस सवाल का जवाब की मुझे याद दिलाता है ...
undergroundmonorail

5

इसके बजाय एक सरणी में शामिल होने के लिए

[...].join

यह करो

[...]*''

जो 2 बाइट्स बचाता है। एक विभाजक उपयोग के साथ जुड़ने के लिए

[...]*?,

5

सदस्यता संख्याएँ!

मैंने कल ही इसकी खोज की थी। -th स्थिति में n[i]रिटर्न nथोड़ा है i। उदाहरण:

irb(main):001:0> n = 0b11010010
=> 210
irb(main):002:0> n[0]
=> 0
irb(main):003:0> n[1]
=> 1
irb(main):004:0> n[2]
=> 0
irb(main):005:0> n[3]
=> 0
irb(main):006:0> n[4]
=> 1
irb(main):007:0> n[5]
=> 0

और अब आप अधिक तर्कों का उपयोग कर सकते हैं जैसे किn[0..3]
बस सुंदर कला

4

आप 2 वर्णों को सहेजने और उपयोग करने में सक्षम हो सकते हैं

[*(...)]

के बजाय

(...).to_a

उदाहरण के लिए, मान लें कि हमारे पास एक श्रेणी है जिसे हम एक सरणी के रूप में चाहते हैं:

(1..2000).to_a

बस इसे इस तरह से करें:

[*1..2000]  #  Parentheses around the (ran..ge) is not needed!

और अब आपके पास एक सरणी के रूप में आपकी सीमा है।


5
मुझे लगता है कि [*1..2000]काम करता है, भी?
लिन

4

<< चाल

a.push x

इसे छोटा किया जा सकता है:

a<<x

-4 बाइट्स के लिए।


2
नोट: यह String
बजे

4

Array#assoc/rassoc

जब आपके पास सरणियों की एक सरणी होती है और किसी विशेष मान से शुरू होने वाले उप-सरणी को खोजना चाहते हैं, तो उपयोग न करें Enumerable#find, उपयोग करें Array#assoc:

a = [[0,"foo"],[0,"bar"],[1,"baz"],[0,"qux"]]
a.find{|x,|x==1} # => [1,"baz"]
a.assoc(1) # => [1,"baz"]

यह Enumerable#any?कुछ स्थितियों के लिए एक अच्छा प्रतिस्थापन भी है।

Array#rassoc एक ही बात करता है, लेकिन उप-सरणियों के अंतिम तत्व की जांच करता है:

a = [[123,"good"],[456,"good"]]
a.any?{|*,x|x=="bad"} # => false
a.rassoc("bad") # => nil

उदाहरण के लिए a.any?लाइन में rassoc , क्या करता |x,|है? यह किस तरह से अलग है |x|?
साइओस

@Cyoce ब्लॉक पैरामीटर डिस्ट्रक्ट्यूरिकिंग असाइनमेंट के समान नियमों का पालन करता है, इसलिए यह x=[1,2]बनाम की तरह है x,=[1,2]। मेरे उदाहरण का उपयोग करके, |x|पहले पुनरावृति में xहोगा [0,"foo"]। के साथ |x,y|, xहोगा 0और yहोगा "foo"। इसी तरह, साथ |x,|, xहोगा 0। दूसरे शब्दों में, यह कहता है "पहले तत्व को अंदर रखो xऔर बाकी को फेंक दो।
जॉर्डन

ध्यान दें कि यह रिवर्स में काम नहीं करता है, उदाहरण के |,y|लिए एक सिंटेक्स एरर, एर्गो है |_,y|। लेकिन मुझे अब यह एहसास हुआ है कि |*,y|काम करता है, जो एक चर नाम _(लेकिन कम नहीं) का उपयोग करके क्लीनर है ।
जॉर्डन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.