Tips umum apa yang Anda miliki untuk bermain golf di Perl 6? Saya mencari ide yang dapat diterapkan pada masalah kode golf secara umum yang setidaknya agak spesifik untuk Perl 6 (mis. "Hapus komentar" bukan jawaban). Silakan kirim satu tip per jawaban.
Harap perhatikan bahwa Perl 6 bukan Perl 5, jadi pertanyaan ini bukan duplikat. Sebagian besar tips untuk bermain golf Perl 5 tidak berlaku untuk Perl 6.
say (3² + 4², 2²⁰, 5⁻²)
==>(25 1048576 0.04)
. Daftar lengkap Unicode yang dapat Anda penyalahgunaan seperti ini ada di sini: docs.perl6.org/language/unicode_texas .Pelajari fungsi untuk membaca input. Perl 6 memiliki banyak fungsi menarik yang dapat dengan mudah membaca input dari ARGV, atau STDIN (jika tidak ada yang ditentukan pada ARGV), yang dapat mempersingkat kode Anda jika digunakan dengan benar. Jika Anda memanggil mereka sebagai metode
STDIN
penanganan file , Anda dapat memaksa mereka untuk bekerja pada penanganan file tertentu (berguna jika Anda misalnya membaca dari , tetapi Anda harus membaca argumen pada ARGV).get
Fungsi ini mendapat satu baris, dan secara otomatis chomps, jadi Anda tidak perlu. Ini berguna jika Anda hanya perlu membaca satu baris.
lines
Fungsi ini mendapatkan semua baris dari file atau STDIN. Ini daftar yang malas, jadi jika Anda menggunakannya
for
, itu hanya akan membaca apa yang Anda butuhkan. Sebagai contoh.slurp
Ini akan membaca seluruh file atau STDIN, dan akan mengembalikan hasilnya sebagai string tunggal.
sumber
say "<$_>" for lines
berfungsi sekarangPeringatan : Dinding teks mendekat. Banyak trik kecil yang saya kumpulkan dari waktu ke waktu.
Tulis solusi Anda sebagai blok anonim
Ini sudah disebutkan tetapi saya ingin mengulanginya. Di TIO, Anda bisa menulis
my $f =
ke header, blok ke kode yang tepat, dan memulai footer dengan a;
. Ini tampaknya merupakan cara terpendek untuk menyelesaikan pekerjaan (karena Anda tidak perlu peduli membaca input apa pun, itu diberikan kepada Anda dalam argumen).Cara lain yang bagus adalah menggunakan tombol
-n
atau-p
, tetapi saya tidak menemukan cara untuk membuatnya bekerja di TIO.Gunakan sintaks titik dua untuk meneruskan argumen
Artinya, alih-alih
thing.method(foo,bar)
, Anda dapat melakukanthing.method:foo,bar
dan menyimpan 1 karakter. Sayangnya, Anda tidak dapat memanggil metode lain pada hasil karena alasan yang jelas, jadi masuk akal untuk menggunakan hanya untuk metode terakhir dalam satu blok.Gunakan
$_
sebanyak yang Anda bisaTerkadang lebih baik mengambil argumen daftar tunggal daripada beberapa argumen terpisah karena ini. Saat mengakses
$_
, Anda dapat memanggil metode hanya dengan memulai dengan titik: misalnya.sort
sama dengan$_.sort
.Namun, ingatlah bahwa setiap blok mendapatkan miliknya sendiri
$_
, sehingga parameter blok luar tidak akan merambat ke bagian dalam. Jika Anda perlu mengakses parameter fungsi utama dari blok dalam, ...Gunakan
^
variabel jika Anda tidak dapat menggunakan$_
Masukkan
^
antara sigil dan nama variabel, seperti ini:$^a
. Ini hanya berfungsi di dalam blok. Kompiler pertama menghitung berapa banyak yang Anda miliki di blok ini, mengurutkannya secara leksikografis, dan kemudian memberikan argumen pertama ke yang pertama, yang kedua ke yang kedua dan seterusnya. The^
kebutuhan untuk digunakan hanya dalam kejadian pertama dari variabel. Jadi,{$^a - $^b}
ambil 2 skalar dan kurangi. Satu-satunya hal yang penting adalah urutan abjad, demikian{-$^b + $^a}
juga hal yang sama.Jika Anda pernah merasa ingin menggunakan sintaks blok runcing (seperti
->$a,$b {$a.map:{$_+$b}}
), Anda jauh lebih baik menulis pernyataan palsu di awal blok menggunakan^
untuk setiap argumen yang tidak akan Anda gunakan di blok utama (seperti{$^b;$^a.map:{$_+$b}}
) (Catatan cara yang lebih baik untuk bermain golf ini adalah{$^a.map(*+$^b)}
. Saya hanya ingin memamerkan konsepnya.)Baca dokumen operator dengan cermat
Operator sangat kuat dan seringkali mereka adalah cara terpendek untuk menyelesaikan sesuatu. Terutama meta-operator (operator yang menganggap operator sebagai argumen)
[]
,[\]
,X
,<<
/>>
danZ
layak perhatian Anda. Jangan lupa bahwa meta-op dapat menggunakan meta-op lain sebagai argumen (sepertiXZ%%
saya berhasil menggunakan di sini ). Anda dapat menggunakan>>
untuk pemanggilan metode juga, yang bisa menjadi jauh lebih murah daripada peta (@list>>.method
bukannya@list.map(*.method)
, tapi hati-hati, mereka tidak sama! ). Dan, akhirnya, sebelum Anda menggunakan biner<< >>
, ingatlah bahwaZ
akan sering melakukan hal yang sama dalam karakter yang jauh lebih sedikit.Jika Anda menumpuk banyak meta-op satu sama lain, Anda dapat menentukan prioritas menggunakan tanda kurung siku
[]
. Itu akan menyelamatkan Anda ketika Anda menumpuk begitu banyak operator sehingga membingungkan kompiler. (Itu tidak sering terjadi.)Akhirnya, jika Anda perlu memaksa sesuatu ke Bool, Int atau Str, jangan gunakan metode
.Bool
,.Int
dan.Str
, melainkan operator?
,+
dan~
. Atau bahkan lebih baik, cukup masukkan mereka ke dalam ekspresi aritmatika untuk memaksa mereka ke Int dan seterusnya. Cara terpendek untuk mendapatkan panjang daftar adalah+@list
. Jika Anda ingin menghitung 2 pangkat dari panjang daftar, katakan saja2**@list
dan itu akan melakukan The Right Thing.Gunakan variabel status bebas
$
,@
dan%
Di setiap blok, setiap kemunculan
$
(atau@
atau%
) merujuk ke variabel status skalar (atau array, atau hash) baru yang mengkilap (variabel yang nilainya tetap ada di seluruh panggilan ke blok). Jika Anda memerlukan variabel status yang perlu direferensikan hanya sekali dalam kode sumber, ketiganya adalah teman besar Anda. (Paling sering$
.) Misalnya, dalam tantangan Reverse Math Cycles , itu dapat digunakan untuk memilih operator secara siklikal dari sebuah array, yang diindeks oleh$++%6
.Gunakan sub bentuk
map
,grep
et al.Itu berarti: lakukan
map {my block},list
daripadalist.map({my block})
. Bahkan jika Anda berhasil menggunakanlist.map:{my block}
, kedua pendekatan ini keluar pada jumlah byte yang sama. Dan sering kali, Anda perlu mengurung daftar saat memanggil metode, tetapi tidak saat memanggil sub. Jadi sub pendekatan yang keluar selalu lebih baik atau setidaknya sama dengan metode yang satu.Satu-satunya pengecualian di sini adalah ketika objek yang akan dibuat
map
ped,grep
ped dan sebagainya, berada di$_
. Maka.map:{}
jelas berdetakmap {},$_
.Gunakan persimpangan (
&
dan|
) alih-alih&&
dan||
.Jelas, mereka 1 byte lebih pendek. Di sisi lain, mereka harus dihancurkan dengan dipaksa ke dalam konteks boolean. Ini selalu dapat dilakukan dengan a
?
. Di sini Anda harus mengetahui meta-op!
op
yang memaksa konteks bool, menggunakanop
dan meniadakan hasilnya.Jika Anda memiliki daftar dan ingin mengubahnya menjadi persimpangan, jangan gunakan
[&]
dan[|]
. Alih-alih menggunakan.any
dan.all
. Ada juga.none
yang tidak dapat dengan mudah ditiru oleh ops persimpangan.sumber
&&
dan||
masih berguna untuk hubungan arus pendek?Kurangi ruang yang digunakan untuk variabel
Ada beberapa bagian untuk ini.
Hapus spasi putih
Variabel yang dideklarasikan menggunakan
my
biasanya dapat dideklarasikan tanpa spasi di antaramy
dan nama variabel.my @a
setara denganmy@a
.Gunakan variabel sigil-less
Anda bisa mendeklarasikan variabel menggunakan backslash untuk menghapus sigil sebelum nama variabel, seperti:
(sayangnya Anda tidak dapat menghapus spasi :()
Ini berguna karena Anda dapat merujuknya hanya sebagai nama variabel kosong nanti.
Pada dasarnya ini menghemat byte jika Anda menggunakan variabel lebih dari satu kali di tempat lain dalam kode Anda. Kelemahannya adalah bahwa variabel perlu diinisialisasi.
Gunakan
$!
dan$/
Variabel pra-deklarasi ini biasanya digunakan untuk pengecualian dan kecocokan regex masing-masing, tetapi tidak perlu didefinisikan menggunakan
my
.Terutama berguna adalah menggunakan
$/
sebagai array dan menggunakan cara pintas$
diikuti oleh nomor untuk mengakses elemen$/
array;sumber
Gunakan
...
sebagai gantifirst
Biasanya, jika Anda ingin menemukan nomor pertama yang cocok dengan beberapa kondisi
&f
, Anda dapat menggambarkannya seperti:Namun, sebagai gantinya Anda dapat menggunakan
...
operator:Jika Anda harus mulai dari
0
, Anda dapat memiliki-1
setelahnya+
.Jika Anda ingin indeks elemen pertama dalam daftar
@a
yang memiliki kondisi&f
, biasanya Anda lakukan:Sebagai gantinya:
(atau sebaliknya jika Anda ingin 0 diindeks). Dengan cara yang sama, Anda bisa mendapatkan semua elemen hingga yang pertama yang melewati kondisi.
Kelemahan dari hal ini adalah bahwa daftar harus melewati kondisi di beberapa titik, jika tidak
...
operator akan mencoba untuk meramalkan akhir daftar, dan kemungkinan besar akan membuat kesalahan. Anda juga tidak dapat menggunakan kode apa pun di sebelah kiri, karena itu akan ditafsirkan sebagai bagian dari urutan.sumber