Lua, 562 535 529 513 507 504 466 458 Bytes
Mein derzeit mit Abstand massivstes Golfspiel, ich denke, ich kann immer noch 100 Bytes abschneiden, worauf ich hinarbeiten werde, aber es als Antwort posten, da es schon einige Zeit gedauert hat :). Ich hatte recht, ich habe mehr als 100 Bytes gekürzt! Ich denke nicht, dass es viel Raum für Verbesserungen gibt.
Diese Funktion muss mit einem 2D-Array aufgerufen werden, das ein Zeichen pro Zelle enthält.
40 Bytes bei der Arbeit mit @KennyLau gespart , dank ihm!
Woohoo! Unter 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
Ungolfed
Sobald ich mit dem Golfen fertig bin, werden Erklärungen folgen. Im Moment leihe ich Ihnen eine lesbare Version dieses Quellcodes: D Hier kommen die Erklärungen!
Bearbeiten: nicht mit der neuesten Änderung aktualisiert, noch vor dem Aktualisieren golfen. Gleiches gilt für die Erklärungen
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
Hier finden Sie einige detaillierte Erklärungen zur Funktionsweise dieses Programms.
Betrachten wir zunächst die Schleife mit der Bezeichnung a
, damit wir das nächste Ende in der oberen linken Ecke finden können. Es wird für immer wiederholt, wenn es kein Ende gibt, aber das ist kein Problem: D.
Auf einem 4x4-Gitter sind hier die Schlangenabstände (links) und die Reihenfolge, in der sie betrachtet werden (rechts).
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
Damit jedes dieser Zeichen das Ende ist, müssen zwei Bedingungen überprüft werden: - Kein Leerzeichen - Umgeben von genau 3 Leerzeichen (oder genau 1 Nicht-Leerzeichen)
Diese Bedingungen werden im folgenden Code überprüft
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...
Durch den Ausdruck wird überprüft, ob das Zeichen kein Leerzeichen ist m[i][j]~=s
.
Wenn Sie überprüfen, ob nur 1 Nicht-Leerzeichen vorhanden ist, indem Sie die obigen Bedingungen für unsere Umgebung angeben, kann dies folgendermaßen geschrieben werden
m[i+1][j]~=" " ⊕ m[i][j+1]~=" " ⊕ m[i-1][j]~=" " ⊕ m[i][j-1]~=" "
Und schließlich, wenn alle oben genannten Werte als wahr ausgewertet werden, gibt der Ternär das zurück, was in der letzten and
-> steht m[i][j]
. Sonst lassen wir los r
:)
Jetzt, wo wir den Schlangenkopf haben, gehen wir zum anderen Ende! Das Iterieren der Schlange wird hauptsächlich durch die folgenden geschachtelten Ternaries erreicht:
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
Wir werden zurückgesetzt i
und j
zur gleichen Zeit, um zu vermeiden, dass Dummies zum Speichern der alten Werte benötigt werden. Beide haben die exakt gleiche Struktur und verwenden einfache Bedingungen. Deshalb werde ich sie in Form von verschachtelten präsentieren if
, damit Sie sie lesen können noch einfacher. :)
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
Kann übersetzt werden in:
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
Probier es aus!
Hier ist der Code, den ich verwende, um dies auszuführen. Sie können ihn online testen, indem Sie ihn kopieren und einfügen.
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)