Kiat untuk bermain golf di Ruby


62

Apa tips umum yang bisa Anda berikan untuk bermain golf di Ruby?

Saya mencari ide yang dapat diterapkan pada masalah kode golf secara umum yang khusus untuk Ruby. (Misalnya, "Hapus komentar" tidak akan menjadi jawaban.)

Silakan kirim satu tip per jawaban.


Seseorang perlu menulis bahasa yang disebut Rub, yang menggunakan karakter Unicode tunggal untuk setiap token Ruby, agak seperti Jelly dan Pyth :)
Mark Thomas

Jawaban:


46
  • Nomor 100-126 dapat ditulis sebagai ?duntuk ?~di 1,8.
  • Pada catatan yang sama jika Anda membutuhkan string karakter tunggal dalam 1,9? X lebih pendek dari "x".
  • Jika Anda perlu mencetak string tanpa menambahkan baris baru, $><<"string"lebih pendek dari print"string".
  • Jika Anda perlu membaca beberapa baris input $<.map{|l|...}lebih pendek dari while l=gets;...;end. Anda juga dapat menggunakannya $<.readuntuk membacanya sekaligus.
  • Jika Anda seharusnya membaca dari sebuah file, $<dan getsakan membaca dari sebuah file alih-alih stdin jika nama filenya ada ARGV. Jadi cara golfiest reimplement catakan: $><<$<.read.

1
? x menghasilkan kode ascii secara umum, sehingga Anda dapat secara realistis mendapatkan semua printables menjadi digit dalam dua karakter. 1.9 berbeda, 'a'.ord menghasilkan angka ascii, tetapi empat byte lebih panjang dari versi desimal.
Hiato

8
Cara yang lebih pegolf untuk diimplementasikan catadalah membiarkan file ruby ​​benar-benar kosong (0 byte) dan bersikeras bahwa itu harus dijalankan dari baris perintah dengan -pbendera.
daniero

1
atau, dari @ daniero sendiri jawabannya ,puts *$<
Bukannya Charles

1
Jadi di 1.8, yang harus saya lakukan adalah pergi? ~ Dan itu akan mengembalikan 126?
Simply Beautiful Art

5
Anda dapat melampaui 126 menggunakan pemikiran seperti atau , atau jika Anda cukup gila:?﷽.ord=65021
Simply Beautiful Art

32

Gunakan operator percikan untuk mendapatkan ekor dan kepala array:

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

Ini juga berfungsi sebaliknya:

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

Gunakan *metode dengan string pada array untuk bergabung dengan elemen:

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

27
  • Gunakan abortuntuk menghentikan program dan mencetak string ke STDERR - lebih pendek dari yang putsdiikuti olehexit
  • Jika Anda membaca baris dengan gets, Anda dapat menggunakan ~/$/untuk menemukan panjangnya (ini tidak termasuk baris baru jika itu ada)
  • Gunakan []untuk memeriksa apakah string berisi yang lain:'foo'['f'] #=> 'f'
  • Gunakan trsebagai gsubpengganti pengganti karakter-bijaksana:'01011'.tr('01','AB') #=> 'ABABB'
  • Jika Anda perlu menghapus trailing newlines, gunakan chopsebagai gantichomp

2
+1 untuk abortdan~/$/
J -_- L

Tolong jelaskan bagaimana cara menggunakan~/$/
Mathieu CAROFF

@MathieuCAROFF setiap kali Anda menelepon gets, hasilnya disimpan dalam $_variabel. /regex/ ~= stringmengembalikan indeks pertandingan pertama. Memanggil ~regex setara dengan /regex/ ~= $_. Jadi itu akan menjadi sepertis=gets;l= ~/$/
Cyoce

20

Akhiri end.

Coba hapus enddari kode Anda.

Jangan gunakan def...enduntuk mendefinisikan fungsi. Buat lambda dengan operator baru -> di Ruby 1.9. (Operator -> adalah "lambda stabby", atau "dash rocket" .) Ini menghemat 5 karakter per fungsi.

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

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

Metode panggilan adalah c natau c(n). Panggilan Lambda adalah c[n]. Mengubah masing c n- masing ke c[n]biaya 1 karakter, jadi jika Anda dapat menggunakan c nlebih dari 5 kali, maka simpan metode ini.

