Tugas Anda adalah menulis juru bahasa RoboZZle. Jika Anda tidak terbiasa dengan permainan, silakan menonton video di robozzle.com atau baca deskripsi saya di bawah ini.
Robot tinggal di kotak persegi panjang berwarna merah, hijau, biru, atau hitam. Kotak hitam tidak dapat diakses. Yang lain dapat diakses dan beberapa di antaranya berisi bintang. Tujuannya adalah untuk mengumpulkan semua bintang tanpa menginjak kotak hitam atau jatuh dari peta. Robot menempati satu kotak dan menghadap ke arah tertentu - kiri, kanan, atas, atau bawah. Ini mengikuti instruksi seperti perakitan yang dikelompokkan ke dalam subrutin F1, F2, ..., F5. Instruksi adalah sepasang predikat ("tidak ada", "jika pada warna merah", "jika pada warna hijau", "jika pada warna biru") dan sebuah tindakan ("maju", "belok kiri", "belok kanan", "belok kanan", "cat merah kotak saat ini", "cat hijau", "cat biru", "jangan apa-apa", "sebut F1", ..., "panggil F5"). Panggilan ke subrutin menggunakan tumpukan dan bisa bersifat rekursif. Sama seperti dalam pemrograman konvensional, setelah instruksi terakhir dari sebuah subrutin selesai, eksekusi berlanjut dari titik di mana subrutin itu dipanggil. Eksekusi dimulai dari instruksi pertama F1 dan berlanjut sampai robot mengunjungi semua kotak dengan bintang, atau ketika robot menginjak kotak hitam atau di luar peta, atau 1000 instruksi telah dieksekusi (predikat gagal dan tindakan "tidak melakukan apa-apa") tidak masuk hitungan), atau tidak ada instruksi lagi untuk dieksekusi (stack underflow).
Input:
a
- matriks karakter 12x16 (seperti biasanya direpresentasikan dalam bahasa Anda, mis. array string) yang menyandikan peta -'#'
untuk kotak yang tidak dapat diakses (hitam),'*'
untuk kotak dengan bintang,'.'
untuk sisanyac
- matriks karakter 12x16 yang menggambarkan warna kotak yang dapat diakses -'R'
(merah),'G'
(hijau), atau'B'
(biru). Kotak yang tidak dapat diakses akan diwakili oleh surat arbitrer dari ketiganya.y
danx
- baris dan kolom berbasis 0 robot;a[y][x]
dijamin'.'
d
- arah robot ini menghadap:0 1 2 3
untuk kanan, bawah, kiri, atas, yaitu ke arah(y,x+1)
,(y+1,x)
,(y,x-1)
,(y-1,x)
f
- string tunggal, implementasi gabungan dari F1 ... F5. Setiap implementasi adalah urutan (kemungkinan kosong) dari pasangan tindakan predikat (paling banyak 10 pasang per subrutin), diakhiri dengan'|'
.predikat:
'_'
tidak ada,'r'
merah,'g'
hijau,'b'
birutindakan:
'F'
maju,'L'
belok kiri,'R'
belok kanan,'r'
cat merah,'g'
cat hijau,'b'
cat biru,'1'
panggil F1, ...,'5'
panggil F5,'_'
jangan lakukan apa-apa
Anda tidak harus memberi nama input seperti di atas, tetapi nilainya harus seperti yang ditentukan.
Keluaran: 1
(atau true
) jika robot mengumpulkan semua bintang sesuai dengan aturan, 0
( false
) jika tidak.
Contoh :
a=["################","################","##*....*...*#.##","##.####.#####.##","##.####.#####.##","##.####*...*#.##","##.########.####","##*........*#.##","################","################","################","################"]
c=["RRRRRRRRRRRRRRRR","RRRRRRRRRRRRRRRR","RRRBBBBRGGGGRRRR","RRBRRRRGRRRRRRRR","RRBRRRRGRRRRRRRR","RRBRRRRRGGGBRRRR","RRBRRRRRRRRGRRRR","RRRBBBBGGGGBRBRR","RRRRRRRRRRRRRRRR","RRRRRRRRRRRRRRRR","RRRRRRRRRRRRRRRR","RRRRRRRRRRRRRRRR"]
y=2; x=6; d=2
// and then depending on "f":
f="_FrLg2_1|_FbLrR_2||||" // result:1
f="_FrRg2_1|_FbLrR_2||||" // result:0 (stepped on a black square)
f="_FrLrL_1|_FbLrR_2||||" // result:0 (1000-step limit exceeded)
f="_FrLg2__|________||||" // result:0 (stack underflow)
Contoh lain , yang melibatkan instruksi "cat":
a=["#***************","#*###*###*###*##","#*###*###*###*##","***#***#***#***#","***#***#***#***#","*###*###*###*###","***#***#***#***#","***#***#***#***#","***#***#***#***#","*###*###*###*###","*.*#***#***#***#","***#***#***#***#"]
c=["RGGGGGGGGGGGGGGG","RBRRRGRRRGRRRGRR","RBRRRGRRRGRRRGRR","RBRRGGGRGGGRGGGR","BRRRGGGRGGGRGGGR","BRRRGRRRGRRRGRRR","BRRRGGGRGGGRGGGR","RBRRGGGRGGGRGGGR","BRRRGGGRGGGRGGGR","BRRRGRRRGRRRGRRR","BGRRGGGRGGGRGGGR","RBRRGGGRGGGRGGGR"]
y=10; x=1; d=0
f="_2_R_R_1|_FgRgFgFg3rRr4b2_Fgb|_F_F_R|_2_L_r||"
// result:1
Untuk menghasilkan tes Anda sendiri, buka puzzle dari daftar di robozzle.com , cobalah untuk menyelesaikannya (atau tidak menyelesaikannya), tekan F12 di browser Anda, ketikkan di konsol JS:
r=robozzle;s=JSON.stringify;with(r.level)console.log('a='+s(Items)+'\nc='+s(Colors)+'\ny='+RobotRow+'\nx='+RobotCol+'\nd='+RobotDir+'\nf='+s(r.encodeSolution()))
dan format ulang hasilnya untuk bahasa Anda.
Kemenangan terpendek. Tidak ada celah.
Jawaban:
Prolog (SWI) , 574 byte
Cobalah online!
Ini mendefinisikan predikat bahwa ketika dipanggil berhasil jika semua bintang berhasil dikumpulkan dan gagal sebaliknya. Predikat mengambil argumen seperti:
a+c+f+x^y^d.
.a
danc
harus berupa daftar string yang dikutip backtick, sementaraf
harus berupa string yang dikutip ganda.Penjelasan
Program ini berisi tiga predikat,
*/2
,^/2
, dan+/2
. The*/2
predikat yang didefinisikan pada baris pertama bertanggung jawab untuk bagian dari pengolahan masukan. The^/2
predikat rekursif menghitung berapa bergerak robot langkah demi langkah dan berhasil jika robot secara hukum mengumpulkan semua bintang dan gagal sebaliknya. The+/2
predikat adalah predikat utama dari program ini dan mempersiapkan masukan untuk^/2
predikat dengan beberapa bantuan dari*/2
predikat. Perhatikan bahwa masing-masing predikat ini secara teknis hanya membutuhkan dua argumen tetapi menggunakan operator dan pencocokan pola mereka dapat berperilaku seolah-olah mereka memiliki lebih banyak argumen (saya membahas fenomena ini lebih mendalam di sini ).*/2
Predikat ini membutuhkan dua argumen. Yang pertama adalah daftar daftar kode karakter (ini adalah bagaimana Prolog mem-parsing backtick string yang dikutip). Yang kedua adalah peta asosiatif dari titik-titik dalam peta 12x16 (diwakili sebagai
X^Y
) hingga 32 ditambah kode karakter yang disimpan pada titik itu dalam daftar daftar kode karakter. 32 ditambahkan ke masing-masing kode karakter sehingga untuk matriks warna itu akan mengubah karakter warna huruf besar menjadi karakter warna huruf kecil.Cara melakukannya adalah menghasilkan daftar pasang poin dan kode karakter pada saat itu menggunakan
findall/3
. Kemudian digunakanlist_to_assoc/2
untuk membuat peta asosiatif yang sesuai dari titik ke kode karakter pada titik itu.The
findall/3
predikat adalah builtin sebuah membutuhkan "template" sebagai argumen pertama, gol sebagai argumen kedua dan daftar sebagai argumen ketiga. Predikat mengisi daftar dengan semua nilai yang mungkin dari templat yang menyebabkan tujuan berhasil. Karena didahulukan operator, template yang dilewatkan kefindall/3
dalam*/2
parsing sebagai(X^Y)-D
. The-
Operator merupakan sepasang dua nilai di Prolog sehingga template merupakan lokasi titik ini (X^Y
) dipasangkan dengan kode karakter 32 ditambah titik ini (D
). Perhatikan bahwa yang^
digunakan dalam mewakili titik sama sekali tidak terhubung ke^/2
predikat.Mari kita perhatikan tujuan yang diteruskan ke
findall/3
predikat.Sasaran berisi tiga predikat yang masing-masing perlu berhasil agar sasaran berhasil. The
nth0/3
predikat yang digunakan dua kali digunakan untuk mendapatkan nilai pada indeks tertentu daftar (yang0
dalam namanya menunjukkan itu adalah nol diindeks). Panggilan pertama untuk menyimpanY
baris th dari matriks karakterO
sementara panggilan kedua menyimpanX
karakter th di baris itu diC
. Predikat terakhirplus/3
berhasil jika dua argumen pertamanya sama dengan argumen ketiga. Ini digunakan untuk membuat kode karakter dalam pasangan 32 lebih besar dari kode karakter dalam matriks karakter yang sebagaimana dinyatakan di atas akan mengubah semua huruf besar menjadi huruf kecil.Akhirnya,
findall/3
simpan semuaX^Y-D
kombinasi yang menyebabkan tujuannya berhasil dalam daftar dariL
mana peta asosiatif dibangun.Selebihnya datang segera...
sumber
JavaScript (ES6),
298276264 byteDisimpan 8 byte berkat @ngn
Mengambil input sebagai
(a,c,x,y,d,f)
, di manaa
danc
adalah array dari array karakter. Pengembalian0
atau1
.Uji kasus
Tampilkan cuplikan kode
Berkomentar
sumber
x+='2101'[d&3]-1,y+='1210'[d&3]-1
->d&=3,x+=(1-d)%2,y+=(2-d)%2
x
berubah paling banyak 1, jadi saya pikir Anda dapat menggantix&~15
denganx&16
APL (Dyalog Classic) ,
236233 byte-3 Terima kasih kepada Erik the Outgolfer
Sekarang saya telah memberikan bonus, saya memposting solusi sampel untuk tantangan saya sendiri. Ada ruang untuk perbaikan di sini - jangan ragu untuk menyalin dan golf lebih lanjut.
Cobalah online!
Sama seperti di atas, diperluas dengan komentar:
sumber