Lua, 562 535 529 513 507 504 466 458 Bayt
Şu ana kadarki en büyük golf oyunuma kadar , hala çalışacağım 100 baytı kesebileceğimi düşünüyorum, fakat bunu zaten biraz zaman aldı gibi bir cevap olarak gönderiyorum :). Haklıydım, 100 bayttan fazla veri kesdim! İyileştirilecek çok yer olduğunu sanmıyorum.
bu fonksiyon hücre başına bir karakter içeren bir 2D dizi ile çağrılmalıdır.
@KennyLau ile çalışırken 40 byte kurtarıldı , onun için teşekkürler!
Bravo! 500'ün altında!
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
Ungolfed
Açıklamalar bir kere golf oynamayı bitirdikten sonra gelecek, şimdilik, size bu kaynak kodun okunabilir bir versiyonunu ödünç vereceğim: D İşte açıklamalar!
Düzenleme: en son değişikliklerle güncellenmedi, güncellemeden önce hala golf. Aynı açıklamalar için de geçerli
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
İşte bu programın nasıl çalıştığı hakkında bazı ayrıntılı açıklamalar geliyor.
Öncelikle, etiketli döngüyü düşünelim, asol üst köşeye en yakın ucu bulmamıza izin veriyor. Sonu yoksa sonsuza dek döngüde kalacaktır, ancak bu bir problem değil: D.
4x4 ızgarada, burada yılan mesafeleri (solda) ve bakılma sırası (sağda).
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
Bu karakterin her biri için, son olarak, iki koşulu kontrol etmek zorundadır: - Boşluk olmamak - Tam olarak 3 boşlukla (veya tam olarak 1 boşluksuz) çevrelenmek
Bu koşullar aşağıdaki kod parçasını kontrol eder
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...
Karakterin boşluk olup olmadığını kontrol etmek, ifade ile sağlanır m[i][j]~=s.
W'nin sadece 1 boşluksuz tarafından çevrilip çevrilmediğini kontrol etmek, çevremiz için yukarıdaki şartları yerine getirerek sağlanır;
m[i+1][j]~=" " ⊕ m[i][j+1]~=" " ⊕ m[i-1][j]~=" " ⊕ m[i][j-1]~=" "
Ve son olarak, yukarıdakilerin tümü doğru olarak değerlendirilirse, üçlü sondakileri geri döndürür and-> m[i][j]. Aksi takdirde, izin vermeyelim r:)
Şimdi yılanın başı bizde, hadi sonuna kadar gidelim! Yılanı yinelemek esas olarak şu iç içe geçmiş üçlüler tarafından sağlanır:
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
Eski değerleri saklamak için aptallara ihtiyaç duymamak için yeniden ayarladık ive jaynı anda hem yapıya sahipler, hem de basit koşullar kullanıyorlar, bu yüzden bunları iç içe şeklinde sunacağım, bunları ifokumanıza izin vermeli daha kolayca. :)
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
Çevrilebilir:
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
Dene!
İşte bunu çalıştırmak için kullandığım kod, çevrimiçi kopyalayıp yapıştırarak test edebilirsiniz .
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)