Semua metode yang mengambil do...endblok dapat mengambil {...}blok sebagai gantinya. Ini menghemat 3 hingga 5 karakter. Jika prioritas {...}terlalu tinggi, maka gunakan tanda kurung untuk memperbaikinya.

# 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','}

Ganti if...else...enddengan operator ternary ?: . Jika cabang memiliki dua pernyataan atau lebih, bungkus dalam tanda kurung.

# 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')

Anda mungkin tidak memiliki whileatau untilmengulang, tetapi jika ya, tuliskan dalam bentuk pengubah.

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

Apakah tanda kurung puts'statement 3'diperlukan?
Cyoce

15

Selain w0lf

Saat bekerja dengan array, .compactdapat diganti dengan -[nil]untuk menyimpan 2 karakter.

Dikombinasikan dengan di atas -> Anda dapat membuatnya lebih pendek dengan -[p]menyimpan 2 karakter lainnya.


14

Gunakan variabel yang telah ditetapkan pendek sedapat mungkin, misalnya $*bukan ARGV. Ada daftar yang bagus di sini , bersama dengan banyak informasi berguna lainnya.


12

Ketika Anda menggunakan interpolasi string, (seperti yang seharusnya Anda lakukan pada posting Martin Büttner ), Anda tidak perlu tanda kurung keriting jika objek Anda memiliki sigil ( $, @) di depannya. Berguna untuk variabel magis seperti $_, $&, $1dll:

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

Begitu juga jika Anda perlu mencetak variabel lebih dari yang Anda gunakan, Anda dapat menghemat beberapa byte.

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

Jika Anda perlu menemukan jika elemen tertentu eberada di dalam rentang r, Anda bisa menggunakannya

r===e

bukannya lebih lama:

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

atau

r.member?(e)

atau

r.include?(e)

3
r===eBahkan tidak lebih pendek?
akuhn

@akuhn Ya, benar. Jauh lebih pendek. Terima kasih telah menunjukkannya, itu membantu saya mempersingkat kode saya sebanyak 10 karakter, yang sangat besar: codegolf.stackexchange.com/a/6125/3527
Cristian

1
Sama-sama. Segala sesuatu yang dapat digunakan dalam pernyataan switch telah ===diimplementasikan.
akuhn

10

$_ adalah baris terakhir dibaca.

  • print - jika tidak ada argumen yang diberikan konten cetak $_
  • ~/regexp/ - kependekan dari $_=~/regexp/

Di Ruby 1.8, Anda memiliki empat metode Kernelyang beroperasi pada $_:

  • chop
  • chomp
  • sub
  • gsub

Di Ruby 1.9, keempat metode ini hanya ada jika skrip Anda menggunakan -natau -p.

Jika Anda ingin mencetak beberapa variabel sering maka gunakan trace_var(:var_name){|a|p a}


2
Ini hanya tersedia ketika Anda menjalankan Ruby dengan opsi -patau -n. Referensi.
Darren Stone

1
Tampaknya trace_varhanya bekerja dengan variabel $ global
daniero

10

Gunakan interpolasi string!

  1. Untuk mengganti to_s. Jika Anda membutuhkan tanda kurung di sekitar apa pun yang ingin Anda ubah menjadi string, to_sdua byte lebih panjang dari interpolasi string:

    (n+10**i).to_s
    "#{n+10**i}"
    
  2. Untuk mengganti rangkaian. Jika Anda menggabungkan sesuatu yang dikelilingi oleh dua string lainnya, interpolasi dapat menghemat satu byte:

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

    Juga berfungsi jika hal tengah itu sendiri disatukan, jika Anda hanya memindahkan rangkaian di dalam interpolasi (alih-alih menggunakan beberapa interpolasi):

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

10

Hindari lengthmasukif a.length<n

lengthadalah 6 byte, sedikit mahal dalam kode golf. dalam banyak situasi, Anda dapat memeriksa apakah array memiliki sesuatu pada titik tertentu. jika Anda melewati indeks terakhir yang akan Anda dapatkan nil, nilai falsey.

