Prindeal (diucapkan prin-dee-al ) adalah bahasa pemrograman esoterik baru yang hanya memiliki empat perintah: pr int , in crement , de crement , dan al ias . Meskipun minimalis, operasi matematika yang kompleks dapat dilakukan di Prindeal dengan menggabungkan empat perintah secara cerdik.
Tugas Anda dalam tantangan golf kode ini adalah menulis program terpendek yang dapat menjalankan kode Prindeal.
Speknya panjang tapi saya sudah mencoba membuatnya sejelas mungkin dan saya percaya bahwa jika Anda berusaha untuk belajar Prindeal Anda akan menemukannya cukup elegan!
Intrepreting Prindeal
Preprocessing
Sebelum sebuah program Prindeal dapat diartikan hal-hal ini perlu dihapus darinya dalam urutan ini:
- Apa pun setelah
#
tanda ke ujung garis itu aktif, ditambah tanda#
itu sendiri. (Ini adalah komentar.) - Membuntuti spasi putih pada baris apa pun.
- Baris benar-benar kosong.
Misalnya, program Prindeal
p cat #The next line has 7 trailing spaces.
p dog
#p mouse
akan diolah menjadi
p cat
p dog
Dari sini kita akan menganggap langkah preprocessing ini telah dilakukan.
Variabel
Kita dengan cepat perlu mendefinisikan variabel sebelum menunjukkan bagaimana mereka digunakan.
Variabel (dan referensi ke variabel) adalah apa yang diteruskan ke argumen perintah Prindeal. Variabel selalu bersifat global , jadi modifikasi terhadap suatu variabel, di mana pun mereka terjadi, tercermin di mana-mana.
Setiap variabel memiliki integer presisi arbitrer non-negatif (0, 1, 2, 3, ...). Variabel tidak perlu diinisialisasi - mereka selalu mulai dengan nilai 0 saat pertama kali mereka digunakan atau dipanggil.
Nama variabel dapat berupa string alfanumerik dan garis bawah non-kosong yang tidak dimulai dengan digit - [a-zA-Z_][0-9a-zA-Z_]*
dalam regex . Mereka peka huruf besar-kecil, jadi spiny_lumpsuck3r
dan Spiny_lumpsuck3r
merupakan variabel yang berbeda.
Eksekusi
Prindeal adalah bahasa pemrograman yang sangat penting . Ketika program Prindeal dijalankan, pernyataannya dieksekusi dari atas ke bawah secara berurutan dan kemudian program berakhir.
Setiap baris non-indentasi dalam program Prindeal adalah pernyataan yang melibatkan eksekusi satu perintah yang mungkin atau tidak dapat mengambil argumen.
Baris indentasi hanya muncul setelah perintah alias . Secara khusus, tepat tiga baris yang ditandai dengan spasi tunggal muncul setelah setiap perintah alias dan dianggap sebagai bagian darinya. Jadi pernyataan alias benar-benar panjang empat baris. (Mereka bisa menjadi satu baris, empat hanya lebih mudah dibaca.)
Pernyataan Non- alias
Dengan pengecualian alias , setiap pernyataan dalam program Prindeal memiliki formulir:
[command name] [argument 1] [argument 2] [argument 3] ...
Mungkin ada sejumlah argumen sewenang-wenang (termasuk tidak ada sama sekali). Setiap argumen selalu merupakan variabel atau (seperti yang akan kita lihat ketika membahas alias ) referensi ke variabel .
Setelah selesai dieksekusi, setiap pernyataan ditandai sebagai kegagalan atau keberhasilan tergantung pada apakah kesalahan ditemukan atau tidak. (Ini hanya masalah ketika kita menggunakan alias .)
Cetak built-in , increment , dan decrement adalah pernyataan dengan formulir di atas. Inilah yang mereka lakukan:
print memiliki nama perintah
p
dan mengambil satu argumen. Ini mencetak nama variabel yang diteruskan dan nilainya (dalam desimal) dipisahkan oleh "=", lalu baris baru. Itu selalu ditandai sebagai keberhasilan .Misalnya, program Prindeal
p _MyVariable_321 p screaming_hairy_armadillo
akan menghasilkan
_MyVariable_321 = 0 screaming_hairy_armadillo = 0
karena semua variabel mulai dari 0. (Spasi sebelum dan sesudah tanda sama dengan diperlukan.)
increment memiliki nama perintah
i
dan mengambil satu argumen. Itu menambah nilai variabel yang dilewatkan oleh 1. Itu selalu ditandai sebagai sukses ..Misalnya saja programnya
i alpaca p alpaca i alpaca p alpaca
akan menghasilkan
alpaca = 1 alpaca = 2
Perhatikan bagaimana
alpaca
peningkatan dari 0 menjadi 1 meskipun belum pernah diakses sebelumnya.decrement memiliki nama perintah
d
dan mengambil satu argumen. Jika variabel yang diteruskan adalah nol, nilainya dikurangi dengan 1 dan pernyataan ditandai sebagai sukses . Jika variabel yang dikirimkan adalah 0 maka tidak ada yang dilakukan dan pernyataan ditandai sebagai kegagalan .Misalnya saja programnya
i malamute p malamute d malamute #success p malamute d malamute #failure p malamute d akita #failure p akita
akan menghasilkan
malamute = 1 malamute = 0 malamute = 0 akita = 0
Perhatikan bahwa pengurangan variabel dengan nilai 0 adalah satu-satunya cara untuk menghasilkan kegagalan .
The alias Pernyataan dan Alias Perintah
The alias perintah memiliki sintaks khusus dan adalah yang paling kuat karena dapat digunakan untuk menentukan perintah baru. Nama perintah alias adalah a
dan pernyataan alias memiliki bentuk:
a [name of new command]
[statement A]
[statement B]
[statement C]
Dimana masing-masing [statement X]
mewakili pernyataan non- alias , yaitu sesuatu dengan formulir [command name] [argument 1] [argument 2] [argument 3] ...
.
Nama perintah alias [name of new command]
mungkin berupa string alfanumerik dan garis bawah yang tidak kosong yang tidak dimulai dengan digit - [a-zA-Z_][0-9a-zA-Z_]*
dalam regex.
(Ini adalah kumpulan nama yang sama dengan variabel tetapi perintah dan variabel yang berbeda adalah hal yang berbeda yang digunakan di tempat yang berbeda . Suatu variabel dapat dinamai sama sebagai perintah tanpa konsekuensi buruk.)
Ketika pernyataan alias dijalankan, perintah baru ditambahkan di samping empat p
i
d
a
perintah asli. Perintah baru dapat digunakan sebagai [command name]
pernyataan dalam dan dipanggil dengan argumen seperti halnya perintah non- alias lainnya .
Ketika pernyataan dengan nama perintah alias dijalankan, tepat dua pernyataan lagi dari pernyataan alias aslinya dijalankan:
[statement A]
selalu dijalankan[statement B]
Dijalankan jika[statement A]
sudah sukses[statement C]
dijalankan jika[statement A]
sebuah kegagalan
Pernyataan A, B, dan C selalu dijalankan dengan malas , yaitu mereka dievaluasi dengan cepat pada saat dijalankan.
Ketika selesai dieksekusi, perintah alias ditandai dengan flag sukses atau gagal yang sama dengan pernyataan B atau C, mana pun yang dieksekusi . ( alias pernyataan itu sendiri tidak perlu ditandai karena tidak dapat muncul di dalam dirinya sendiri.)
Contoh Alias 1
Katakanlah kita menginginkan perintah baru yang menambah variabel
frog
dua kali. Pernyataan alias ini membuatnya:a increment_frog_twice i frog i frog d frog
Pernyataan A (
i frog
) selalu dijalankan dan selalu ditandai sebagai keberhasilan sehingga pernyataan B (i frog
) juga selalu dijalankan dan variabelnyafrog
bertambah dengan 2.increment_frog_twice
Perintah selalu ditandai sebagai keberhasilan karena pernyataan B selalu dijalankan dan B selalu merupakan sukses . Pernyataan C (d frog
) tidak pernah dijalankan.Jadi output untuk
a increment_frog_twice i frog i frog d frog p frog increment_frog_twice p frog
akan menjadi
frog = 0 frog = 2
Kita dapat menggeneralisasi contoh ini sehingga variabel apa pun dapat ditambahkan dua kali dengan memberikan perintah alias argumen.
Dalam pernyataan alias , bilangan bulat positif 1, 2, 3, dll. Mewakili argumen 1, 2, 3, dll. Diteruskan ke perintah alias. (Argumen ini mungkin variabel biasa atau referensi ke variabel itu sendiri.) Angka-angka ini hanya dapat muncul dalam argumen pernyataan A, B, dan C dalam pernyataan alias . Tidak masuk akal bagi mereka untuk muncul di tempat lain.
Contoh Alias 2
Ini menggeneralisasi contoh terakhir - variabel apa pun yang dilewatkan
increment_twice
akan ditambahkan oleh 2 karena1
merupakan referensi ke argumen pertama yang dilewatkan dalam:a increment_twice i 1 i 1 d 1 #never reached p toad increment_twice toad p toad
Output dari program ini adalah
toad = 0 toad = 2
Kami kemudian dapat alias perintah lain yang mengambil dua argumen dan memanggil
increment_twice
keduanya:a increment_twice i 1 i 1 d 1 #never reached a increment_both_twice increment_twice 1 increment_twice 2 d 1 #never reached increment_both_twice platypus duck p platypus p duck
Outputnya di sini adalah
platypus = 2 duck = 2
Sangat penting untuk menyadari bahwa perintah alias dapat bersifat rekursif, karena di sinilah letak kekuatan mereka yang sebenarnya. Sebagai contoh, kita dapat membuat perintah yang menetapkan variabel apa pun yang diteruskan ke 0:
Contoh Alias 3
The
set_to_zero
perintah mengambil satu argumen dan menetapkan variabel untuk 0 dan ditandai sebagai keberhasilan bila dilakukan:a set_to_zero d 1 set_to_zero 1 i _dummy_ i oryx i oryx i oryx p oryx set_to_zero oryx p oryx
Output dari program ini adalah
oryx = 3 oryx = 0
Apa yang terjadi adalah ketika
set_to_zero oryx
dijalankan,d 1
berhasil mengurangioryx
dari 3 ke 2, kemudianset_to_zero 1
dipanggil, yang sama dengan meneleponset_to_zero oryx
lagi. Jadi mengulangi proses sampaid 1
adalah kegagalan , menghentikan rekursi dan kenaikan_dummy_
variabel sehingga sukses diproduksi.
Tantangan
Tulis program yang dapat menjalankan kode Prindeal persis seperti yang dijelaskan di atas. Ambil kode Prindeal melalui stdin, baris perintah, atau sebagai file teks. Cetak output program Prindeal ke stdout atau alternatif terdekat bahasa Anda.
Atau, Anda dapat menulis fungsi yang mengambil kode sebagai string dan mencetak atau mengembalikan string output.
Selain itu, Anda dapat mengasumsikan bahwa:
- Kode Prindeal input hanya akan berisi baris baru dan ASCII yang dapat dicetak dan (secara opsional) berakhir dengan baris kosong.
- Kode input akan valid Prindeal - terbentuk dengan baik dan secara sintaksis benar.
- Menjalankan kode tidak akan menghasilkan loop tak terbatas atau referensi yang tidak valid untuk perintah yang belum didefinisikan atau argumen yang belum diberikan.
- Nama perintah
p
,i
,d
, dana
tidak akan pernah alias lebih. (Anda mungkin tidak berasumsi bahwa variabel tidak akan memiliki nama-nama ini.)
Juga, tidak masalah jika nilai variabel Anda tidak benar-benar bilangan bulat presisi arbitrer karena hanya angka kurang dari sekitar 1000 yang akan diuji. Tidak masalah jika bahasa Anda memiliki batas rekursi (seperti Python ) yang mungkin dihadapi oleh program Prindeal yang lebih kompleks selama program pengujian di bawah ini berfungsi.
Program Tes
Berikut ini adalah program Prindeal besar yang membangun operasi penambahan, perkalian, dan eksponensial melalui penggunaan variabel dummy (dimulai dengan _
konvensi) dan banyak alias penolong:
#Command Definitions:
a s #flag as a success
i _
d _
d _
a f #flag as a failure
d _
d _
d _
a z #1 = zero
d 1
z 1
s
a n #1 = one
z 1
i 1
s
a move #2 += 1, 1 = zero
moveH 1 2
move 1 2
s
a moveH #move helper
d 1
i 2
f
a dupe #2 += 1, 3 += 1, 1 = zero
dupeH1 1 2 3
dupe 1 2 3
s
a dupeH1 #dupe helper
d 1
dupeH2 2 3
f
a dupeH2 #dupe helper
i 1
i 2
s
a copy #2 = 1
z 2
copyH 1 2
s
a copyH #copy helper
dupe 1 2 _copy
move _copy 1
s
a addTo #1 += 2
copy 2 _add
#testing comments #
move _add 1#in weird places # just because #
s
#it's a g##d idea
###
a add #1 = 2 + 3
#its a good idea
z 1
addH 1 2 3
s
##
#
a addH #add helper
#this is a comment
addTo 1 2 #as is this
addTo 1 3
s
a mul #1 = 2 * 3
mulH1 1 2
mulH2 1 3
s
a mulH1 #mul helper
z 1
copy 2 _mul
s
a mulH2 #mul helper
mulH3 1 2
mulH2 1 2
s
a mulH3 #mul helper
d _mul
addTo 1 2
f
a mulBy #1 *= 2
mul _mulBy 1 2
copy _mulBy 1
s
a pow #1 = 2^3
powH1 1 3
powH2 1 2
s
a powH1 #pow helper
n 1
copy 2 _pow
s
a powH2 #pow helper
powH3 1 2
powH2 1 2
s
a powH3 #pow helper
d _pow
mulBy 1 2
f
#Running Tests:
p A
p B
p C
n A #A = 1
n B #B = 1
add C A B #C = A + B = 1 + 1 = 2
p ____
p A
p B
p C
add B A C #B = A + C = 1 + 2 = 3
p ____
p A
p B
p C
mul d B C #d = B * C = 3 * 2 = 6
p ____
p d
mulBy d B #d = d * B = 6 * 3 = 18
p ____
p d
d A #A = A - 1 = 1 - 1 = 0
mulBy d A #d = d * A = 18 * 0 = 0
p ____
p d
pow A C B #A = C ^ B = 2 ^ 3 = 8
p ____
p A
p B
p C
pow A B C #A = B ^ C = 3 ^ 2 = 9
p ____
p A
p B
p C
pow C A B #C = A ^ B = 9 ^ 3 = 729
p ____
p A
p B
p C
(Jika Anda bermain-main dengan kode ini, sadarilah bahwa banyak perintah akan gagal jika variabel yang sama diberikan beberapa kali sebagai argumen. Ini dapat dengan mudah diperbaiki tetapi kode yang dihasilkan lebih panjang.)
Penerjemah Prindeal Anda harus dapat menghasilkan output yang tepat:
A = 0
B = 0
C = 0
____ = 0
A = 1
B = 1
C = 2
____ = 0
A = 1
B = 3
C = 2
____ = 0
d = 6
____ = 0
d = 18
____ = 0
d = 0
____ = 0
A = 8
B = 3
C = 2
____ = 0
A = 9
B = 3
C = 2
____ = 0
A = 9
B = 3
C = 729
Mencetak gol
Kode terpendek dalam byte menang. Tiebreak pergi ke pengiriman sebelumnya.
Brownie Bonus: Tulis program keren di Prindeal. Saya menerapkan penambahan dan perkalian, bisakah Anda melakukan pengurangan atau pembagian?
p
, lalup p
, mana yang akan mencetak 1, kan?