Apa tips umum yang Anda miliki untuk bermain golf di Tcl? Saya mencari ide yang dapat diterapkan pada masalah kode golf secara umum yang setidaknya agak spesifik untuk Tcl (mis. "Hapus komentar" bukan jawaban). Silakan kirim satu tip per jawaban.
Pada jawaban saya /codegolf//a/107557/29325 saya dapat menunjukkan:
Biasanya set j 0;while \$j<$n;{...;incr j}
lebih pendek dari yang setarafor {set j 0} {$j<$n} {incr j} {...}
Ketika variabel pengulangan dimulai pada 1, kita dapat melakukan kenaikan sebagai bagian dari while
kondisi pengujian, menghindari menulis sebelum set i 1
tidak perlu: while {[incr i]<=$n} {...}
bukannyaset i 1;while \$i<=$n;{...;incr i}
PERHATIAN : Seseorang hanya bisa 2. dalam kasus loop luar! Saya tidak bisa menerapkannya ke j
variabel saya karena harus diatur ulang ke 1 di luar loop dalamnya sendiri! Dan incr j
akan memperoleh nilai yang ditetapkan pada langkah terakhir dari loop dalam, alih-alih mengambil variabel yang tidak ditentukanj
untuk mengasumsikan 0
dan menambahkannya ke 1
!
Kadang-kadang layak untuk digunakan di time {script} n
mana n
jumlah iterasi bukan normal while
atau for
loop. Meskipun time
tujuan tidak berulang, efek yang dicapai adalah sama.
Saya membuat perubahan baru-baru ini untuk jawaban saya sendiri mengikuti arah ini.
PEMBARUAN: Saya baru saja menemukan perangkap yang mudah jatuh: Anda tidak dapat mengganti a for
atau a while
dengan time
blok, jika mengandung a break
atau a continue
.
Gunakan shell interaktif. Ini memungkinkan Anda untuk menyingkat nama perintah selama hanya 1 perintah dimulai dengan huruf yang tersisa.
Contoh:
gets
-> ge
lassign
-> las
expr
-> exp
puts
-> pu
Dan solusi interaktif gratis: P
Latar belakang :
Ketika tclsh
berjalan dengan terminal sebagai perangkat input, ia menetapkan variabel tcl_interactive
untuk 1
. Ini menyebabkan unknown
(prosedur default yang akan dipanggil jika perintah tidak dapat ditemukan) untuk mencari perintah yang dimulai dengan nama itu.
Kelemahan: itu akan mencetak hasil setiap baris, gunakan ;
bukan baris baru.
Ohh, dan itu mungkin memanggil perintah eksternal seperti w
, yang merupakan singkatan dari while
.
Sub-perintah dan opsi dapat (biasanya) disingkat. Ini dapat menghemat sedikit, tetapi Anda harus menguji karena tidak semuanya dapat dipersingkat dengan cara ini (misalnya regsub
, opsi tidak dapat).
Anda kemudian dapat menggunakan ini dengan keajaiban namespace
untuk melakukan beberapa hal yang benar-benar jahat. Pertimbangkan ini:
namespace exp *;namespace en cr -c ?
Setelah itu, ?
sekarang perintah magis yang memungkinkan Anda menyingkat perintah Tcl global, dan semua tanpa ketidakpastian yang mengganggu unknown
.
Saya menggunakan Tcl 8.0.5, tapi saya percaya yang berikut ini berlaku untuk semua versi terbaru.
Gunakan rename
untuk mengganti nama rename
:
rename rename &
The &
dapat berupa identifier; &
hanya mengingatkan saya pada "referensi" dalam C.
Gunakan nama yang diubah namanya rename
untuk set
:
& set =
Sekali lagi, =
dapat berupa pengidentifikasi apa pun; =
hanya intuitif bagi saya.
Sekarang, ganti nama perintah lain yang perlu diganti namanya, misalnya
& regsub R
& string S
& while W
Perintah bernilai penggantian nama jika, diberi panjangnya n , dan kejadian k , k (n-1) - (n + 4)> 0 . Memecahkan untuk k , rumusnya menjadi k > (n+4)/(n-1)
. Ini tabel referensi yang memudahkan:
length of minimum example(s)
command occurrences
------------------------------------------------
2 6 if (consider renaming to "?")
3 4 for, set (consider renaming to "=")
4 3 eval, expr, incr (consider renaming to "+"), info, join, proc, puts, scan
5 3 break, catch, lsort, split, subst, trace, unset, while
6 3 format, lindex, lrange, regexp, regsub, rename, return, string, switch
7 2 foreach, lappend, linsert, llength, lsearch, unknown
. 2 lreplace
. 2 continue
. 2
Selanjutnya, kompak perintah yang sering digunakan suka
= I index
= L length
jadi kamu bisa melakukan hal-hal seperti
S $I $x 7
S $L $x
Beberapa miscellanea yang jelas:
lappend
dapat mengatur elemen pertama dari daftar jika belum ada (tidak perlu diinisialisasi).array
, misalnya set doesNotExist(7) 43
."a b c"
) alih-alih [list a b c]
.foo${a}bar
.two\ words
daripada "two words"
. (Ingat secara umum bahwa untuk string yang berdekatan tanpa spasi, tanda kutip ganda dapat dihilangkan!)for
sebagai while
s untuk menyimpan satu atau dua karakter, karena while
dapat secara bersamaan memeriksa dan menambah sementara for
menggunakan blok yang terpisah.Untuk program yang lebih besar, inilah trik yang saya pikirkan tetapi belum diterapkan:
proc unknown {c args} {eval [info commands $c*] $args}
Ini meniru singkatan perintah interaktif! Biayanya 54 karakter, tetapi sekarang Anda dapat menggunakan j
untuk join
, sp
untuk split
, st
untuk string
, w
untuk while
, dan seterusnya.
info script {};set tcl_interactive 1
unknown
rute: lihat di sini dan di sini .selain itu opsional
Seperti yang dikatakan pada halaman manual jika ,
else
tersirat padaif
konstruksi blok. Jadi apaif ... {} else {}
bisa menjadi
if ... {} {}
seperti yang Anda lihat pada beberapa jawaban saya.
sumber
Mungkin itu harus diintegrasikan pada jawaban lain, tetapi begini saja:
Ketika a
proc
hanya memiliki satu parameter, ia dapat ditulis sebagaidari pada
Hal yang sama berlaku untuk dua parameter
proc
menggunakan backslash; dapat ditulis sebagaidari pada
Untuk jumlah parameter yang lebih tinggi,
{}
render kode yang lebih pendek.sumber
Kadang-kadang layak untuk mengganti dua
set
pernyataan untuk menyatukan string dengan hanya satulappend
pernyataan. Pada konstruksi seperti, seseorang dapat menggantikanoleh
Itu
append
perintah memilikiincr
perilaku seperti yang menginisialisasi variabel belum ditentukan.Berhati-hati untuk tidak kesalahan
append
denganlappend
sumber
Jika Anda menangani daftar dengan operasi yang secara sintaksis saling terkait di antara setiap elemen, terkadang Anda bisa
join
elemen untuk melakukan operasi tertentu, alih-alih melewatinya.Pada /codegolf//a/127042/29325 ada contoh:
Ini
read stdin
memberi23 214 52
kemudian membagi akan memberikan daftar{23 214 52}
. Setelah itu,[join {23 214 52} +]
akan mengembalikan string23+214+52
. Akhirnyaexpr 23+214+52
melakukan pekerjaan penjumlahansumber
split
.Jika Anda memiliki kode besar, Anda dapat menghindari beberapa penggunaan
expr
menggunakannamespace pat tcl::mathop
di awal. Ini menyediakan operasi awalan-sintaks sebagai fonction Tcl biasa. Sebagai contoh:Lihat halaman doc Mathop resmi
sumber
Ketika Anda memiliki beberapa variabel yang berada
set
di baris berikutnya, Anda dapat menggunakan satulassign
alih-alih beberapaset
instruksi untuk mencapai efek yang sama.Salah satu contoh adalah jawaban saya sendiri /codegolf//a/105789/29325
Untuk memutuskan, seseorang hanya perlu mempertimbangkan jumlah variabel (dengan asumsi variabel 1 huruf, seperti yang diharapkan saat bermain golf):
<5,
set
pegolf= 5,
set
danlassign
menghasilkan jumlah byte yang sama> 5,
lassign
lebih pegolfsumber