Jadi, Anda dapat Mengubah:

if a.length<5ke if !a[4]untuk -5 byte

atau

if a.length>5ke if a[5]-6 byte

atau

if a.length<nke if !a[n-1]-3 byte

atau

if a.length>nke if a[n]-6 byte

Catatan : hanya akan bekerja dengan larik semua nilai kebenaran. memiliki nilatau falsedi dalam array dapat menyebabkan masalah.


4
Saya selalu menggunakan size... Tapi ini jelas lebih baik. BTW, bekerja Stringjuga.
manatwork

10

Jangan gunakan kata kunci truedan false.

Menggunakan:

  • !puntuk true(terima kasih, histokrat!)
  • !0untuk false. Jika semua yang Anda butuhkan adalah nilai palsu, maka Anda cukup menggunakan p(yang mengembalikan nil).

untuk menyimpan beberapa karakter.


1
Kecuali jika Anda benar-benar membutuhkan true(yaitu jika nilai kebenaran sudah cukup, seperti dalam kondisi if), Anda bahkan tidak perlu !!.
Martin Ender

4
Dan juga, p(yang mengevaluasi nil) adalah nilai falsey yang lebih pendek. Yang berarti cara terpendek untuk mendapatkannya trueadalah !p.
histokrat

@ poin bagus histokrat! Saya sudah mengedit jawaban saya.
Cristian Lupascu


9

Jika Anda perlu mendapatkan nomor dari ARGV,, getatau sesuatu yang serupa untuk melakukan sesuatu yang berkali-kali, alih-alih memanggilnya to_i, Anda bisa menggunakan ?1.upto x{do something x times}mana x adalah string.

Jadi menggunakan ?1.upto(a){}bukannya x.to_i.times{}akan menghemat 2 karakter.

Anda juga dapat menulis ulang hal-hal seperti p 1 while 1atau p 1 if 1sebagai p 1while 1ataup 1if 1

Contoh itu tidak terlalu berguna, tetapi bisa digunakan untuk hal lain.

Selain itu, jika Anda perlu menetapkan elemen pertama array ke variabel, a,=cakan menyimpan dua karakter sebagai lawana=c[0]


9

Fitur baru di Ruby 2.3 dan 2.4

Ada baiknya untuk tetap mengikuti fitur bahasa baru yang akan membantu permainan golf Anda. Ada beberapa yang hebat di Rubi terbaru.

Ruby 2.3

Operator navigasi yang aman: &.

Saat Anda memanggil metode yang mungkin kembali niltetapi Anda ingin membuat panggilan metode tambahan jika tidak, Anda membuang byte yang menangani nilkasus ini:

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

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

"Operator navigasi aman" menghentikan rantai panggilan metode jika seseorang kembali nildan kembali niluntuk seluruh ekspresi:

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

Array#dig & Hash#dig

Akses mendalam ke elemen bersarang, dengan nama pendek yang bagus:

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

Kembali niljika menyentuh jalan buntu:

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

Enumerable#grep_v

Kebalikan dari - Enumerable#grepmengembalikan semua elemen yang tidak cocok dengan argumen yang diberikan (dibandingkan dengan ===). Seperti grep, jika sebuah blok diberikan hasilnya dikembalikan sebagai gantinya.

