¿Qué consejos generales tienes para jugar al golf en Lua? Estoy buscando ideas que se puedan aplicar a los problemas de golf de código en general que sean al menos algo específicos para Lua (por ejemplo, "eliminar comentarios" no es una respuesta). Por favor, publique un consejo por respuesta.
21
Respuestas:
Además de los ya publicados, aquí hay algunos trucos que he reunido con el tiempo, sin ningún orden específico ...
Para las llamadas a funciones que solo tienen un parámetro delimitado por un símbolo (
"
para cadenas,{
para tablas), el parámetro no necesita estar entre paréntesis.Por ejemplo, en lugar de hacerlo
print("hello")
, simplemente puede hacer:print"hello"
Elimine la mayor cantidad de espacio en blanco posible: esto es especialmente fácil de hacer después de un símbolo que cierra cadenas (o antes de una apertura), llamadas a funciones, tablas ...
En lugar de
print(42) a=1
hacerlo, puede hacerloprint(42)a=1
. Otro ejemplo:print(a and-1 or-2)
.¡Usa el operador ternario cuando puedas! En lugar de
if a>0 then print("hello") else print("goodbye") end
, prefieraprint(a>0 and "hello" or "goodbye")
. Más información aquí .(En realidad, esto puede ser aún mejor:
print(a>0 and"hello"or"goodbye")
)Use el azúcar sintáctico de dos puntos cuando pueda: en lugar de
string.rep(str,12)
hacerlostr:rep(12)
. Eso también funciona en no variables de esta manera (y solo de esta manera):("a"):rep(5)
En lugar de hacer
tonumber(str)
solo hazstr+0
Para funciones sin parámetros, en lugar de definirlas de la manera habitual (
function tick() blabla() end
), puede hacer:,ticks=loadstring"blabla()"
que ahorra 1 o más bytes, dependiendo del contenido. Además, si define varias funciones, localiceloadstring
antes una variable de 1 carácter y ahorrará muchos bytes;). Créditos a Jim Bauwens por este truco.Lua considera la cadena vacía (y
0
muy diferente a otros idiomas) como verdadera en las pruebas condicionales, por lo que, por ejemplo, en lugar de hacerlowhile 1 do ... end
, guarde 1 byte escribiendowhile''do ... end
fuente
str+0
equivalente es~~str
, puede ser útil por su precedenciaYa he pensado en uno. No sé si funciona en otros idiomas, pero Lua es el único que sé que le permite almacenar funciones en variables. Entonces, si eg
string.sub
se usa varias veces en su programa, use egs=string.sub
.fuente
s=("").sub
aos=a.sub
para cualquier variable quea
contenga un valor de cadena.Es un lenguaje bastante detallado para el golf ... pero algunos consejos generales que vienen a la mente son:
if
...then
...else
...end
es un desperdicio importante.for i=1,5 do
.#
operador es bastante bueno para jugar al golf (y en general).fuente
Acorta tu ciclo infinito
Cuando tiene que usar un bucle infinito, puede pensar en usar a
while
, pero usar una etiqueta en su lugar es más corto en 2 bytes:Usa el menor espacio posible
Hay una cosa simple que podría (ab) usar para eliminar aún más espacios de su código. Las especificaciones de Lua son claras sobre el nombre que le das a las variables: tienen que comenzar con una letra. Implica que, a veces, puede omitir espacios entre números y funciones / variables
La posibilidad de eliminar el espacio depende de la letra que sigue al número, aquí está la letra que no le permitirá hacer esto:
Al usar esto y prestar atención a cómo llama a sus variables, puede hacer que la mayoría de sus códigos fuente estén libres de espacio.
Tomando un ejemplo que ya está aquí, y siguiendo este consejo, aquí hay un byte más que podría eliminar :).
Use el método de entrada correcto
Si observamos el estándar y el costo de cada tipo principal de entrada, esto es lo que tenemos:
Cada uno de este método nos permite tomar 1 entrada, siendo la función la que tiene el costo más alto (pero nos permite tomar una tabla como entrada)
Ahora podemos ver que usar el argumento de la línea de comandos es el camino a seguir si desea jugar al golf, pero tenga en cuenta: puede ser aún más corto
El
...
son un poco especial en Lua, que es una variable que contiene el contenido descomprimido delarg
o los parámetros descomprimidos en caso de una función variadic.Cuando tenga que obtener más de una entrada y usar cada una de ellas, puede ser bueno guardarlas en una variable. Aquí hay algunas formas de guardar 2 entradas en variables
y aquí están las llamadas más cortas que podrías haber hecho sin las variables:
Desde el punto donde tiene 3 argumentos, o cuando usa 2 argumentos, con uno usado dos veces, ¡ya está ganando bytes debido a
a,b=...
! :)Casi nunca uso si!
Casi no hay casos en los que el uso de una declaración if / elseif / if cueste menos que un ternario. La base para tal afirmación es realmente pesada:
Con un ejemplo simple, ya guarda 12 bytes, cuando tiene que hacer otras cosas, se vuelve cada vez más importante, ¡así que tenga en cuenta eso!
Además, los ternaries en lua son especiales , hay alguna condición en su funcionamiento, para los interesados, lo explicaré a continuación:
Los ternarios en lua son de la forma
<condition> and <case true: have to be a true value> or <case false: can be anything>
En primer lugar, veamos la tabla de verdad de
or
. Aor
se puede considerar como una función: siempre devuelve un valor, aquí está el valor que devuelve:Eso es lo que nos permite construir nuestro ternario.
El
and
es lo que nos permitirá evaluar la condición, siempre devolveráy
six and y
se evalúa como TRUE.El problema con esto es que fallará si queremos que se devuelva un
nil
ofalse
cuando la condición seafalse
. Por ejemplo, lo siguiente siempre devolverá 5, a pesar de que la condición sea verdadera.Aquí hay una evaluación paso a paso de un ternario para explicar cómo funciona (será útil para cuando tenga que anidarlos :))
fuente
He compilado varios consejos también. Estoy seguro de que algunos de los míos se superpondrán con los ya mencionados, pero los incluiré de todos modos para crear una respuesta más completa.
Asigna funciones repetidas a variables
Lua le permite asignar funciones a variables. Incluso las variables de un personaje. Esto significa que si repite la función
string.sub(x, y)
más de dos veces, obtendrá un beneficio al asignarla a una variable.Sin asignar a una variable (69 caracteres):
Asignación a una variable (51 caracteres):
Hay casos en los que puedes llevar esto un paso más allá. Lua permite que una OOP manipule cadenas, de esta manera:
str:sub(x, y)
ostr.sub(x, y)
Esto abre nuevas opciones para nuestro código. Puede asignar una variable a la función por su referencia como se muestra (46 caracteres).Use la forma más eficiente de analizar cadenas
Puede encontrarse utilizando un
for
bucle estring.sub
iterar carácter por carácter en Lua. A veces esto puede funcionar mejor, dependiendo de sus necesidades, pero otras veces, string.gmatch funcionará en menos caracteres. Aquí hay un ejemplo de ambos:Y cuando se juega al golf, la diferencia es más notable:
Reestructurar asignaciones para optimizar espacios en blanco
En Lua, no tiene que poner un carácter de espacio entre paréntesis cerrados o una comilla final y el siguiente carácter. Hasta ahora, he encontrado dos casos en los que la reestructuración con esto en mente reducirá los caracteres.
Asignación de variables:
Si declaraciones:
Devuelve la menor cantidad de caracteres posible
Si debe devolver un valor verdadero o falso, entonces parece que necesariamente debe usar al menos 5 caracteres para el valor devuelto. En realidad, lo siguiente funciona igual de bien:
fuente
nil
yfalse
se evalúa como falsa en lua, todo lo demás es cierto, por lo que sus consejos acerca de reemplazarx==0
,x==""
yx==''
porx
es falsa. Actualmente lo estoy cambiando anil
:).Estas son solo optimizaciones de Lua (creo):
Las cadenas se convierten automáticamente en números cuando se realizan operaciones aritméticas en ellas. Solo ten cuidado con las declaraciones condicionales, no se convierten automáticamente. Esto es excelente para tomar la entrada del usuario como números mientras ahorra espacio.
Cambiar el contenido de dos variables no requiere una variable temporal.
a,b=b,a
intercambiará los valores de a y b.Además, para ampliar lo que se dijo anteriormente, cualquier carácter alfanumérico puede tocar un carácter no alfanumérico. Por
a,b=io.read():match"(.+)/(.+)"u,v=a,b
lo tanto, es un script perfecto y funcional, incluso con la falta de espacios en blanco.fuente
Combinar asignaciones de variables locales
En lugar de:
Usar asignación paralela:
¡6 bytes guardados para cada variable!
Declarar variables locales a través de parámetros de función no utilizados
En lugar de:
Utilizar
6 bytes guardados (menos 1-2 bytes por cada variable que pueda estar duplicada).
fuente
local
esté justificado al jugar al golf, porque solo tienes que usar un nombre diferente. Podríamos usar TODOS los nombres de hasta 7 caracteres Y tablas con índices de cadena de hasta 7 combinaciones de caracteres antes de llegar a algo que podría beneficiarse con el uso de localesFunciones Variadas
La función variadic principal que te molestará es
print()
. Por ejemplo, cuando lo esté utilizandoString.gsub()
, imprimirá la cadena que modificó Y la cantidad de veces que segsub
activó.Para suprimir esa segunda salida, encapsule su
gsub
en parens para forzarlo a devolver solo un valorfuente
Sepa como salida
Hay dos métodos principales de salida en lua
Cuando tiene que concatenar varias veces, puede acortar eso mediante el uso
io.write()
asignado a una variable de una letra en lugar del operador de concatenación estándar..
Ganas 2 bytes en cada llamada mientras pagas por adelantado
Incluso estás en la tercera concatenación y comienzas a ganar byte en la cuarta.
fuente
print
y noprintf
!Un montón de consejos sin ningún orden en particular:
string
Es un nombre bastante largo. Eficientemente,('').char
es lo mismo questring.char
. Se pueden lograr resultados aún mejores si lo usa junto con un punto y coma en las variablesa=...; print(a:sub(1, 5))
, pero algunasstring
funciones no toman cadenas como entrada.tonumber
, y+0
a menudo sólo perder bytes.load'your function code here'
lugar defunction()your function code here end
. Acceder a argumentos de la función utilizando...
inside.a:gsub('.',load'my function')
parece ser la forma más corta de iterar sobre caracteres en una cadenaa:find('.',1,1)
(para probar este problema, intente incluir%
en varios lugares en su entrada y verifique los resultados). Innumerables ideas se rompieron debido a que Lua intentó analizar la entrada como patrón.nil
es de tres bytes,_
es uno (es solo un nombre aleatorio que probablemente no existe). Además, cualquier dígito funcionará como valor verdadero.x and i or o
. No es solo un operador ternario, es una expresión lógica completa. De hecho, significa lo siguiente: "six
es verdadero, intentei
. Si x o i es falso, devuelva o". Entonces, sii
no es verdad, el resultado sí lo eso
. Además, se pueden omitir ambasand
oor
partes (x and i
,x or o
).math.floor
:5.3//1==5.0
. Tenga en cuenta que el número resultante siempre sigue el tipo de entrada uno (entero / flotante).fuente