มีเคล็ดลับอะไรที่คุณสามารถให้เล่นกอล์ฟใน Ruby
ฉันกำลังมองหาความคิดที่สามารถนำไปใช้กับปัญหารหัสกอล์ฟโดยทั่วไปที่เฉพาะเจาะจงกับทับทิม (ตัวอย่างเช่น "ลบความคิดเห็น" จะไม่ใช่คำตอบ)
กรุณาโพสต์หนึ่งเคล็ดลับต่อคำตอบ
มีเคล็ดลับอะไรที่คุณสามารถให้เล่นกอล์ฟใน Ruby
ฉันกำลังมองหาความคิดที่สามารถนำไปใช้กับปัญหารหัสกอล์ฟโดยทั่วไปที่เฉพาะเจาะจงกับทับทิม (ตัวอย่างเช่น "ลบความคิดเห็น" จะไม่ใช่คำตอบ)
กรุณาโพสต์หนึ่งเคล็ดลับต่อคำตอบ
คำตอบ:
?d
ไป?~
ใน 1.8$><<"string"
print"string"
$<.map{|l|...}
while l=gets;...;end
นอกจากนี้คุณสามารถใช้$<.read
อ่านมันทั้งหมดในครั้งเดียว$<
และgets
จะอ่านจากไฟล์แทน stdin ARGV
ถ้าชื่อไฟล์ที่อยู่ใน ดังนั้นวิธีที่จะตีกอล์ฟให้ได้ผลที่สุดcat
ก็คือ: $><<$<.read
.cat
คือการปล่อยให้ไฟล์ทับทิมว่างเปล่าโดยสิ้นเชิง (0 ไบต์) และยืนยันว่าควรรันจากบรรทัดคำสั่งด้วย-p
แฟล็ก
puts *$<
☺
หรือ♫
หรือคุณบ้าพอ:?﷽.ord=65021
ใช้ตัวดำเนินการเครื่องหมายเพื่อรับส่วนท้ายและส่วนหัวของอาร์เรย์:
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"
abort
เพื่อยกเลิกโปรแกรมและพิมพ์สตริงเป็น STDERR - สั้นกว่าputs
ตามด้วยexit
gets
คุณสามารถใช้~/$/
เพื่อค้นหาความยาวของมัน (นี่จะไม่นับบรรทัดใหม่หากมี)[]
เพื่อตรวจสอบว่าสตริงมีอีกอันหรือไม่:'foo'['f'] #=> 'f'
tr
แทนการgsub
เปลี่ยนตัวอักขระที่ชาญฉลาด:'01011'.tr('01','AB') #=> 'ABABB'
chop
แทนchomp
abort
และ~/$/
~/$/
gets
ผลลัพธ์จะถูกเก็บไว้ใน$_
ตัวแปร /regex/ ~= string
ส่งคืนดัชนีของการแข่งขันครั้งแรก โทร~
ใน regex /regex/ ~= $_
เทียบเท่ากับ ดังนั้นมันจะเป็นอย่างไรs=gets;l= ~/$/
end
ปลายของคุณลองลบend
จากรหัสของคุณ
อย่าใช้def...end
เพื่อกำหนดฟังก์ชั่น สร้างแลมบ์ดาด้วยตัวดำเนินการใหม่ -> ใน Ruby 1.9 (ตัวดำเนินการ -> คือ"stabby lambda" หรือ "dash rocket" ) สิ่งนี้จะบันทึก 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 n
มากกว่า 5 ครั้งให้ใช้วิธีนี้ต่อไป
วิธีการทั้งหมดที่ใช้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
กับผู้ประกอบ ternary ?:
ถ้าสาขามีสองคำสั่งหรือมากกว่าให้ห่อมันไว้ในวงเล็บ
# 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'
จำเป็นหรือไม่?
นอกจากนี้เพื่อ w0lf
เมื่อทำงานกับอาร์เรย์คุณ
.compact
สามารถแทนที่ด้วย-[nil]
เพื่อบันทึก 2 ตัวอักษร
รวมกับด้านบน -> คุณสามารถทำให้สั้นลงได้ด้วย-[p]
เพื่อประหยัดอีก 2 ตัวอักษร
ใช้ตัวแปรที่กำหนดไว้สั้น ๆ หากทำได้เช่น$*
แทนที่จะARGV
ใช้ มีรายการที่ดีของพวกเขาที่นี่พร้อมกับข้อมูลที่เป็นประโยชน์อื่น ๆ อีกมากมาย
เมื่อคุณใช้สตริงการแก้ไข (ตามที่คุณควร pr โพสต์มาร์ตินBüttnerของ ) คุณไม่จำเป็นต้องวงเล็บปีกกาถ้าวัตถุของคุณมีเครื่องหมาย ( $
, @
) ในด้านหน้าของมัน ที่เป็นประโยชน์สำหรับตัวแปรที่มีมนต์ขลังเหมือน$_
, $&
, $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"
หากคุณต้องการค้นหาว่าองค์ประกอบเฉพาะe
อยู่ในช่วงr
หรือไม่คุณสามารถใช้
r===e
แทนอีกต่อไป:
r.cover?(e) # only works if `r.exclude_end?` is false
หรือ
r.member?(e)
หรือ
r.include?(e)
r===e
สั้นกว่านี้ใช่ไหม
===
นำไปใช้งาน
$_
เป็นบรรทัดสุดท้ายที่อ่าน
print
- หากไม่มีการโต้แย้งให้เนื้อหาการพิมพ์ของ $_
~/regexp/
- ย่อจาก $_=~/regexp/
ใน Ruby 1.8 คุณมีสี่วิธีในการKernel
ทำงาน$_
:
chop
chomp
sub
gsub
ในทับทิม 1.9 เหล่านี้สี่วิธีการที่มีอยู่เฉพาะในกรณีที่คุณใช้สคริปต์หรือ-n
-p
หากคุณต้องการพิมพ์ตัวแปรบางตัวก็ให้ใช้ trace_var(:var_name){|a|p a}
trace_var
จะใช้ได้กับตัวแปร $ ทั่วโลกเท่านั้น
ใช้การแก้ไขสตริง!
to_s
จะเข้ามาแทนที่ หากคุณต้องการวงเล็บในสิ่งที่คุณต้องการเปลี่ยนเป็นสตริงto_s
มีความยาวมากกว่าการแก้ไขสตริงสองไบต์
(n+10**i).to_s
"#{n+10**i}"
เพื่อแทนที่การต่อข้อมูล หากคุณต่อสิ่งที่ล้อมรอบด้วยสตริงอื่นสองตัวการแก้ไขสามารถช่วยคุณหนึ่งไบต์:
"foo"+c+"bar"
"foo#{c}bar"
นอกจากนี้ยังทำงานได้ถ้าสิ่งที่อยู่ตรงกลางของตัวเอง concatenated ถ้าคุณเพียงแค่ย้ายการเรียงต่อกันในการแก้ไข (แทนการใช้การแก้ไขหลาย ๆ ):
"foo"+c+d+e+"bar"
"foo#{c+d+e}bar"
length
อยู่ในif a.length<n
length
คือ 6 ไบต์ค่าใช้จ่ายเล็กน้อยในการตีกอล์ฟ ในหลาย ๆ สถานการณ์คุณสามารถตรวจสอบว่าอาร์เรย์มีอะไรที่จุดใดจุดหนึ่งแทนหรือไม่ หากคุณคว้าดัชนีที่ผ่านมาคุณจะได้รับnil
ค่าที่ผิดพลาด
ดังนั้นคุณสามารถเปลี่ยน:
if a.length<5
ถึงif !a[4]
-5 ไบต์
หรือ
if a.length>5
ถึงif a[5]
-6 ไบต์
หรือ
if a.length<n
ถึงif !a[n-1]
-3 ไบต์
หรือ
if a.length>n
ถึงif a[n]
-6 ไบต์
หมายเหตุ : จะทำงานกับอาร์เรย์ของค่าความจริงทั้งหมดเท่านั้น มีnil
หรือfalse
ภายในอาร์เรย์อาจทำให้เกิดปัญหา
size
... แต่นี่ดีกว่าแน่นอน BTW ก็ใช้ได้String
เช่นกัน
อย่าใช้true
และfalse
คำหลัก
ใช้:
!p
สำหรับtrue
(ขอบคุณ histocrat!)!0
false
สำหรับ หากสิ่งที่คุณต้องการคือค่าที่ผิดพลาดคุณสามารถใช้p
(ซึ่งคืนค่าnil
)เพื่อบันทึกตัวอักษร
true
(เช่นถ้าค่า truthy เป็นพอเช่นในถ้าเงื่อนไข), !!
คุณไม่จำเป็นต้อง
p
(ซึ่งประเมินผลnil
) เป็นค่าที่สั้นลง ซึ่งหมายความว่าทางที่สั้นที่สุดที่จะได้รับคือtrue
!p
หากคุณต้องการที่จะได้รับหมายเลขจากARGV
, get
หรือสิ่งที่คล้ายกันที่จะทำอะไรบางอย่างที่หลายต่อหลายครั้งแทนการโทรto_i
ในนั้นคุณก็สามารถใช้?1.upto x{do something x times}
ที่ x เป็นสตริง
ดังนั้นการใช้?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]
มันเป็นการดีที่จะอยู่เคียงข้างคุณสมบัติภาษาใหม่ที่จะช่วยให้เกมกอล์ฟของคุณ มีบางอย่างที่ยอดเยี่ยมในทับทิมล่าสุด
&.
เมื่อคุณเรียกใช้เมธอดที่อาจส่งคืน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
ส่งคืน 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]
Ruby 2.4 ยังไม่ออก แต่จะเปิดตัวเร็ว ๆ นี้พร้อมคุณสมบัติเล็ก ๆ น้อย ๆ (เมื่อวางจำหน่ายฉันจะอัปเดตโพสต์นี้พร้อมลิงก์ไปยังเอกสาร) ฉันเรียนรู้เกี่ยวกับส่วนใหญ่ในโพสต์บล็อกที่ยอดเยี่ยมนี้
Enumerable#sum
ไม่มีอีกarr.reduce(:+)
แล้ว arr.sum
ขณะนี้คุณสามารถเพียงแค่ทำ ใช้อาร์กิวเมนต์ตัวเลือกค่าเริ่มต้นซึ่งมีค่าเริ่มต้นเป็น 0 สำหรับองค์ประกอบที่เป็นตัวเลข ( [].sum == 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
มันดีทีเดียว
เป็นโบนัสจะใช้อาร์กิวเมนต์ตัวเลือก Radix:
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
เนื่องจากอยู่ใน Comparable คุณสามารถใช้กับคลาสใดก็ได้ที่มี Comparable เช่น:
?~.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
สิ่งนี้ทำให้เกิดข้อผิดพลาดใน Ruby รุ่นก่อนหน้า แต่ได้รับอนุญาตใน 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
Enumerable#sum
, .flatten.sum
2 ไบต์สั้นกว่า.sum{|a,b|a+b}
(-Math::E).truncate(1)
เทียบเท่ากับ-Math::E.truncate(1)
ที่สั้นกว่า 1 ไบต์
&.
สามารถใช้กับตัวห้อยแบบนี้a&.[]i
(สั้นกว่า 1 ไบต์a&.at i
) แม้ว่าหากจำเป็นต้องใช้ตัวยึดจะa||a[i]
มีขนาด 1 ไบต์สั้นกว่าa&.[](i)
หรือa&.at(i)
a*(b+c)
สมมติว่าคุณต้องการที่จะแสดง เนื่องจากความสำคัญกว่าa*b+c
จะไม่ทำงาน (ชัด) วิธีที่ยอดเยี่ยมของ Ruby ในการมีผู้ปฏิบัติงานเป็นวิธีการเพื่อช่วยชีวิต! คุณสามารถใช้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!
ใช้||
แทน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
วนซ้ำไปเรื่อย ๆ ในอาเรย์และมันก็สั้นกว่าตัวละครตัวหนึ่ง
ฉันเพิ่งลองรหัสกอล์ฟ - ท้าทาย 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
เพื่อประโยชน์ของ code-golf เราไม่จำเป็นต้องสร้างโมดูลหรือคลาส
แทน
module PigLatin def self.translate s;'some code'end;end
หนึ่งสามารถทำได้
def(PigLatin=p).translate s;'some code'end
บันทึกได้ 13 ตัวอักษร!
PigLatin
แต่ยัง@pig_latin
, และ$pig_latin
'pig'['latin']
translate
nil
เคอร์เนล # pเป็นวิธีการที่สนุก
ใช้แทนp var
puts var
ทำงานได้อย่างสมบูรณ์แบบด้วยจำนวนเต็มและลอย แต่ไม่สามารถใช้ได้กับทุกประเภท มันพิมพ์เครื่องหมายคำพูดรอบ ๆ สตริงซึ่งอาจไม่ใช่สิ่งที่คุณต้องการ
ใช้กับอาร์กิวเมนต์เดี่ยวp
ส่งคืนอาร์กิวเมนต์หลังจากพิมพ์
ใช้กับอาร์กิวเมนต์หลายตัวp
ส่งคืนอาร์กิวเมนต์ในอาร์เรย์
ใช้p
(ที่มีการขัดแย้งใด) nil
แทน
p 'some string'
พิมพ์"some string"
และไม่เพียง แต่some string
ถูกวิจารณ์โดยคนอื่นบ่อยๆ
p s
จะเหมือนกันputs s.inspect
แต่จะกลับมาs
อย่าใช้ #each คุณสามารถวนซ้ำองค์ประกอบทั้งหมดได้ดีด้วย #map ดังนั้นแทนที่จะ
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"
สำหรับความงงงวยยังมีช่องว่าง?
ใช้ค่าคงที่แทนที่จะส่งค่าอาร์กิวเมนต์ไปรอบ ๆ แม้ว่าคุณต้องการเปลี่ยนค่า ล่ามจะให้คำเตือนแก่stderrแต่ใครจะเป็นห่วง หากคุณต้องการกำหนดตัวแปรเพิ่มเติมที่เกี่ยวข้องกับแต่ละอื่น ๆ คุณสามารถโยงพวกเขาเช่นนี้:
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'
อักขระ escape พิเศษแทนบล็อก:
"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."]
กำจัดช่องว่างการขึ้นบรรทัดใหม่และวงเล็บ คุณสามารถละทิ้งทับทิมไปสักหน่อยได้ หากมีข้อสงสัยให้ลองใช้หากไม่ได้ผลและโปรดจำไว้ว่านี่อาจทำให้การเน้นไวยากรณ์ของเครื่องมือแก้ไข ...
x+=1if$*<<A==????::??==??
?\n
เป็นสิ่งที่ดี แต่ไม่ได้จริงๆสั้นกว่าจริงใส่ตัวอักษรขึ้นบรรทัดใหม่ให้อยู่ในเครื่องหมาย (เหมือนกันสำหรับแท็บ)
puts$*
ยิ่งสั้น
x+=1;$*<<A
อีกวิธีหนึ่งในการใช้ตัวดำเนินการสีแดง: หากคุณต้องการกำหนดค่าตัวอักษรแบบอาร์เรย์เดียว*
ด้านซ้ายมือจะสั้นกว่าเครื่องหมายวงเล็บทางด้านขวา:
a=[0]
*a=0
ด้วยค่าหลายค่าคุณไม่จำเป็นต้องใช้ตัวดำเนินการ splat (ด้วย histocrat สำหรับการแก้ไขในส่วนนั้น):
a=[1,2]
a=1,2
เมื่อความท้าทายต้องการให้คุณส่งออกหลายบรรทัดคุณไม่จำเป็นต้องวนซ้ำผลลัพธ์ของคุณเพื่อพิมพ์แต่ละบรรทัดเช่นอาร์เรย์ puts
วิธีจะแผ่อาร์เรย์และพิมพ์แต่ละองค์ประกอบในบรรทัดที่แยกต่างหาก
> a = %w(testing one two three)
> puts a
testing
one
two
three
การรวมตัวดำเนินการสีแดงกับ#p
คุณสามารถทำให้มันสั้นลงได้:
p *a
ผู้ประกอบการ splat (ในทางเทคนิค*@
แล้วฉันคิดว่า) มันจะแปลงค่าตัวเลขที่ไม่ใช่อาร์เรย์ของคุณไปเป็นอาร์เรย์:
> p a.lazy.map{|x|x*2}
#<Enumerator::Lazy: #<Enumerator::Lazy: [1, 2, 3]>:map>
VS
> p *a.lazy.map{|x|x*2}
2
4
6
*@
ไม่ใช่วิธี splat คือน้ำตาล syntactic
a.uniq # before
a|[] # after
^^
หากคุณจะใช้อาเรย์ที่ว่างเปล่า[]
ในตัวแปรคุณสามารถบันทึกไบต์ได้มากขึ้น:
a.uniq;b=[] # before
a|b=[] # after
^^^^^
a&a
จะสั้นกว่า 1 ไบต์
ใช้ Goruby แทน Ruby ซึ่งเป็นสิ่งที่คล้ายกับ Ruby รุ่นย่อ คุณสามารถติดตั้งได้ด้วย rvm ผ่านทาง
rvm install goruby
Goruby อนุญาตให้คุณเขียนรหัสส่วนใหญ่ของคุณตามที่คุณต้องการจะเขียน Ruby แต่มีตัวย่อเพิ่มเติมอยู่ภายในเพื่อค้นหาคำย่อที่มีให้สั้นที่สุดสำหรับบางสิ่งคุณสามารถใช้วิธีผู้ช่วย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
เพื่อพิมพ์ตัวอักษรในเมืองหลวง (ซึ่งไม่ใช่ตัวอย่างที่ดีมาก) โพสต์บล็อกนี้อธิบายเนื้อหาเพิ่มเติมและผลงานภายในบางส่วนหากคุณสนใจที่จะอ่านเพิ่มเติม
PS: อย่าพลาดh
วิธี ;-)
หากต้องการเข้าร่วมอาร์เรย์แทนที่จะเป็นเช่นนี้
[...].join
ทำเช่นนี้
[...]*''
ซึ่งช่วยประหยัด 2 ไบต์ เพื่อเข้าร่วมกับการใช้ตัวคั่น
[...]*?,
ฉันเพิ่งค้นพบเมื่อวานนี้ n[i]
ส่งกลับn
บิตของi
ตำแหน่งที่ -th ตัวอย่าง:
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]
คุณสามารถบันทึก 2 ตัวอักษรและใช้งานได้
[*(...)]
แทน
(...).to_a
ตัวอย่างเช่นสมมติว่าเรามีช่วงที่เราต้องการเป็นอาร์เรย์:
(1..2000).to_a
เพียงทำแบบนี้:
[*1..2000] # Parentheses around the (ran..ge) is not needed!
และตอนนี้คุณมีช่วงของคุณเป็นอาร์เรย์
[*1..2000]
ผลเช่นกัน?
a.push x
สามารถย่อให้เหลือ:
a<<x
สำหรับ -4 ไบต์
String
s
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|
อย่างไร
x=[1,2]
x,=[1,2]
โดยใช้ตัวอย่างของฉันข้างต้นด้วย|x|
ในซ้ำแรกจะเป็นx
[0,"foo"]
ด้วย|x,y|
, x
จะเป็น0
และจะเป็นy
"foo"
ในทำนองเดียวกันกับ|x,|
, จะx
0
กล่าวอีกนัยหนึ่งก็คือ "ใส่องค์ประกอบแรกเข้าx
และโยนส่วนที่เหลือออกไป
|,y|
เป็น SyntaxError, เออร์|_,y|
โก แต่ตอนนี้ฉันเพิ่งรู้ว่าใช้|*,y|
งานได้ดีกว่าการใช้ตัวแปรชื่อ_
(แต่ไม่สั้นกว่า)