(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

Mengembalikan Proc yang menghasilkan nilai untuk kunci yang diberikan, yang bisa sangat berguna:

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

Ruby 2.4 belum keluar, tetapi akan segera dan memiliki beberapa fitur kecil yang hebat. (Ketika dirilis saya akan memperbarui posting ini dengan beberapa tautan ke dokumen.) Saya belajar tentang sebagian besar dari ini di posting blog besar ini .

Enumerable#sum

Tidak ada lagi arr.reduce(:+). Sekarang Anda bisa melakukannya arr.sum. Dibutuhkan argumen nilai awal opsional, yang default ke 0 untuk elemen Numeric ( [].sum == 0). Untuk jenis lain Anda harus memberikan nilai awal. Itu juga menerima blok yang akan diterapkan ke setiap elemen sebelum penambahan:

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

Integer#digits

Ini mengembalikan array angka angka dalam urutan signifikansi terkecil ke terbesar:

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

Dibandingkan dengan, katakanlah 123.to_s.chars.map(&:to_i).reverse, ini cukup bagus.

Sebagai bonus, dibutuhkan argumen radix opsional:

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

Comparable#clamp

Lakukan apa yang tertulis di kaleng:

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

Karena itu dalam Sebanding Anda dapat menggunakannya dengan kelas apa pun yang termasuk Sebanding, misalnya:

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

String#unpack1

Penghematan 2 byte .unpack(...)[0]:

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

Presisi argumen untuk Numeric#ceil, floor, dantruncate

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

Penugasan berganda dalam kondisi

Ini menimbulkan kesalahan dalam versi Ruby yang lebih lama, tetapi diizinkan di 2.4.

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

Golf Math::E.ceil(1)untuk Math::E.ceil 1, dan juga untuk floordan truncate.
Simply Beautiful Art

1
@SimplyBeautifulArt Saya berharap seseorang yang bermain golf di Ruby dapat membuat lompatan itu sendiri.
Jordan

Sebab Enumerable#sum, .flatten.sum2 byte lebih pendek dari.sum{|a,b|a+b}
Asone Tuhid

(-Math::E).truncate(1)setara dengan -Math::E.truncate(1)yang 1 byte lebih pendek
Asone Tuhid

1
&.dapat digunakan dengan berlangganan seperti ini a&.[]i(1 byte lebih pendek dari a&.at i). Meskipun, jika tanda kurung diperlukan, a||a[i]apakah 1 byte lebih pendek dari a&.[](i)ataua&.at(i)
Asone Tuhid

7

Notasi ilmiah sering dapat digunakan untuk memotong satu atau dua arang:

x=1000
#versus
x=1e3

9
Catatan: Ini akan mengembalikan nilai Float (1000.0) alih-alih bilangan bulat, yang dapat menyebabkan hasil yang tidak akurat dengan jumlah besar.
Dogbert

4
Ah, lebih baik 1e2lebih baik daripada 100.0saat dibutuhkan persentase.
Phrogz

Mirip dengan prinsip ini, 1.0*adalah 1 char lebih pendek dari.to_f
Unihedron

7

Gunakan metode operator alih-alih tanda kurung

Katakanlah Anda ingin mengekspresikan a*(b+c). Karena diutamakan, a*b+ctidak akan bekerja (jelas). Cara keren Ruby untuk memiliki operator sebagai metode untuk menyelamatkan! Anda dapat menggunakan a.*b+cuntuk membuat prioritas *lebih rendah dari itu +.

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

Ini juga dapat bekerja dengan !dan ~operator (hal-hal seperti unary +atau unary -tidak bekerja karena metode mereka -@dan +@, tabungan ()tetapi menambahkan .@)

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

6

Gunakan ||sebagai gantinya ordan &&sebaliknya and.

Di samping satu karakter dari andAnda dapat menghemat ruang (dan mungkin braket) di sekitar operator.

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

Jika Anda mengulang pada array yang biasanya Anda gunakan each. Tetapi maploop juga melalui array dan itu adalah satu karakter lebih pendek.


6

Saya baru saja mencoba tantangan kode-golf TDD yaitu Menulis kode terpendek untuk membuat spesifikasi lulus. Spesifikasinya kira-kira seperti itu

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

Demi kode-golf, seseorang tidak perlu membuat modul atau kelas.

Dari pada

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

seseorang bisa melakukannya

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

Menghemat 13 karakter!


7
Ha, sangat teliti. Tidak hanya Anda menambahkan perilaku yang diperlukan untuk PigLatin, tetapi juga untuk @pig_latin, $pig_latin, dan 'pig'['latin'].
histokrat

@ histokrat: Sekarang saya mengerti. Itu karena translatetelah ditetapkan nil.
Eric Duminil

6

Kernel # p adalah metode yang menyenangkan.

Gunakan p varsebagai ganti puts var. Ini berfungsi sempurna dengan bilangan bulat dan mengapung, tetapi tidak dengan semua jenis. Ini mencetak tanda kutip di sekitar string, yang mungkin bukan yang Anda inginkan.

Digunakan dengan argumen tunggal, pmengembalikan argumen setelah mencetaknya.

Digunakan dengan banyak argumen, pmengembalikan argumen dalam array.

Gunakan p(tanpa argumen) sebagai ganti nil.


10
Sayangnya p 'some string'hasil cetak "some string"dan bukan hanya some stringyang sering dikritik oleh orang lain.
Patrick Oscity

1
Pada dasarnya p ssama dengan puts s.inspect, tetapi kembalis
Cyoce

6

Jangan gunakan #each. Anda dapat mengulang semua elemen dengan #map. Jadi, bukannya

ARGV.each{|x|puts x}

Anda dapat melakukan hal yang sama dalam lebih sedikit byte.

ARGV.map{|x|puts x}

Tentu saja, dalam hal ini puts $*akan lebih pendek.


Ada literal untuk bilangan rasional dan kompleks:

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

=> true
true
true

Anda dapat menggunakan sebagian besar byte dalam string. "\x01"(6 byte) dapat disingkat menjadi ""(3 byte). Jika Anda hanya membutuhkan satu byte ini, ini dapat dipersingkat lebih jauh menjadi ?(2 byte).

Dengan cara yang sama, Anda bisa mendapatkan baris baru lebih pendek seperti ini:

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

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

Anda dapat menggunakan ?\ndan ?\tjuga, yang satu byte lebih pendek dari "\n"dan "\t". Untuk kebingungan, ada juga spasi?


Gunakan konstanta alih-alih memberikan argumen, bahkan jika Anda perlu mengubahnya. Penerjemah akan memberikan peringatan kepada stderr , tetapi siapa yang peduli. Jika Anda perlu mendefinisikan lebih banyak variabel yang terkait satu sama lain, Anda dapat membuat mereka seperti ini:

A=C+B=7+C=9

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

Ini lebih pendek dari C=9;B=16;A=17atau C=0;B=C+7;A=C+B.


Jika Anda membutuhkan loop tak terbatas, gunakan loop{...}. Loop dengan panjang yang tidak diketahui mungkin lebih pendek dengan loop lainnya:

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

while'
'!=f(gets);end

Beberapa lagi trik gsub / regexp. Gunakan '\1'karakter pelarian khusus alih-alih blok:

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

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

Dan variabel khusus $1dll. Jika Anda perlu melakukan operasi. Perlu diingat bahwa mereka didefinisikan tidak hanya di dalam blok:

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

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

Singkirkan spasi, baris baru, dan tanda kurung. Anda dapat menghilangkan sedikit ruby. Jika ragu, selalu coba jika berhasil tanpa, dan perlu diingat ini mungkin merusak beberapa sintaks editor yang disorot ...

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

"Silakan kirim satu tip per jawaban." Juga ?\nbagus, tetapi tidak terlalu pendek daripada benar-benar menempatkan karakter baris baru di dalam tanda kutip. (sama untuk tab)
Martin Ender

Dan puts$*bahkan lebih pendek.
Cyoce

Saya tahu Anda mencoba membuktikan suatu hal, tetapi saya cukup yakin bahwa contoh terakhir sama denganx+=1;$*<<A
Asone Tuhid

6

Namun cara lain untuk menggunakan operator percikan: jika Anda ingin menetapkan literal array tunggal, a *di sisi kiri lebih pendek dari tanda kurung di sisi kanan:

a=[0]
*a=0

Dengan beberapa nilai, Anda bahkan tidak memerlukan operator percikan (terima kasih kepada histocrat karena telah mengoreksi saya tentang hal itu):

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

Kasing terakhir sebenarnya tidak membutuhkan percikan.
histokrat

@ histokrat Oh wow, saya pikir nilai kedua hanya akan dibuang dalam kasus itu.
Martin Ender

1
Saya tidak percaya saya belum tahu ini sepanjang waktu saya habiskan bermain golf di Ruby.
Gagang Pintu

6

Ketika sebuah tantangan mengharuskan Anda menghasilkan beberapa baris, Anda tidak perlu mengulang -ulang hasil Anda untuk mencetak setiap baris misalnya array. The putsMetode akan meratakan sebuah array dan mencetak setiap elemen pada baris terpisah.

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

Menggabungkan operator percikan dengan #pAnda dapat membuatnya lebih pendek:

p *a

Operator percikan (secara teknis *@metode, saya pikir) juga melemparkan enumerables non-array Anda ke array:

> 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

1
*@bukan metode, percikan adalah gula sintaksis
Asone Tuhid

6

Simpan beberapa byte saat menghapus elemen array yang berulang

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

Jika Anda akan menggunakan array kosong []dalam sebuah variabel, Anda dapat menyimpan lebih banyak byte:

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

2
Untuk kasus pertama, a&alebih pendek 1 byte
Asone Tuhid

5

Gunakan Goruby alih-alih Ruby, yang mirip dengan Ruby versi singkat. Anda dapat menginstalnya dengan rvm via

rvm install goruby

Goruby memungkinkan Anda menulis sebagian besar kode Anda seperti menulis Ruby, tetapi memiliki singkatan tambahan. Untuk mengetahui singkatan tersingkat yang tersedia untuk sesuatu, Anda dapat menggunakan metode helper shortest_abbreviation, misalnya:

shortest_abbreviation :puts
#=> "pts"

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

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

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

Juga sangat berguna adalah alias sayuntuk putsyang itu sendiri dapat disingkat dengan s. Jadi, bukannya

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

Anda sekarang dapat menulis

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

untuk mencetak alfabet dalam huruf besar (yang bukan contoh yang sangat bagus). Posting blog ini menjelaskan lebih banyak hal dan beberapa pekerjaan dalam jika Anda tertarik membaca lebih lanjut.

PS: jangan ketinggalan hmetode ;-)


