El objetivo de esta publicación es reunir todos los consejos de golf que se pueden aplicar fácilmente en <all languages>
lugar de uno específico.
Solo publique respuestas de que su lógica se puede aplicar a la mayoría de los idiomas
Por favor, un consejo por respuesta
<all languages>
...Respuestas:
Fusionar bucles
Por lo general, puede fusionar dos bucles consecuentes, o dos bucles anidados, en uno.
Antes de:
Después:
fuente
foo
se llamaa
tiempos,bar
se llamab
tiempos. Esto se debe a que en "después", el ciclo ejecutaa+b
tiempos, la primeraa
llamadafoo
, la siguiente llamadabar
.for(y=0;y<Y;++y)for(x=0;x<X;++x)
a menudo puede convertirsefor(i=0;i<X*Y;++i)
conx
reemplazada pori%X
yy
reemplazado pori/X
.Solo por mencionar lo obvio:
Cuestione su elección de algoritmo e intente algo completamente nuevo.
Al jugar al golf (especialmente problemas más difíciles que resultan en programas más largos) con demasiada frecuencia, puede seguir el camino que eligió por primera vez sin probar otras opciones fundamentales . Por supuesto, puede micro golf una o unas pocas líneas a la vez o una parte de la idea general, pero a menudo no intenta una solución totalmente diferente.
Esto fue especialmente notable en Hitting 495 (Kaprekar) donde desviarse del algoritmo real y buscar patrones que puede aplicar para obtener el mismo resultado fue más corto en muchos idiomas (simplemente no J).
La desventaja es que posiblemente resuelves lo mismo media docena de veces. Pero funciona en todos los idiomas, excepto HQ9 + (donde encontrar otra forma de generar Hello World sería un poco inútil).
fuente
Utilice el desarrollo basado en pruebas
Si el código debe manejar varias entradas, escriba pruebas exhaustivas y facilite ejecutarlas todas muy rápidamente. Esto le permite probar transformaciones arriesgadas paso a paso. El golf se convierte en una refactorización con intención perversa.
fuente
Intenta reducir las declaraciones lógicas
Por ejemplo, si
A
yB
son booleanos y su idioma trata los booleanos como números en cierta medida,A and (not B)
yA>B
son equivalentes. Por ejemplo en Pythones lo mismo que:
fuente
B>A or foo()
sería una forma aún más corta de expresar esto, aproveche la evaluación perezosa de las expresiones booleanas para asegurarse de que solo calcule las cosas cuando sea necesario.B>A or foo
evaluaríafoo
siB==A
no es lo que queremos. (¿Correcto?)Inicialice variables usando valores que ya tiene.
En lugar de
x=1
, intente buscar algo que ya sea igual a 1.Por ejemplo, el valor de retorno de una función:
printf("..");x=0;
->x=!printf("..");
. Es más fácil con 0, porque siempre puedes negarlo, o cuando todo lo que necesitas es el valor de verdad correcto (y no te importa si es 1 o 19).fuente
Use unary
~
parax+1
yx-1
Este truco se aplica a los idiomas que tienen un operador de negación bit a bit unario
~
y un operador de negación regular unario-
.Si su programa, por casualidad, contiene la expresión
-x-1
, puede reemplazarlo~x
para guardar bytes. Esto no ocurre con demasiada frecuencia, pero observe lo que sucede si negamos (-
) ambas expresiones: ¡x+1
igual-~x
! Del mismo modo,x-1
es igual~-x
. (Piense en qué dirección apunta la tilde: derecha es+
, izquierda es-
).Esto es útil, porque en todos los idiomas que puedo pensar que tienen estos operadores, tienen mayor prioridad que la mayoría de los operadores. Esto le permite ahorrar entre paréntesis. Mira cómo ahorramos cuatro bytes aquí:
fuente
Exprimir espacios en blanco
Conozca las reglas para espacios en blanco en su idioma. Es posible que algunos signos de puntuación u otros caracteres no necesiten espacios en blanco circundantes. Considere esta función de shell Bourne :
En Bourne shell,
();
son metacaracteres y no necesitan espacios en blanco circundantes. Sin embargo,{}
son palabras y necesitan espacios en blanco a menos que estén al lado de metacaracteres. Podemos jugar al golf 4 espacios al lado();
, pero debemos mantener el espacio entre{
yecho
.En Common Lisp y PicoLisp ,
()
son metacaracteres. Considere este código para encontrar el promedio de dos números:Podemos jugar al golf 2 espacios.
Algunos idiomas tienen reglas extrañas y sutiles para los espacios en blanco. Considere este programa Ruby, que imprime la suma y el producto de una línea de enteros.
Cada uno
&
necesita un espacio antes de sí mismo. En Ruby,i=$F.map &:to_i
significai=$F.map(&:to_i)
donde&
pasa un parámetro de bloque. Pero,i=$F.map&:to_i
significai=$F.map.&(:to_i)
donde&
está un operador binario.Esta rareza ocurre en idiomas, como Perl o Ruby, que usan signos de puntuación ambiguos. Si tiene dudas, use un REPL o escriba programas cortos para probar las reglas de espacios en blanco.
fuente
asignar funciones a nuevos nombres si se usan varias veces
fuente
x
.Nombres de variables de una letra
Tienes 52 de ellos; úsalos todos! No tenga miedo de probar diferentes enfoques y comparar longitudes. Conozca el idioma y los accesos directos específicos / funciones de biblioteca disponibles.
fuente
$
y_
se puede usar como identificadores.@
es un nombre de variable válido en T-SQL, úselo en lugar de@a
.Usa el operador condicional.
Un operador condicional
es más beneficioso, en cuanto al carácter, que una declaración IF .
Se puede escribir como
fuente
a&&b||c
en su lugar. Un poco más largo, pero aún más corto que unif
.Iff
, aunque es una función, por lo que está sujeto a la evaluación de todos los argumentos.if(a ? b : c)
a&&b||c
puede regresarc
cuandoa
es verdadero sib
es falso, un pequeño caso marginal, pero no debemos olvidar eso ^^Escribe una explicación de tu código
Escribir una explicación te obliga a mirar a fondo cada parte de tu código nuevamente y a hacer explícitos tus pensamientos y elecciones al escribir cierto pasaje. Al hacerlo, puede encontrar que son posibles diferentes enfoques que pueden ahorrar algunos bytes, o que inconscientemente hizo suposiciones que no necesariamente son válidas.
Este consejo es similar a Cuestionar el algoritmo de su elección y probar algo completamente nuevo ; Sin embargo, he descubierto que el paso de escribir realmente cómo se supone que funciona cada parte es a veces crucial para tomar conciencia de las alternativas.
Como beneficio adicional, las respuestas que incluyen una explicación son más interesantes para otros usuarios y, por lo tanto, es más probable que se voten positivamente.
fuente
Comprueba tu cuenta de personaje
Suena como una obviedad, pero al tener cuidado, ¡podrías "salvar" a algunos personajes al no hacer nada!
Si está utilizando Windows, puede estar ingresando en
\r\n
lugar de solo\r
o\n
cuando presiona Retorno, ¡agregando un byte adicional por línea! Gire los caracteres de control solo para verificar que no está haciendo esto.En Notepad ++ puede convertir todas las
\r\n
terminaciones de línea simplemente\r
yendo aEdit > EOL Conversion > UNIX/OSX Format
.¡También asegúrate de no incluir ningún espacio en blanco al final de tu cuenta de personaje! El avance de línea en la línea inferior de su código también es intrascendente, por lo que tampoco será necesario contarlo.
fuente
Lee la pregunta detenidamente
El golf de código se trata tanto de entender la pregunta (qué se pregunta y qué no) pregunta, aunque esté implícito en cualquier otro entorno) como producir código que (puede) solo satisfaga lo que se pregunta.
No es necesario manejar ninguna entrada que no sea la que se solicita explícitamente. Si hay algunos casos de prueba y ningún requisito genérico, su código solo puede funcionar en esos casos. Etc.
fuente
Use operaciones bit a bit para verificar números entre 0 y 2 n -1
Puede ser un caso marginal, pero a veces puede ser útil. Se basa en el hecho de que todos los números a los que se aplica m = 2 n -1 tienen los n bits más a la derecha establecidos en 1.
Entonces, 7 10 == 00000111 2 , 15 10 == 00001111 2 , 31 10 == 00011111 2 y así sucesivamente.
El truco es
x&~m
. Esto devolverá verdadero siemprex
que no esté entre 0 em
(inclusive), y falso de lo contrario. Ahorra 6 bytes de la siguiente expresión equivalente más corta:x>=0&&x<=m
pero obviamente solo funciona cuandom
cumple 2 n -1.fuente
Reutilice parámetros de función en lugar de nuevas variables
fuente
main(i){...
que ahora tiene una variable con el valor de 1 sin tener que hacer cualquier tarea. 2 caracteres guardados allí ..Mayor / menor que para guardar un dígito:
¡Solo recuerde cambiar el código de
if
aelse
y ellos harán exactamente lo mismo (o cambiarán los lados de la desigualdad)!Nota: esto se puede aplicar con cualquier potencia de 10 y sus negativos:
...-100, -10, 10, 100...
(enlace fuente)
fuente
if(n>99999)
vsif(n<1e5)
Use> y <en lugar de> = y <=
Al comparar con valores enteros codificados, use
>
y en<
lugar de>=
y<=
donde sea posible. Por ejemplo, usandoEs 2 bytes más corto que usar
fuente
<1
lugar de==0
como verificación cero (o en>0
lugar de!=0
la verificación reflejada).x
ser un número entero?Evite las interrupciones prematuras del bucle
Si se ejecuta a través de un bucle para verificar 1 o más instancias de una verificación booleana, podría hacer que un programa más eficiente salga del bucle en el primer valor verdadero. Sin embargo, eliminar la ruptura y recorrer todas las iteraciones permite un código más corto.
fuente
if
declaración de distancia en estos casos:m|=i>=100
. (Y también puede simplificar eli>=100
toi>99
en este caso, pero eso no es muy relevante aquí)utilizar
-
lugar de!=
para comparaciones numéricas:
Si a es igual a b,
a-b
resulta en0
, lo cual es falso. Cualquier otra cosa que no0
sea la verdad; así quesi se usa en un contexto booleano,
a-b
<=>a!=b
Si lo usa con
if/else
o con el operador ternario, esto también puede ahorrarle un byte para la igualdad:a==b?c:d
<=>a-b?d:c
fuente
Cadenas divididas para matrices largas
La mayoría de los idiomas tienen una forma de dividir una cadena en una serie de cadenas alrededor de un token de algún tipo. Esto inevitablemente será más corto que un literal de matriz una vez que la longitud alcance un umbral dependiente del idioma, porque la sobrecarga adicional por cadena será una copia de un token de un carácter en lugar de (al menos) dos delimitadores de cadena.
Ej. En GolfScript
se convierte
Para algunos idiomas, el umbral es tan bajo como una cadena. Por ejemplo, en Java,
se convierte
fuente
%w{Foo Bar Baz Quux}
.qw(Foo Bar Baz Quux)
convierte en una lista de cadenas.Comprende lo que otras personas hicieron
Además de ser divertido, si examina el código de otras personas, a veces puede descubrir un buen algoritmo en el que no pensó, o un truco (a veces obvio) que pasa por alto.
A veces hay una respuesta existente que puede traducir a otro idioma y beneficiarse de los beneficios del otro idioma.
fuente
conozca su precedencia de operador
Siempre que combine varias expresiones, verifique la tabla de precedencia de operadores para su idioma para ver si puede reordenar cosas para guardar paréntesis.
Ejemplos:
(a&b)&&c
no necesita paréntesis:a&b&&c
al igual(a*b)+c
que no.a+(b<<c)
puede reescribirse comoa+b*2**c
.Eso no guarda nada para este ejemplo, pero lo hará si
c
es un literal entero pequeño (<14).a<b&&c<d
cona<b&c<d
(a menos que necesite la evaluación de cortocircuito)fuente
For-loop más cortos
Si tiene
X
declaraciones{
dentro de}
su ciclo for, puede mover lasX-1
declaraciones(
dentro)
del ciclo for después del segundo puntofor(blah;blah;HERE)
y coma para guardar 3 bytes. (separe las declaraciones usando una coma,
)En lugar de
puede mover una de las declaraciones a las
(
llaves del ciclo for)
mientras deja la otra fueray ahorre 3 bytes (ahorró 1 byte más gracias a @ETHProductions)
En pocas palabras,
en lugar de
mueve las declaraciones para que termines con esto
y guardar 3 bytes
fuente
for
es la declaración final, se;
convierte en opcionalUse unary
~
paraa-b-1
ya+b+1
Además de las sugerencias de @Lynn con respecto a
x+1
→-~x
; yx-1
→~-x
, también puedes jugar al golfa-b-1
ya+b+1
.Puede parecer un consejo que no usará con tanta frecuencia, algo así como usarlo en
~x
lugar de-x-1
no suceder con frecuencia, pero lo he usado suficientes veces para verlo como un consejo útil aquí. Especialmente con la indexación de matrices, puede usar estos anteriores en algunos casos.fuente
Comprimir o / y rayas
Truco simple que se me ocurrió al tratar de exprimir una larga racha de condiciones encadenadas por ands (o ors, en este caso simplemente sustituya 'all' por 'any').
P.ej:
Se convierte
fuente
all(array-of-Booleans)
incorporado?[a>0,a<10,a+b==4,a+3<1].all?
if 10>a>0 and a+b==4>1>a+3:
Confíe en el compilador para proporcionar el rendimiento requerido.
Asegúrese de saber qué optimizaciones están garantizadas por el compilador y en qué niveles de optimización, y úselas generosamente. E incluso si el rendimiento no es un requisito de
preocupación, aún puede probar con optimizaciones activadas y luego solo descontar un carácter porque su código aún es técnicamente válido sin el indicador del compilador.Considere la siguiente función de Haskell para calcular 2 ^ n (ignorando el hecho de que Haskell ya tiene un operador de exponenciación incorporado o tres) (23 caracteres):
El problema es que es terriblemente lento, se ejecuta en tiempo exponencial. Esto puede hacer que su código no sea comprobable o que falle cualquier restricción de rendimiento dada por la pregunta. Es posible que tenga la tentación de utilizar una variable temporal o un literal de función invocado inmediatamente para evitar llamadas repetidas a funciones (25 caracteres):
Pero el compilador ya puede hacer eso por usted, ¡solo necesita establecerlo
-O
como un indicador del compilador! En lugar de gastar algunos caracteres adicionales por sitio para eliminar subexpresiones comunes manualmente, solo dígale al compilador que haga optimizaciones básicas para usted para un total de uno o dos caracteres en todo el programa.fuente
p(x-1)*2
?Quizás algo obvio pero ...
Hacer uso de los valores de retorno del operador
¡Tenga en cuenta que el operador de asignación devuelve un valor!
Por ejemplo, si desea agregar y a x y luego verificar si x es mayor que algo, puede hacer
en lugar de
O tal vez desee encontrar la longitud de una cadena después de recortarla:
Más bien que
fuente
a = (b=c)+1;
estableceb
enc
, y luego establecea
enb+1
.a=1+b=c
. Y puede agregar PHP y JavaScript a su lista.=
operador una mayor prioridad a la izquierda que a la derecha, por lo que1+x=2
es válido y se evalúa a3
Utilice la versión de idioma / compilador / peculiaridades del entorno / nuevas características
Esto es especialmente útil para los políglotas , pero se puede aplicar a otros desafíos. A veces, un error del compilador puede salir de un byte, un error de implementación puede permitirle guardar algunos caracteres, o una característica realmente innovadora puede mejorar su puntaje.
fuente
Combine múltiples / anidados si las comprobaciones utilizando Y / O cuando sea posible.
es decir:
en lugar de:
fuente
&
, `|) para eliminar más caracteres.&
lugar de&&
eliminar 1 carácter en algunos casos, confunde la precedencia del operador y tendrá que poner paréntesis para que funcione. Úselo sabiamente.Encuentre mejores formas de inicializar sus variables
Algunas otras respuestas estuvieron a punto de mencionar esto, pero en muchos idiomas (¿estrictamente escritos?), Es más corto inicializar
x
como una cadena vacía como:o
x
como runa vacía (char) como:que
y
Obviamente, se prefiere usar valores preexistentes, pero no es tan fácil.
fuente