Lua, 562 535 529 513 507 504 466 458 byte
Cho đến nay, môn golf khổng lồ nhất của tôi vào lúc này, tôi nghĩ rằng tôi vẫn có thể cắt được 100 byte, điều mà tôi sẽ làm, nhưng đăng nó như một câu trả lời vì nó đã mất một thời gian :). Tôi đã đúng, tôi đã cắt giảm hơn 100 byte! Tôi không nghĩ có nhiều chỗ để cải thiện.
hàm này phải được gọi với một mảng 2D chứa một ký tự cho mỗi ô.
Đã lưu 40 byte khi làm việc với @KennyLau , nhờ anh ấy!
Woohoo! Dưới 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
Ung dung
Giải thích sẽ đến sau khi tôi chơi golf xong, hiện tại, tôi sẽ cho bạn mượn phiên bản có thể đọc được của mã nguồn này: D Đây là phần giải thích!
Chỉnh sửa: không cập nhật với sửa đổi mới nhất, vẫn chơi golf trước khi cập nhật. Giải thích tương tự
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
Vì vậy, đây là một số giải thích chi tiết về cách thức hoạt động của chương trình này.
Trước hết, hãy xem xét vòng lặp có nhãn a
, nó cho phép chúng ta tìm điểm cuối gần nhất với góc trên cùng bên trái. Nó sẽ lặp lại mãi mãi nếu không có kết thúc, nhưng đó không phải là vấn đề: D.
Trên lưới 4 x 4, đây là khoảng cách con rắn (trái) và thứ tự chúng được nhìn (phải)
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
Đối với mỗi nhân vật này, để kết thúc, nó phải kiểm tra hai điều kiện: - Không phải là khoảng trắng - Được bao quanh bởi chính xác 3 khoảng trắng (hoặc chính xác là 1 khoảng trắng)
Những điều kiện này được kiểm tra đoạn mã sau
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...
Kiểm tra nếu char không phải là một khoảng trắng đạt được bằng biểu thức m[i][j]~=s
.
Kiểm tra xem có bị bao quanh bởi 1 không gian không gian hay không bằng cách sử dụng các điều kiện trên cho xung quanh chúng ta, điều này có thể được viết là
m[i+1][j]~=" " ⊕ m[i][j+1]~=" " ⊕ m[i-1][j]~=" " ⊕ m[i][j-1]~=" "
Và cuối cùng, nếu tất cả những điều trên được đánh giá là đúng, thì chim nhạn sẽ trả lại những gì cuối cùng and
-> m[i][j]
. Khác, chúng ta hãy r
bỏ chọn :)
Bây giờ chúng ta có đầu của con rắn, chúng ta hãy đi hết đầu kia! Lặp lại con rắn chủ yếu đạt được bởi các chim nhạn lồng nhau sau đây:
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
Chúng tôi thiết lập lại i
và j
đồng thời để tránh cần người giả lưu trữ các giá trị cũ Cả hai đều có cùng cấu trúc và sử dụng các điều kiện đơn giản, vì vậy tôi sẽ trình bày chúng ở dạng lồng nhau if
, nó sẽ cho phép bạn đọc chúng dễ dàng hơn. :)
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
Có thể được dịch thành:
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
Kiểm tra nó!
Đây là mã tôi sử dụng để chạy mã này, bạn có thể kiểm tra mã trực tuyến bằng cách sao chép mã.
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)