Lua, 562 535 529 513 507 504 466 458 Bytes
Sejauh ini golf terbesar saya , saya pikir saya masih bisa memotong 100 byte, yang akan saya upayakan, tetapi mempostingnya sebagai jawaban karena sudah memakan waktu :). Saya benar, saya telah mengurangi lebih dari 100 byte! Saya tidak berpikir ada banyak ruang untuk perbaikan.
fungsi ini harus dipanggil dengan array 2D yang mengandung satu karakter per sel.
Disimpan 40 byte saat bekerja dengan @ KennyLau , terima kasih padanya!
Woo hoo! Di bawah 500!
function f(m)t=2u=1i=1j=1s=" "::a::if s~=m[i][j]and(i<#m and m[i+1][j]~=s)~=(j<#m[i]and m[i][j+1]~=s)~=(i>1 and m[i-1][j]~=s)~=(j>1 and m[i][j-1]~=s)then goto b end
i,t=i%t+1,#m>t and t==i and t+1or t j=j>1 and j-1or u u=u<#m[1]and j==1 and u+1or u goto a::b::io.write(m[i][j])m[i][j]=s
i,j=i<#m and s~=m[i+1][j]and i+1or i>1 and s~=m[i-1][j]and i-1or i,j<#m[i]and s~=m[i][j+1]and j+1or j>1 and s~=m[i][j-1]and j-1or j
if s==m[i][j]then return end goto b end
Tidak disatukan
Penjelasan akan datang setelah saya selesai bermain golf ini, untuk saat ini, saya akan meminjamkan Anda versi yang dapat dibaca dari kode sumber ini: D Inilah penjelasannya!
Sunting: tidak diperbarui dengan modifikasi terbaru, masih bermain golf sebelum memperbarui. Sama halnya dengan penjelasan
function f(m) -- declare the function f which takes a matrix of characters
t=2 -- initialise the treshold for i
-- when looking for the first end of the snake
u=1 -- same thing for j
i,j=1,1 -- initialise i and j,our position in the matrix
s=" " -- shorthand for a space
::a:: -- label a, start of an infinite loop
if m[i][j]~=s -- check if the current character isn't a space
and(i<#m -- and weither it is surrounded by exactly
and m[i+1][j]~=s) -- 3 spaces or not
~=(j<#m[i]
and m[i][j+1]~=s) -- (more explanations below)
~=(i>1
and m[i-1][j]~=s)
~=(j>1
and m[i][j-1]~=s)
then goto b end -- if it is, go to the label b, we found the head
i,t= -- at the same time
i%t+1, -- increment i
#m>t and t==i and t+1or t -- if we checked all chars in the current range, t++
j=j>1 and j-1or u -- decrement j
u=u>#m[1]and j==1 and u+1or u-- if we checked all chars in the current range, u++
goto a -- loop back to label a
::b:: -- label b, start of infinite loop
io.write(m[i][j]) -- output the current char
m[i][j]=s -- and set it to a space
i,j=i<#m -- change i and j to find the next character in the snake
and m[i+1][j]~=s -- this nested ternary is also explained below
and i+1 -- as it takes a lot of lines in comment ^^'
or i>1
and m[i-1][j]~=s
and i-1
or i,
j<#m[i]
and m[i][j+1]~=s
and j+1
or j>1
and m[i][j-1]~=s
and j-1
or j
if m[i][j]==s -- if the new char is a space
then -- it means we finished
return -- exit properly to avoid infinite
end -- printing of spaces
goto b -- else, loop back to label b
end
Jadi, inilah beberapa penjelasan terperinci tentang cara kerja program ini.
Pertama-tama, mari kita perhatikan loop berlabel a
, ini memungkinkan kita untuk menemukan ujung terdekat ke sudut kiri atas. Ini akan berulang selamanya jika tidak ada akhirnya, tapi itu tidak masalah: D.
Pada kotak 4x4, di sini adalah jarak ular (kiri), dan urutan mereka melihat (kanan)
1 2 3 4 | 1 2 4 7
2 3 4 5 | 3 5 8 11
3 4 5 6 | 6 9 12 14
4 5 6 7 | 10 13 15 16
Untuk setiap karakter ini, untuk menjadi yang terakhir, ia harus memeriksa dua kondisi: - Tidak menjadi ruang - Dikelilingi oleh tepat 3 ruang (atau tepat 1 non-ruang)
Kondisi-kondisi ini diperiksa bagian kode berikut
r=m[i][j]~=s
and(i<#m and m[i+1][j]~=s)
==not(j<#m[i] and m[i][j+1]~=s)
==not(i-1>0 and m[i-1][j]~=s)
==not(j-1>0 and m[i][j-1]~=s)
and m[i][j]
or r
-- special note: "==not" is used as an equivalent to xor
-- as Lua doesn't know what is a xor...
Memeriksa apakah char bukan spasi dicapai oleh ekspresi m[i][j]~=s
.
Memeriksa apakah kita hanya dikelilingi oleh 1 non-ruang dicapai dengan xor-ing kondisi di atas untuk sekitar kita, ini dapat ditulis sebagai
m[i+1][j]~=" " ⊕ m[i][j+1]~=" " ⊕ m[i-1][j]~=" " ⊕ m[i][j-1]~=" "
Dan akhirnya, jika semua hal di atas dievaluasi dengan benar, ternary akan mengembalikan apa yang ada di terakhir and
-> m[i][j]
. Lain, kita biarkan r
tidak disetel :)
Sekarang kita memiliki kepala ular, mari kita lanjutkan ke ujung yang lain! Iterasi ular terutama dicapai oleh terner bersarang berikut:
i,j=i<#m and m[i+1][j]~=s and i+1or i-1>0 and m[i-1][j]~=s and i-1or i,
j<#m[i]and m[i][j+1]~=s and j+1or j-1>0 and m[i][j-1]~=s and j-1or j
Kami mengatur ulang i
dan j
pada saat yang sama untuk menghindari kebutuhan boneka untuk menyimpan nilai-nilai lama. Mereka berdua memiliki struktur yang sama persis, dan menggunakan kondisi sederhana, jadi saya akan menyajikannya dalam bentuk bersarang if
, sehingga Anda dapat membacanya lebih mudah. :)
i=i<#m and m[i+1][j]~=s and i+1or i-1>0 and m[i-1][j]~=s and i-1or i
Dapat diterjemahkan ke:
if(i<#m)
then
if(m[i+1][j]~=" ")
then
i=i+1
end
elseif(i-1>0)
then
if(m[i-1][j]~=" ")
then
i=i-1
end
end
Menguji!
Berikut kode yang saya gunakan untuk menjalankan ini, Anda dapat mengujinya secara online dengan menyalin-menempelnya.
function f(m)t=2u=1i=1j=1s=" "::a::if s~=m[i][j]and(i<#m and m[i+1][j]~=s)~=(j<#m[i]and m[i][j+1]~=s)~=(i>1 and m[i-1][j]~=s)~=(j>1 and m[i][j-1]~=s)then goto b end
i,t=i%t+1,#m>t and t==i and t+1or t j=j>1 and j-1or u u=u<#m[1]and j==1 and u+1or u goto a::b::io.write(m[i][j])m[i][j]=s
i,j=i<#m and s~=m[i+1][j]and i+1or i>1 and s~=m[i-1][j]and i-1or i,j<#m[i]and s~=m[i][j+1]and j+1or j>1 and s~=m[i][j-1]and j-1or j
if s==m[i][j]then return end goto b end
test1={}
s1={
" tSyrep ",
" r p ",
" in Sli ",
" g Sile",
" Snakes n",
"Ser ylt",
"a eh ilS ",
"fe w t ",
" emo h ",
" Sre ",
}
for i=1,#s1
do
test1[i]={}
s1[i]:gsub(".",function(c)test1[i][#test1[i]+1]=c end)
end
f(test1)