Lebih dari 2 tahun kemudian dan saya akhirnya menemukan jawaban yang mengingatkan saya pada ...
undergroundmonorail

5

Untuk bergabung dengan array, alih-alih ini

[...].join

melakukan hal ini

[...]*''

yang menghemat 2 byte. Untuk bergabung dengan penggunaan pemisah

[...]*?,

5

Nomor Berlangganan!

Saya baru saja menemukan ini kemarin. n[i]mengembalikan nbit pada iposisi ke -. Contoh:

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

Dan sekarang Anda dapat menggunakan lebih banyak argumen sepertin[0..3]
Simply Beautiful Art

4

Anda mungkin dapat menyimpan 2 karakter dan menggunakan

[*(...)]

dari pada

(...).to_a

Sebagai contoh, misalkan kita memiliki rentang yang kita inginkan sebagai array:

(1..2000).to_a

Lakukan saja seperti ini:

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

Dan sekarang Anda memiliki rentang sebagai array.


5
Saya pikir [*1..2000]berhasil juga?
Lynn

4

<< trik

a.push x

dapat disingkat menjadi:

a<<x

untuk -4 byte.


2
Catatan: ini juga berfungsi untuk Strings
Cyoce

4

Array#assoc/rassoc

Ketika Anda memiliki array array dan ingin menemukan sub-array yang dimulai dengan nilai tertentu, jangan gunakan Enumerable#find, gunakan Array#assoc:

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

Ini juga merupakan pengganti yang baik untuk Enumerable#any?beberapa situasi.

Array#rassoc melakukan hal yang sama, tetapi memeriksa elemen terakhir sub-array:

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

Untuk a.any?baris dalam rassoc contoh, apa fungsinya |x,|? Bagaimana bedanya |x|?
Cyoce

@Cyoce Blok parameter destructuring mengikuti aturan yang sama seperti destrukturisasi tugas, jadi seperti x=[1,2]vs x,=[1,2]. Menggunakan contoh saya di atas, dengan |x|, di iterasi pertama xakan [0,"foo"]. Dengan |x,y|, xakan 0dan yakan "foo". Demikian juga, dengan |x,|, xakan 0. Dengan kata lain, dikatakan "masukkan elemen pertama xdan buang sisanya.
Jordan

Perhatikan bahwa itu tidak bekerja secara terbalik, misalnya |,y|adalah SyntaxError, ergo |_,y|. Tapi saya baru saja menyadari bahwa itu |*,y|berfungsi, yang lebih bersih daripada menggunakan variabel bernama _(tapi tidak lebih pendek).
Jordan
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.