Roguelike mencari jalan
Tugas Anda akan, diberikan array dua dimensi dari elemen yang dijelaskan di bawah ini, yang mewakili ruang bawah tanah, untuk menghasilkan atau mengembalikan nomor tunggal yang mewakili jumlah keping emas yang dapat dikumpulkan oleh penjahat tanpa membangunkan monster apa pun.
Elemen-elemen array adalah sebagai berikut:
- Ruang kosong diwakili oleh salah satu
.
atau satu ruang, panggilan Anda; - Posisi awal Rogue diwakili oleh, tentu saja
@
,; - Sepotong emas diwakili oleh
$
; - Dinding diwakili oleh
#
; - Monster diwakili oleh karakter dari regexp berikut:
[a-zA-Z*&]
.
Array tidak boleh mengandung karakter apa pun yang tidak tercantum di atas, sehingga Anda dapat mengasumsikan bahwa apa pun yang bukan dinding, ruang kosong, bajingan, atau keping emas adalah monster.
Aturan untuk merintis jalan adalah:
- Si nakal hanya bisa berjalan melalui sel-sel kosong atau sel-sel yang mengandung emas;
- Dibutuhkan belokan untuk bergerak ke sel yang berdekatan atau berdekatan secara diagonal;
- Mengambil emas itu instan;
- Si nakal tidak bisa tetap berdekatan atau berdekatan secara diagonal dengan monster selama lebih dari satu putaran tanpa membangunkannya, yang dilarang;
- Si nakal dapat memasuki area kesadaran monster beberapa kali, monster itu hanya akan bangun jika si nakal menghabiskan dua putaran berturut-turut di dekatnya.
Aturan input dan output
Anda bisa mendapatkan input dalam format apa pun yang masuk akal, termasuk array dua dimensi, array datar, string, atau apa pun. Jika itu membuat hidup Anda lebih mudah, Anda juga dapat mengambil dimensi array.
Dijamin bajingan itu tidak akan berada di dekat monster di awal.
Program atau fungsi lengkap tidak masalah.
Mencetak gol
Ini adalah kode-golf , skornya adalah jumlah byte dari kiriman Anda dengan lebih sedikit yang lebih baik.
Uji kasus
Saya menggunakan titik-titik untuk ruang kosong di sini untuk tujuan keterbacaan, jika Anda ingin Anda dapat menggunakan spasi (lihat di atas). Perhatikan juga bahwa ini adalah kebetulan murni bahwa bajingan itu selalu berada di sudut kiri atas, kode Anda harus menangani posisi valid lainnya juga.
1)
@..
.$.
... -> 1
Hanya tes kewarasan.
2)
@....
...g$
..... -> 0
Sekali lagi, tes kewarasan.
3)
@....
...$g
..... -> 1
Si nakal dapat mengambil emas dengan bergerak dari kiri.
4)
@....g..
.......$
........
.....h.. -> 1
Si bajingan dapat berzigzag di antara para monster, tidak pernah tinggal lebih dari satu belokan di dekat masing-masing monster.
5)
@....z..
.......$
.....b.. -> 0
Taktik dari test case sebelumnya tidak berfungsi di sini - area sensitivitas monster tumpang tindih.
6)
@$#.
###$
.... -> 1
Tes kewarasan.
7)
@..#..
$.$g.$
...#.. -> 2
Dito.
8)
@#.d#$
$...##
e.....
..$...
##..$b
.#..g$ -> 3
Dari semua emas di sini, hanya tiga yang dapat dicapai dengan aman: emas di dekat posisi awal dapat diperoleh dengan memindahkan satu dan kemudian kembali ke posisi awal. Untuk melarikan diri dari sudut kiri atas bajingan harus bergerak secara diagonal ke kanan bawah dua kali. Emas di tengah tidak menimbulkan tantangan. Emas terluar dijaga oleh g
dan b
bisa didapat dengan bergerak secara diagonal dari tempat ke kanan emas tengah dan kemudian kembali. Sisanya tidak dapat diperoleh: emas kanan atas diblokir oleh dinding, dan emas kanan bawah membutuhkan dua belokan di area sensitivitas monster.
Kasus uji berikut ini disumbangkan dengan murah hati oleh mbomb007.
9)
12345678
a @....g.D
b .......$
c ......#.
d .....h.. -> 1
Yang ini rumit. Sebuah jalan adalah b4-b5-c6-b7-c8-b8(grab)
.
10)
12345678
a @....g.D
b .......$
c .......#
d .....h.. -> 1
Sebuah jalan adalah [bc]4-c5-b6-c7-b8(grab)
.
11)
12345678
a @....g.D
b ......#$
c .......#
d .....h.. -> 1
Dinding ekstra tidak benar-benar mengubah apa pun, [bc]4-c5-b6-c7-b8(grab)
masih merupakan solusi.
sumber
@
input yang valid?Jawaban:
solusi sebelumnya (sebagian dari mereka) dapat ditemukan di wadah footer di tautan tio (itu mungkin lebih mudah dibaca)
JavaScript (Node.js) ,
883436411360.345311 byteCobalah online!
Penjelasan -
alih-alih beralih dari pemain ke uang tunai, saya beralih dari kasing ke @. saya pikir saya harus lebih cepat karena saya tahu kapan harus berhenti mencari (mencapai @), dan ketika Anda mencari uang tunai Anda harus selalu bergerak sampai Anda menutupi semua tempat (dan cara untuk sampai ke sana). jadi algo cukup sederhana seperti itu - fungsi utama
g.map((r,y)=>[...r].map((c,x)=>A+=c=="$"&&P(g,x,y)),A=0)|A
: cari uang tunai -> jika Anda menemukannya -> mulai mencari pemain -> jika Anda menemukannya -> kenaikan A sekarang mari kita ke path finder alias Pif(/[.$]/.test(c=(g[y]||[])[x]))
hanya periksa apakah sel saat ini adalah "spesial" -> jika demikian kami ingin kembali jika ini adalah pemain. kasus khusus: @ # (monster)for(;i--;) if(/^[a-zA-Z*&]$/.test(C=(g[y+~-(i/3)]||0)[x+i%3-1])) -> if my neighbor is a monster {if(m[C])return false -> and it already was in the previous turn - this path is not value M[C]=1} -> if not just add it to the neighbors monsters
for(;I--;) if(!p[(X=x+~-(I / 3))+","+(Y=y+I%3-1)]&&P(g,X,Y,M,{...p,[x+","+y]:1}))return true
beralih kembali ke tetangga - jika saya belum ada di sana (p adalah jalur yang diambil) lanjutkan jalan (panggilan P)sumber
I / 3
memiliki ruang yang tidak perlu. Hilangkan ruang putih itu dan skor Anda sebenarnya324
! (2)return true
dapat menjadireturn 1
(nilai yang benar) danreturn false
dapat secara sederhanareturn
(tersiratundefined
, nilai yang palsu). (3) Regex^[^.@$#]$
untuk memeriksa tidak ada monster lebih pendek daripada^[a-zA-Z*&]$
memeriksa monster. Kerja bagus!