Karena kita tidak bisa mendapatkan cukup golf bahasa esoteris, bukan?
/// - slash yang diucapkan —adalah bahasa kecil yang menyenangkan berdasarkan s///
fungsi penggantian-regex dari ketenaran Perl. Ini hanya berisi dua karakter khusus, garis miring /
dan garis miring terbalik \
. Anda dapat menemukan artikel lengkapnya di esolangs wiki , tetapi saya akan mereproduksi deskripsi bahasa di bawah ini, serta beberapa contoh.
Singkatnya, ini berfungsi dengan mengidentifikasi /pattern/repl/rest
dalam program dan membuat penggantian sebanyak mungkin. Tidak ada karakter yang khusus kecuali /
dan \
: /
membatasi pola dan penggantian dalam program, sementara \
memungkinkan Anda untuk memasukkan huruf /
atau \
karakter ke dalam kode Anda. Khususnya, ini bukan ekspresi reguler, hanya penggantian string biasa.
Tantangan Anda adalah menghasilkan penerjemah untuk bahasa ///, baik sebagai program yang membaca STDIN atau fungsi yang mengambil argumen string, dalam karakter sesedikit mungkin.
Anda dapat menggunakan bahasa apa pun kecuali /// sendiri. Anda tidak boleh menggunakan pustaka yang menafsirkan ///; Anda dapat, bagaimanapun, menggunakan regex, regex librari, atau pustaka pencocokan string.
Eksekusi
Ada empat negara bagian, cetak , pola , penggantian , dan penggantian . Di setiap negara kecuali penggantian :
- Jika program kosong, eksekusi terhenti.
- Lain, jika karakter pertama
\
, lakukan sesuatu dengan karakter berikutnya (jika ada) dan hapus keduanya dari program. - Jika karakter pertama adalah
/
, hapus, dan ubah ke status berikutnya. - Lain, lakukan sesuatu dengan karakter pertama dan hapus dari program.
- Ulangi.
Status menyatakan melalui cetak , pola , penggantian , dan penggantian secara berurutan.
- Dalam mode cetak , 'lakukan sesuatu' berarti mengeluarkan karakter.
- Dalam mode pola , 'lakukan sesuatu' berarti menambahkan karakter ke Pola saat ini.
- Dalam mode penggantian , 'lakukan sesuatu' berarti menambahkan karakter ke Penggantian saat ini.
Dalam mode substitusi , Anda mengikuti serangkaian aturan yang berbeda. Ganti secara berulang kejadian pertama dari Pola saat ini dengan Penggantian saat ini dalam program, sampai tidak ada lagi penggantian yang mungkin. Pada saat itu, hapus Pola dan Penggantian dan kembali ke mode cetak .
Dalam program ini /foo/foobar/foo foo foo
, hal berikut terjadi:
/foo/foobar/foo foo foo
foo foo foo
foobar foo foo
foobarbar foo foo
foobarbarbar foo foo
...
Loop ini selamanya dan tidak pernah keluar dari mode substitusi . Demikian pula, jika Pola kosong, maka kemunculan pertama string kosong — di awal program — selalu cocok, sehingga mode substitusi berulang selamanya, tidak pernah berhenti.
Contohnya
no
Output: no
.
/ world! world!/Hello,/ world! world! world!
Output: Hello, world!
.
/foo/Hello, world!//B\/\\R/foo/B/\R
Output: Hello, world!
.
a/ab/bbaa/abb
Output: a
. Program tidak berhenti.
//
Output: tidak ada.
///
Output: tidak ada. Program tidak berhenti.
/\\/good/\/
Output: good
.
Ada juga quine di wiki yang bisa Anda coba.
sumber
/-/World//--/Hello//--W/--, w/---!
Apa yang tidak untuk dicintai? (Coba hapus tanda hubung dari akhir)\
Karakter tersebut lolos dari semua karakter yang mengikutinya, termasuk/
, yang nantinya dapat digunakan seperti biasa. Meskipun ini tidak terlihat banyak, ini membuat /// Turing-complete .///
IDE saya yang saya buat!Jawaban:
APL (133)
Ini adalah fungsi yang mengambil
///
kode sebagai argumen yang benar.Tidak disatukan, dengan penjelasan:
sumber
///
dan//foo/
(yaitu loop selamanya)?/
itu masih akan tersisa pada saat itu.J -
181190170 charIni adalah mimpi buruk. Saya menulis ulang dari awal, dua kali, karena itu terus mengganggu saya. Ini adalah fungsi yang mengambil argumen string tunggal, mengeluarkan ke STDOUT.
Untuk menjelaskannya, saya akan memecahnya menjadi subekspresi.
i
(kependekan dari iterate ) adalah kata keterangan. Dibutuhkan argumen kata kerja di sebelah kiri dan mengembalikan kata kerja(f)i
, yang ketika diterapkan pada argumen, berlakuf
berulang kali pada argumen sampai salah satu dari dua hal terjadi: ia menemukan titik tetap (y = f y
), atau melemparkan kesalahan. Perilaku titik tetap melekat^:_
, dan::]
melakukan penanganan kesalahan.parse
tokenizes input ke dalam apa yang saya sebut formulir setengah-parsing , dan kemudian memotongnya di '/' unescaped. Itu mengikat melarikan diri garis miring terbalik ke karakter mereka, tetapi tidak menghilangkan garis miring terbalik — jadi kita dapat mengembalikannya atau menyelesaikannya tergantung yang kita inginkan.Sebagian besar pekerjaan menarik terjadi di
;:
. Ini adalah primitif juru mesin sekuensial, mengambil deskripsi mesin ((0;(0,:~1 0,.2);'\';&<1 0)
) di sebelah kiri dan sesuatu untuk diurai di sebelah kanan. Ini melakukan tokenizing. Saya akan perhatikan bahwa mesin khusus ini benar-benar memperlakukan karakter pertama tidak khusus, bahkan jika itu adalah\
dan harus mengikat. Saya melakukan ini karena beberapa alasan: (1) tabel negara lebih sederhana, sehingga dapat di-golf lebih lanjut; (2) kita dapat dengan mudah menambahkan karakter dummy ke depan untuk menghindari masalah; dan (3) bahwa karakter-dummy menjadi setengah-parsing tanpa biaya tambahan, jadi saya dapat menggunakannya untuk mengatur fase pemotongan, selanjutnya.Kami juga menggunakan
<;._1
untuk memotong hasil tokenized pada unescaped/
(yang saya pilih untuk menjadi karakter pertama). Ini berguna untuk mengeluarkan output, pola, dan penggantian dariout/patt/repl/rest
semua dalam satu langkah, tetapi sayangnya juga memotong seluruh program, di mana kita membutuhkan mereka/
untuk tetap tidak tersentuh. Saya menyambungkan ini kembali selamaeval
, karena membuat<;._1
mereka sendirian berakhir dengan biaya lebih banyak.Garpu
(eval [ print)
mengeksekusiprint
pada hasil dariparse
karena efek sampingnya, dan kemudian berjalaneval
.print
adalah kata kerja sederhana yang membuka kotak pertama (yang kita tahu pasti adalah keluaran), selesai menguraikannya, dan mengirimkannya ke STDOUT. Namun, kami juga mengambil kesempatan untuk mendefinisikan kata kerja utilitasp
.p
didefinisikan sebagai>@{.@[
, sehingga dibutuhkan arg kiri (bertindak seperti identitas jika hanya diberi satu arg), mengambil item pertama dari itu (identitas saat diberi skalar), dan menghapus kotaknya (identitas jika sudah dibuka kotaknya). Ini akan sangat bergunasub
.eval
mengevaluasi sisa program yang diproses. Jika kita tidak memiliki pola penuh atau penggantian penuh,eval
buang saja dan hanya mengembalikan daftar kosong, yang mengakhiri evaluasi dengan membuat;:
(dariparse
) kesalahan pada iterasi berikutnya. Lain,eval
sepenuhnya mem-parsing pola dan penggantian, memperbaiki sisa sumber, dan kemudian melewati keduanyasub
. Dengan ledakan:sub
adalah di mana satu (mungkin tak terbatas) pergantian terjadi. Karena cara kita mengatureval
, sumbernya adalah argumen yang tepat, dan pola serta penggantiannya digabungkan menjadi satu di sebelah kiri. Karena argumen diperintahkan seperti ini dan kita tahu pola dan penggantian tidak berubah dalam putaran pergantian, kita dapat menggunakan fitur laini
— fakta bahwa itu hanya mengubah argumen yang benar dan terus lewat di kiri yang sama — untuk mendelegasikan untuk J perlu khawatir tentang melacak negara.Ada dua titik masalah. Yang pertama adalah bahwa kata kerja J dapat memiliki paling banyak dua argumen, jadi kami tidak memiliki cara mudah untuk mengakses sembarang yang dibundel bersama, seperti pola dan penggantian, di sini. Melalui penggunaan cerdas dari
p
utilitas yang kami tetapkan, ini bukan masalah besar. Faktanya, kita dapat mengakses pola dalam satu karakter, hanya dengan menggunakanp
, karena>@{.@[
definisinya: Unbox of the First item dari Left arg. Mendapatkan penggantian itu lebih sulit, tetapi cara tersingkat adalahp&|.
, 2 karakter lebih pendek daripada secara manual.Masalah kedua adalah bahwa
i
keluar pada titik-titik tetap alih-alih berulang selamanya, dan jika polanya dan penggantiannya sama dan Anda membuat substitusi, itu terlihat seperti titik tetap untuk J. Kami menangani ini dengan memasukkan loop tak terbatas dengan meniadakan 1 ke atas dan berakhir jika kami mendeteksi mereka sama: ini adalah-i@=`p@.~:~/
bagian, menggantikanp&|.
.Siklus ini berulang karena penggunaan
i
, sampai sesuatu di luarsub
kesalahan keluar. Sejauh yang saya ketahui, ini hanya bisa terjadi ketika kita kehabisan karakter, ketika kita membuang serangkaian pola-dan-penggantian yang tidak lengkap.Fakta menyenangkan tentang golf ini:
;:
lebih pendek dari iterasi secara manual melalui string.0{
harus memiliki kesempatan untuk kesalahan sebelumsub
masuk ke loop tak terbatas, jadi ini harus bekerja dengan baik jika pola cocok dengan penggantian tetapi tidak pernah muncul di sisa sumber. Namun, ini mungkin atau mungkin bukan perilaku yang tidak ditentukan, karena saya tidak dapat menemukan kutipan di dokumen. Whoopsie.i
, kesalahan itu juga terperangkap. Bergantung pada saat Anda menekan Ctrl + C, Anda mungkin:sub
loop dengan mencoba menyatukan angka ke string, dan kemudian terus menafsirkan /// seolah-olah Anda selesai mengganti string dengan dirinya sendiri dengan jumlah kali yang tak terbatas.sub
setengah jalan dan terus menafsirkan ekspresi /// setengah sub.Contoh penggunaan:
sumber
/\\/good/\/
test case; debugging memberitahu saya bahwa masalahnya adalah penggunaan saya1!:2&4
, karena jqt tidak memiliki stdin / out. Akan menyelidiki. Apa Anda9!:12''
dan9!:14''
?9!:12''
adalah 6, dan9!:14''
j701 / 2011-01-10 / 11: 25.Perl - 190
Membaca
///
program dari stdin hingga EOF.sumber
m/^(.*?)(?<!\\)\/(.*?)(?<!\\)\/(.*?)(?<!\\)\/(.*)$/s
--yaitu mencocokkan output, pola, dan penggantian sekaligus - membuat golf lebih pendek? Saya sendiri tidak tahu Perl./a/\0/a
Pip ,
100102 byteSaya tidak pernah membuktikan bahwa Pip adalah Turing-complete (walaupun jelas sekali begitu), dan alih-alih menggunakan rute BF yang biasa, saya pikir /// akan menarik. Setelah saya memiliki solusinya, saya pikir saya akan golf dan mempostingnya di sini.
101 byte kode, +1 untuk
-r
bendera:Inilah versi saya yang tidak diserang dengan komentar berlebihan:
Cobalah online! (Perhatikan bahwa TIO tidak memberikan output apa pun ketika program tidak berhenti, dan juga memiliki batas waktu. Untuk contoh yang lebih besar dan loop tak terbatas, disarankan menjalankan Pip dari baris perintah.)
sumber
pip + -r
, 101 byteC ++: Visual C ++ 2013 = 423, g ++ 4.9.0 = 442
Ini tidak akan pernah menang, tetapi karena saya telah memutuskan bahwa semua proyek perangkat lunak saya di masa depan akan ditulis dalam bahasa yang luar biasa ini, saya memerlukan intepreter untuk itu dan saya pikir saya mungkin juga membagikan yang saya buat ...
Perbedaan skornya adalah bahwa Visual C ++ tidak perlu menyertakan pertama tetapi g ++ tidak. Skor tersebut mengasumsikan bahwa akhir baris dihitung sebagai 1.
sumber
if(!o[i]);
sebagaiif(P
untuk menyimpan karakter, atau aku salah paham bagaimana #define bekerja?P
dimain
memiliki ruang setelah, sehingga Anda dapat menyimpan karakter dengan mengganti ruang-ruang tersebut dengan titik koma dan mengeluarkannya dari#define
. Kemudian, jika Anda dapat menggunakan#define
di dalam yang lain, Anda dapat menyimpan lebih banyak dengan menulis ulangN(x)
sebagai(92==P
gantio[i]==92
danO
juga.N(x)
sebagaiP;else if(n<x)(P==92?
dan mengubah panggilan ke yangN
sesuai bisa menghemat beberapa byte.Python 2 (236), Python 3 (198?)
Disebut sebagai
d(r"""/foo/Hello, world!//B\/\\R/foo/B/\R""")
. Kutipan rangkap hanya diperlukan jika///
program berisi baris baru: jika tidak, kutipan sederhana tidak masalah.EDIT: Penerjemah ini sekarang mencetak hal-hal seperti yang diharapkan (sebelumnya hanya dicetak di akhir, lih komentar). Untuk Python 3, hapus baris pertama (tapi saya tidak punya Python 3 pada instal lama saya, jadi tidak bisa memastikan tidak ada perubahan lain).
sumber
/a/ab/bbaa/abb
./a/ab/bbaa/abb
akan terjebak dalam loop tanpa akhir tanpa mencetak apapun, karena substitusi pertama adalaha
=>ab
. Yang benara/ab/bbaa/abb
berfungsi seperti yang diiklankan.-u
untuk memaksa buffer output menjadi tidak terbaca.Cobra - 226
sumber
Ruby ,
119110 byteBerakhir dengan pengecualian
Cobalah online!
Berakhir bersih (116 byte)
Cobalah online!
sumber
Python 2/3 (211 byte)
Kode berikut, berdasarkan pada jawaban Bruno Le Floch , adalah Python 2 dan Python 3 yang kompatibel.
Selain itu, menjadi berulang daripada rekursif itu tidak berisiko memukul kedalaman rekursi maksimum Python.
sumber
in(0,1,2)
kein 0,1,2
dan[""]*2+[1]
ke["","",1]
, menghasilkan 211 byte .BaCon ,
391387395 byteDari kontribusi di halaman ini saya hanya menjalankan program Python. Yang lain bekerja untuk beberapa /// sampel, atau tidak bekerja sama sekali. Oleh karena itu, saya memutuskan untuk menambahkan versi saya, yang merupakan implementasi di BASIC.
Untuk bersaing dalam kontes CodeGolf dengan BASIC tidak mudah, karena BASIC menggunakan kata-kata panjang sebagai pernyataan. Satu-satunya singkatan yang biasa ditemukan di BASIC adalah '?' tanda, yang berarti PRINT.
Jadi program di bawah ini mungkin tidak pernah menang, tetapi setidaknya ia bekerja dengan semua kode demonstrasi pada halaman Codegolf ini dan pada Esolangs Wiki . Termasuk semua versi "99 botol bir".
sumber