Apa, pos ini belum ada?
Tentu saja, GolfScript yang dibuat untuk golf, sehingga Anda mungkin berpikir bahwa tidak ada tips khusus yang benar-benar dibutuhkan. Tetapi untuk memanfaatkan fitur GolfScript sepenuhnya, Anda perlu mempelajari beberapa trik yang tidak jelas. Posting ini untuk mengumpulkan tips dan trik yang sangat membantu.
Untuk memulainya, berikut adalah halaman referensi GolfScript resmi. Anda harus benar-benar membiasakan diri dengan ini terlebih dahulu:
Secara khusus, saya akan sangat menyarankan membaca halaman dalam urutan ini - referensi cepat tidak banyak digunakan sampai Anda sudah cukup terbiasa dengan built-in, dan tutorial mencakup beberapa detail penting yang tidak dijelaskan pada halaman lain. .
Ps. Demi inspirasi dan minat pribadi, berikut adalah beberapa pertanyaan yang ingin saya lihat jawabannya:
Bagaimana cara melakukan transliterasi terbatas dalam GolfScript?
{FROM?TO=}%
berfungsi jika Anda dapat yakin semua input ditemukanFROM
(atau tidak keberatan semuanya dipetakan ke elemen terakhirTO
), tetapi semua cara yang saya lihat untuk membiarkan nilai yang tidak dipetakan tidak berubah lebih kurang klugey.Bagaimana cara terbaik mengubah string menjadi array kode ASCII dan kembali? Operasi apa yang melakukan ini sebagai efek samping? Apa cara terbaik untuk membuang karakter dalam string ke stack (seperti
~
halnya untuk array)?
sumber
... x
menjadi... [x]
? Yang terbaik yang bisa saya lihat adalah[.;]
.x
angka, maka[]+
berfungsi dan satu karakter lebih pendek. Dan tentu saja, jikax
satu-satunya hal di stack, maka hanya]
akan dilakukan.Jawaban:
Rasional / Float / Kompleks
Saya telah membaca berkali-kali sehingga GolfScript hanya memiliki bilangan bulat yang mulai saya percayai. Ya itu tidak benar.
Outputnya adalah
dengan interpreter GolfScript standar dan
di Web GolfScript .
Retasan serupa memungkinkan untuk melakukan cast ke Rational, Float atau bahkan Complex:
sumber
Gint.new(@val**b.val)
. TampaknyaGint
konstruktor kehilangan pemain int ...Menegasikan angka
Satu hal yang tidak dimiliki GolfScript adalah operator negasi bawaan. Cara yang jelas untuk mengubah angka pada tumpukan menjadi negatif, seperti
-1*
atau0\-
, membutuhkan tiga karakter. Namun, ada cara untuk melakukannya dalam dua:Ini berfungsi karena GolfScript menggunakan aritmatika komplemen dua , sehingga ~ x sama dengan - x −1.
Tentu saja, varian ini
(~
juga berfungsi; memilih di antara mereka umumnya masalah selera.sumber
Mengocok array
Cara termudah untuk mengocok array dalam GolfScript adalah dengan mengurutkannya dengan kunci sortir acak. Jika Anda hanya perlu secara acak mengocok beberapa nilai, kode berikut akan melakukannya:
Perhatikan bahwa, bahkan untuk daftar pendek, ini tidak akan memberikan pengocokan yang sangat baik. Karena paradoks ulang tahun , untuk mendapatkan pengocokan yang cukup seragam, argumen untuk
rand
perlu secara signifikan lebih besar daripada kuadrat dari panjang daftar yang dikocok.Mengganti yang di
9
atas dengan99
demikian memberikan hasil yang cukup baik untuk daftar hingga sepuluh elemen, tetapi menunjukkan bias yang terlihat untuk daftar yang lebih panjang.Kode berikut, yang menggunakan 9 9 = 387.420.489 nilai yang mungkin, baik untuk sekitar 1000 item atau lebih (dan dapat diterima hingga sekitar 20.000):
Untuk daftar yang sangat panjang, tambahkan satu lagi untuk nilai 99 99 ≈ 3,7 × 10 197 :
Pengujian:
Berikut distribusi elemen pertama dalam daftar 10-elemen yang dikocok menggunakan berbagai varian yang ditunjukkan di atas, sampel lebih dari 10.000 percobaan:
Output dari
10,{;9rand}$0=
menunjukkan bias yang sangat jelas, dengan0
kemungkinan lebih dari tiga kali berakhir di posisi pertama seperti1
:Dengan
10,{;99rand}$0=
, sebagian besar bias hilang, tetapi jumlah yang nyata masih tetap:Dengan
10,{;9.?rand}$0=
, output pada dasarnya tidak bisa dibedakan dari sampel yang benar-benar acak:Ps. Untuk pengacakan array atau string numerik yang benar - benar buruk, kode berikut terkadang dapat diterima:
Ini umumnya akan menjadi sangat bias, tetapi selama semua elemen dari array input (atau semua kode karakter dalam string) lebih besar dari satu, ia memiliki probabilitas nol untuk menghasilkan permutasi array, yang kadang-kadang dapat memuaskan persyaratan tantangan yang ditulis dengan buruk.
sumber
Untuk mengatasi subquestion tertentu:
Bagi mereka yang tidak mengerti masalahnya, sistem tipe GolfScript memberikan prioritas pada jenis dalam integer pesanan, array, string, blok. Ini berarti bahwa operasi array biasa yang diterapkan ke string hampir selalu memberi Anda string. Misalnya
akan meninggalkan
'BCD234'
di tumpukan.Akibatnya, cara terbaik untuk mengubah string menjadi array kode ASCII hampir pasti membuang karakter pada stack dan kemudian mengumpulkannya ke dalam array.
Apa cara terbaik untuk membuang karakter dalam string ke tumpukan?
{}/
Apa cara terbaik untuk mengubah string menjadi array kode ASCII?
[{}/]
(dengan peringatan biasa bahwa jika tidak ada hal lain di tumpukan Anda dapat melewati[
)Apa cara terbaik untuk mengubah array kode ASCII menjadi string?
''+
(Perhatikan bahwa ini juga meratakan array, jadi mis.[65 [66 67] [[[49] 50] 51]]''+
Memberi'ABC123'
)sumber
[]+''+
? (sepertinya agak lama)Jika program Anda rusak secara misterius, periksa variabel Anda
Saya baru saja menghabiskan waktu debugging program yang tampaknya benar yang digunakan
!
sebagai variabel (dengan alasan bahwa saya tidak akan menggunakannya lagi). Sayangnya saya memang menggunakanif
, dan ternyata implementasiif
panggilan!
untuk memutuskan cabang mana yang harus diikuti.sumber
Membungkus item teratas tumpukan ke dalam array
Untuk generalisasi penuh, opsi terbaik tampaknya adalah 4 karakter. Namun, dalam kasus-kasus khusus tertentu dimungkinkan untuk mengurangi ini.
1 char
]
bekerja dalam kasus khusus yangx
merupakan satu-satunya hal di stack.3 karakter
[]+
bekerja dalam kasus khusus yangx
merupakan bilangan bulat..,/
bekerja dalam kasus khusus yangx
merupakan array atau string yang benar. Misalnya"AB".,/
memberi["AB"]
;3,.,/
memberi[[0 1 2]]
. Namun,"".,/
dan[].,/
keduanya memberi[]
.4 karakter
[.;]
bekerja tanpa syarat.sumber
Itu pertanyaan yang bagus. Tidak ada cara langsung untuk menetapkan nilai ke elemen array di GolfScript, jadi, dengan satu atau lain cara, Anda harus membangun kembali seluruh array.
Cara umum terpendek yang saya tahu untuk memasukkan nilai baru
x
di indeksi
dalam array adalah dengan membagi array pada indeks yang diberikan dan menambahkanx
ke babak pertama sebelum bergabung bersama mereka lagi:.i<[x]+\i>+
(11 karakter) - masukkan nilaix
ke dalam array dengan indeks (berbasis-0)i
Untuk mengganti nilai pada indeks
i
denganx
, kita hanya perlu mempersingkat paruh kedua array dengan satu elemen:.i<[x]+\i)>+
(12 karakter) - ganti elemen pada indeks (berbasis-0)i
dengan nilainyax
Sebagai alternatif, memperpendek paruh pertama akan secara efektif melakukan hal yang sama, tetapi dengan pengindeksan berbasis 1, yang kadang-kadang lebih disukai:
.i(<[x]+\i>+
(12 karakter) - ganti elemen pada indeks (berbasis-1)i
dengan nilainyax
Dalam semua contoh di atas, jika
x
angka, tanda kurung di sekitarnya mungkin dihilangkan untuk menyimpan dua karakter, karena bagaimanapun akan secara otomatis dipaksa ke dalam array dengan cara+
:.i<x+\i>+
(9 karakter) - masukkan angkax
ke dalam array dengan indeks (berbasis-0)i
.i<x+\i)>+
(10 karakter) - ganti elemen di (0-based) indexi
dengan angkax
.i(<x+\i>+
(10 karakter) - ganti elemen di (1-based) indexi
dengan angkax
Tanda kurung juga dapat dihilangkan jika salah satu
x
atau "array" input (atau keduanya) benar-benar string, dalam hal ini hasilnya juga akan dipaksa menjadi string (menggunakan array biasa → aturan konversi string).Ps. Sebagai kasus khusus, jika kita tahu bahwa array memiliki elemen antara
i
dan 2 ×i
, kita dapat memasukkan elemen barux
pada indeks (berbasis 0)i
dengani/[x]*
(6 karakter). Apa ini sebenarnya adalah membagi array menjadi potongan-potongan hinggai
elemen dan menyisipkan dix
antara setiap potongan. Perhatikan bahwa, dalam hal ini, tanda kurung diperlukan meskipunx
angka.Pps. Pendekatan alternatif adalah menggunakan variabel yang dinamai secara dinamis. Sebagai contoh,
akan menetapkan nilai
'foo'
ke variabelx42
, sementaraakan mengambilnya.
Anda dapat mengoptimalkan ini lebih jauh dengan menghilangkan
x
awalan dan hanya menetapkan langsung ke literal angka - ini benar-benar legal di GolfScript, dan memungkinkan Anda untuk menyimpan satu char dari kode tugas dan memperpendek kode pengambilan menjadi adil`~
(atau tidak sama sekali, jika indeksnya konstan!). Sisi buruknya, tentu saja, adalah bahwa menetapkan literal numerik akan menimpa nilai literal itu di tempat lain dalam kode Anda. Namun, sering kali, penggunaan jumlah literal dapat dihindari (atau setidaknya dibatasi pada awal program, sebelum salah satu dari mereka dipindahkan), dalam hal ini trik ini baik-baik saja.sumber
i
selama 9 byte:.[i=]/[x]*
Manipulasi hasil akhir
Secara default, ketika program Anda berakhir, interpreter GolfScript menampilkan semua yang ada di stack, ditambah baris baru final, persis seperti jika program Anda berakhir dengan:
Apa yang tidak disebutkan secara langsung oleh dokumentasi adalah bahwa penerjemah secara harfiah memanggil built-in
puts
untuk menghasilkan output ini, dan bahwa built-in ini secara harfiah didefinisikan sebagai:Dengan demikian, Anda dapat menekan atau memanipulasi hasil akhir dengan mendefinisikan ulang
jika Anda merasa benar-benar bengkok). Berikut ini beberapa contohnya:
puts
,print
dan / ataun
(atauMenekan baris terakhir final:
(Tentu saja Anda dapat meninggalkan
;
jika Anda tidak keberatan string kosong ekstra di tumpukan.)Menekan hasil akhir sepenuhnya:
Ini menimpa
puts
dengan apa pun yang terjadi di atas tumpukan. Jika itu adalah sesuatu yang tidak ingin Anda lakukan, Anda dapat menggunakan mis0:puts;
. Perhatikan bahwa ini juga menekanp
(yang didefinisikan sebagai{`puts}:p;
), tetapi Anda masih bisa menggunakanprint
untuk output jika Anda mau.sumber
nothing
maksud Anda\n
?];
untuk menekan hasil akhir.min / maks
Untuk menemukan nilai terkecil / terbesar dalam array, cukup sortir dan ambil elemen pertama / terakhir:
$0=
(3 karakter) - elemen minimum dalam suatu arry$-1=
(4 karakter) - elemen maksimum dalam arrayJika Anda tahu panjang array, dan itu 10 elemen atau kurang, Anda dapat menemukan maksimum dalam tiga karakter dengan mengganti
-1
dengan indeks elemen terakhir.Jika Anda memiliki nilai pada stack, Anda bisa mengumpulkannya ke dalam array terlebih dahulu. Untuk ini, trik yang kadang-kadang bermanfaat adalah
[\]
mengumpulkan dua elemen teratas dari tumpukan ke dalam array, sementara[@]
mengumpulkan tiga teratas. Jadi, kita mendapatkan:[\]$0=
(6 karakter) - minimal dua nilai pada stack[@]$0=
(6 karakter) - minimal tiga nilai pada stack[\]$1=
(6 karakter) - maksimum dua nilai pada stack[@]$2=
(6 karakter) - maksimum tiga nilai pada stackTrik yang sama juga dapat digunakan untuk menemukan median dari tiga nilai, yang kadang-kadang berguna:
[@]$1=
(6 karakter) - median tiga nilai pada stackBerikut ini adalah trik lain yang berpotensi bermanfaat untuk menemukan min / maks dari dua nilai sambil meninggalkan nilai asli di tumpukan :
.2$>$
(5 karakter) - temukan minimum dua nilai pada stack, sambil membiarkan nilai asli tidak tersentuh.2$<$
(5 karakter) - temukan maksimum dua nilai pada stack, sambil membiarkan nilai asli tidak tersentuhCara kerjanya adalah
.2$
mengkloning dua elemen teratas pada stack dalam urutan terbalik (yaitua b
→a b b a
),<
/>
membandingkan salinan dan mengembalikan 0 atau 1, dan skalar$
kemudian menyalin salah satu dari dua nilai input tergantung pada hasil perbandingan.Jika Anda memiliki dua bilangan bulat negatif pada tumpukan, Anda dapat menggunakan
,\,&,
(5 karakter) untuk menemukan nilai minimum dan,\,|,
(5 karakter) untuk menemukan nilai maksimumnya. Trik ini menggunakan set persimpangan dan gabungan, masing-masing, pada rentang. Anda dapat menyimpan karakter lain jika memungkinkan untuk diterapkan,
pada setiap argumen secara terpisah tanpa harus menukarnya. Karena metode ini menghitung rentang untuk setiap argumen, itu tidak sangat efisien untuk angka yang lebih besar, tetapi bisa sangat berguna untuk input yang lebih kecil.Cara yang lebih pendek untuk menemukan minimum dua bilangan bulat non-negatif pada stack adalah
,<,
(3 karakter). Sayangnya, trik ini tidak berfungsi untuk menemukan yang maksimal.nilai mutlak
Operator nilai absolut bawaan GolfScript adalah
abs
(3 karakter). Walaupun ini dua karakter lebih dari yang saya inginkan, secara umum sulit dikalahkan.Dalam beberapa kasus (misalnya untuk mengurutkan berdasarkan nilai absolut) Anda mungkin menemukan kuadrat angka sebagai pengganti yang memadai untuk nilai absolutnya; ini dapat dihitung dalam dua karakter, baik
2?
atau.*
. Jadi, kita mendapatkan:{.*}$0=
(7 karakter) - elemen minimum dengan nilai absolut dalam array{.*}$-1=
(8 karakter) - elemen maksimum dengan nilai absolut dalam arrayDemikian pula, alih-alih pengujian misalnya jika nilai absolut angka kurang dari 3 dengan
abs 3<
(6 karakter, termasuk spasi), Anda dapat menguji apakah kuadratnya kurang dari 9 dengan.*9<
(4 karakter, tanpa ruang yang diperlukan).sumber
,\,&,
(5 karakter) untuk menemukan nilai minimum dan,\,|,
(5 karakter) untuk menemukan nilai maksimumnya. Trik ini menggunakan set persimpangan dan gabungan, masing-masing, pada rentang. Anda dapat menyimpan karakter lain jika memungkinkan untuk diterapkan,
pada setiap argumen secara terpisah tanpa harus menukarnya. Karena metode ini menghitung rentang untuk setiap argumen, itu tidak sangat efisien untuk angka yang lebih besar, tetapi bisa sangat berguna untuk input yang lebih kecil.Menghapus duplikat dari array
Operator yang ditetapkan
|
(gabungan),&
(persimpangan) dan^
(perbedaan simetris) akan memecah beberapa elemen array menjadi satu. Dengan demikian, cara paling sederhana untuk menghapus elemen duplikat dari array adalah dengan mengambil persatuan atau persimpangan dengan itu sendiri:atau:
Operator-operator ini akan memperlakukan string sebagai array karakter, sehingga mereka juga dapat digunakan untuk menghapus karakter duplikat dari string.
sumber
Transliterasi terbatas
Untuk mengatasi subquestion tertentu: diberi string, apa cara terbaik untuk melakukan a
tr
? Misalnyatr/ABC/abc/
Jika semua karakter dalam string akan terpengaruh, ini cukup mudah:
{'ABC'?'abc'=}%
(overhead: 9 karakter).Namun, itu rusak jika beberapa karakter tidak transliterasi dan
'ABC'?
memberi-1
.Jika transliterasinya non-siklik, maka dapat dilakukan satu per satu penggantian dengan pemisahan string dan bergabung:
'AaBbCc'1/2/{~@@/\*}/
(overhead: 15 karakter). Ini mungkin bisa diperbaiki, tetapi ada pendekatan alternatif yang saat ini lebih baik dan berfungsi untuk transliterasi siklik.Saat ini, solusi umum terpendek memiliki overhead 14 karakter:
Satu pendekatan melibatkan karakter pelarian:, di mana menunjukkan byte nol literal. (Tentu saja, metode ini tidak sepenuhnya umum: metode ini tidak dapat memetakan karakter lain ke dalam byte nol.)
{.'ABC'?'abc0'=\or}%
0
Atau,
{.'ABC'?'abc'@),+=}%
memiliki overhead yang sama, tetapi hanya menggunakan karakter ASCII yang dapat dicetak. Ini@),+
adalah cara berbelit-belit (tapi, tampaknya, yang terpendek) untuk memastikan bahwa string pengganti selalu berakhir dengan karakter input.sumber
'ABCDEF'
saya mendapatkan hasilnya'abc000'
, tetapi hasil yang tepat adalah'abcDEF'
. Apakah saya melewatkan sesuatu?Ubah string menjadi array char
Anda dapat melakukan ini dengan mengetik:
1/
setelahnya.Contoh:
"String"1/
mendorong untuk menumpuk array['S''t''r''i''n''g']
.Ini berguna saat Anda ingin memindahkan karakter di sekitar string.
sumber
"abc"1/(+
->"bca"
, tetapi"abc"(+
->bc97
.Menugaskan ke sejumlah literal
Seringkali, alih-alih menulis
1:x
dan kemudian menggunakan / memperbarui variabelx
, Anda bisa menggunakan dan memperbarui1
secara langsung:Tentu saja, ini juga berfungsi untuk nilai awal lainnya, tetapi akan rusak jika nilai itu terjadi di tempat lain dalam kode Anda.
Tanda baca sebagai nama variabel
Jika Anda memiliki untuk menggunakan variabel, itu juga sering bijaksana untuk menggunakan tanda baca yang tidak sudah dalam kode Anda - banyak program dapat melakukannya tanpa
&
,|
,^
, atau?
. Dengan cara ini, misalnya, Anda dapat menulis&n
alih-alihx n
untuk mendorong variabel Anda dan kemudian mendorong baris baru.sumber
!
seringkali merupakan ide yang buruk, karena akan merusakif
dando
(sertawhile
,until
,and
,or
danxor
). Demikian pula,or
didefinisikan oleh penerjemah sebagai alias untuk1$\if
, jadi mendefinisikan ulang1
,$
atau\
juga akan merusaknya. Mendefinisikan ulang`
istirahatp
.Memfilter array
Cara paling umum untuk memfilter array adalah dengan menggunakan
{ },
, yang mengevaluasi blok kode untuk setiap elemen array, dan memilih elemen-elemen yang nilai hasilnya benar (yaitu bertindak sepertigrep
dalam Perl).Namun, menggunakan operator pengurangan array
-
seringkali lebih pendek. Operator ini mengambil dua array, dan menghapus setiap elemen yang terjadi di array kedua dari yang pertama. Itu tidak mengubah urutan elemen dalam array pertama atau menutup duplikat. Trik yang berguna adalah menerapkan operasi pengurangan dua kali untuk menghasilkan operator persimpangan array yang tidak runtuh:a b -
: hapus semua elemen yang ditemukan dalam arrayb
dari arraya
a. b --
: hapus semua elemen yang tidak ditemukan dalam arrayb
dari arraya
Secara khusus, ini dapat digunakan untuk menghitung berapa kali suatu elemen terjadi dalam array:
a.[c]--,
: hitung berapa kali elemen tersebutc
muncul dalam arraya
Secara umum, metode ini tidak optimal, karena salah satu dari:
a[c]/,(
: hitung berapa kali elemen tersebutc
muncul dalam arraya
a{c=},,
: hitung berapa kali elemen tersebutc
muncul dalam arraya
lebih pendek satu karakter (dan, jika OK untuk hitungan dimatikan oleh satu,
a[c]/,
menghemat satu karakter lebih banyak). Namun, dalam kasus khusus di manac
angka dana
array normal (bukan string), tanda kurung di sekitarc
dapat dihilangkan karena-
operator memaksa argumennya ke tipe yang sama:a.c--,
: hitung berapa kali jumlah ituc
terjadi dalam array (bukan string!)a
(Jika
a
adalah string danc
angka antara 0 dan 9,a.c--
akan menghitung berapa kali digit ituc
muncula
.)Trik serupa dapat digunakan untuk menemukan elemen paling umum dalam array :
Sekali lagi, jika input adalah array angka, seluruh
[.]
urutan dapat dihilangkan. Sayangnya, ini tidak berfungsi untuk string tanpa[.]
.sumber
a[c]/,(
dana{c=},,
satu byte lebih pendek.Baca dari STDIN
GolfScript dapat membaca dari stdin:
Ini akan terus membaca dari STDIN sampai EOF tercapai. Kalau tidak:
atau
Hal lain yang tersedia:
Untuk masing-masing, mereka hanya dapat digunakan sekali (dan juga sekali untuk setiap perubahan parameter, juga sekali lagi dengan tanda kurung kosong); setelah itu, nilai asli adalah apa yang akan Anda dapatkan alih-alih nilai baru.
sumber
{"#{STDIN.readline}"p}2*
tidak membaca 2 baris tetapi string dievaluasi hanya sekali.i
ke bilangan bulat apa pun,'"#{'i):i';STDIN.gets}"'++~
akan memberikan hasil yang berbeda setiap kali dievaluasi. Backticks juga layak disebut. Jika kita menganggap Linux, kita bisa menggunakan, misalnya,`head -1`
bukanSTDIN.gets
."#{var'g','gpush Gstring.new(STDIN.gets)'.cc}";
juga akan membiarkan Anda menentukan operator GolfScript barug
yang membaca garis dari stdin dan mendorongnya di tumpukan.Mendekode input heksadesimal
GolfScript tidak memiliki hex integer literals, jadi, sayangnya, Anda tidak bisa hanya menguraikan input heksadesimal
~
. Sebaliknya, jika kode Anda harus mengambil input hex, Anda harus menguraikannya secara manual.Loop 8-char ini, diterapkan pada string, akan mengonversi digit heks huruf kecil menjadi setara numeriknya:
Jika Anda harus (juga) menerima angka hex huruf besar, solusi termudah (dan mungkin yang terpendek) adalah dengan terlebih dahulu menggunakan huruf kecil
32|
, dengan total 11 karakter:Perhatikan bahwa output secara teknis masih berupa string (terdiri dari karakter ASCII 0 - 15), tetapi sebagian besar fungsi array GolfScript akan menerima string juga. Jika Anda benar-benar membutuhkan array, Anda selalu dapat menggunakan
[{39%9-}/]
(di mana yang pertama[
adalah opsional jika tumpukannya kosong).Untuk mengubah output dari kode di atas menjadi bilangan bulat, Anda cukup menggunakan
16base
(6 karakter). Jika Anda menginginkan array byte sebagai gantinya, solusi terpendek yang saya temukan hanya dengan mendekode setiap pasangan digit hex dengan2/{16base}%
(11 karakter). Semua disatukan, kode terpendek yang saya temukan untuk mengubah string hex menjadi array byte adalah 8 + 11 = 19 karakter:Perhatikan bahwa output dari kode ini memang berupa array, bukan string. Jika perlu, Anda dapat mengencangkannya dengan menggabungkannya misalnya dengan
""+
atau, jika Anda tidak keberatan dengan baris baru tambahan di akhirn+
,.sumber
Menentukan operator bawaan baru
Standar GolfScript interpreter memiliki jarang digunakan fitur yang yang memungkinkan kode Ruby interpolasi dalam string literal yang dikutip ganda.
Salah satu alasan mengapa fitur ini tidak lebih umum digunakan adalah bahwa, canggung, kode interpolasi dijalankan pada waktu kompilasi , dan output di-cache oleh interpreter GolfScript sehingga string literal yang sama akan selalu menghasilkan nilai yang sama, bahkan di dalam string eval.
Namun, satu hal fitur ini ternyata bagus untuk mendefinisikan operator GolfScript baru diimplementasikan dalam kode Ruby. Sebagai contoh, berikut ini cara mendefinisikan operator penjumlahan biner baru yang berfungsi seperti operator bawaan standar
+
:Tidak masalah di mana Anda memasukkan definisi dalam kode Anda; operator baru akan ditentukan segera setelah string yang dikutip ganda berisi kode Ruby diuraikan. The
add
Operator didefinisikan di atas karya persis seperti built-in+
operator, dan dapat digunakan dengan cara yang persis sama:Tentu saja, mendefinisikan operator tambahan baru sangat tidak berguna, kecuali Anda telah melakukan sesuatu yang konyol seperti menghapus
+
operator bawaan . Tetapi Anda dapat menggunakan trik yang sama untuk mendefinisikan operator baru yang melakukan hal-hal yang tidak dapat (dengan mudah) dilakukan oleh Golfscript seperti, misalnya, menyeret array secara seragam:atau mencetak isi seluruh tumpukan:
atau input interaktif:
atau bahkan akses web:
Tentu saja, implementasi yang lebih golf (dan lebih berisiko!) Dari yang terakhir akan misalnya:
Meskipun tidak terlalu bersifat golf, ini memungkinkan Anda memperluas kemampuan GolfScript melampaui apa yang disediakan perintah bawaan.
Bagaimana cara kerjanya?
Referensi otoritatif tentang cara mendefinisikan operator GolfScript baru dengan cara ini, tentu saja, kode sumber untuk penerjemah . Yang mengatakan, inilah beberapa tips cepat:
Untuk menetapkan operator baru
name
yang menjalankan kode Rubycode
, gunakan:Di dalam kode, gunakan
gpop
untuk membaca nilai dari stack, dangpush
untuk mendorongnya kembali. Anda juga dapat mengakses stack secara langsung melalui array$stack
. Misalnya, untuk mendorong keduaa
danb
ke stack, itu Golfier untuk melakukan$stack<<a<<b
daripadagpush a;gpush b
.[
penanda mulai array disimpan dalam$lb
array. Thegpop
Fungsi mengurus menyesuaikan tanda tersebut turun jika tumpukan menyusut di bawah posisi mereka, tetapi memanipulasi$stack
array yang langsung tidak.The
.cc
Metode string yang mengkompilasi kode Ruby dalam string ke operator GolfScript hanya bungkus-toko di sekitarGblock.new()
. Ini juga memiliki varian.cc1
,.cc2
dan.cc3
itu membuat operator secara otomatis mengeluarkan argumen 1, 2 atau 3 dari stack dan menetapkannya ke variabela
,b
danc
. Ada juga.order
metode yang berfungsi seperti itu.cc2
, kecuali bahwa itu secara otomatis mengurutkan argumen berdasarkan jenis prioritas .Semua nilai-nilai pada stack GolfScript adalah (dan harus!) Objek dari jenis
Gint
,Garray
,Gstring
atauGblock
. Integer atau array asli yang mendasarinya, di mana diperlukan, dapat diakses melalui.val
metode.Gstring.val
mengembalikan arrayGint
s! Untuk mengubahGstring
menjadi string Ruby asli, panggil.to_s
saja (atau gunakan dalam konteks yang melakukannya secara otomatis, seperti interpolasi string). Memanggil.to_gs
nilai GS apa pun mengubahnya menjadiGstring
, sehingga nilai GS apa pun dapat dirangkum dengan.to_gs.to_s
.The
gpush
Fungsi tidak auto-wrap nomor Ruby asli, string atau array ke dalam jenis GS yang sesuai, sehingga Anda akan sering harus melakukannya sendiri dengan secara eksplisit menyebut misalnyaGstring.new()
. Jika Anda mendorong apa pun selain salah satu dari tipe nilai GS ke tumpukan, kode apa pun yang kemudian mencoba untuk memanipulasinya kemungkinan akan mogok.Tipe nilai GS juga memiliki
.factory
metode yang memanggil konstruktor tipe tersebut, yang dapat berguna misalnya untuk menyusun ulang array / string setelah memanipulasi kontennya. Semua tipe juga memiliki.coerce
metode yang melakukan pemaksaan tipe :a.coerce(b)
mengembalikan pasangan yang mengandunga
danb
dipaksa ke tipe yang sama.sumber