Consejos para jugar golf en <todos los idiomas>

81

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

ajax333221
fuente
55
¿"Mayoría" por qué métrica?
dejó de girar en contra del reloj el
2
@leftaroundabout por la métrica de la misma palabra
ajax333221
8
El problema es que muchos lenguajes son (a menudo de corta duración) experimentales con paradigmas muy atípicos, para los cuales las expresiones de programación típicas no tienen ningún sentido. Así que "la mayoría de todos los idiomas" es prácticamente imposible de cumplir. Debe restringirlo de alguna manera, por ejemplo, a "la mayoría de los idiomas utilizados regularmente en codegolf.SE". Por el momento, las respuestas se parecen bastante a "la mayoría de los lenguajes remotos derivados de C", pero esos, aunque la gran mayoría de todo el código escrito está escrito en ellos, no son la mayoría de los lenguajes .
dejó de girar en contra del reloj el
3
A la izquierda, creo que todos sabemos lo que significan a grandes rasgos. Se trata principalmente de optimizaciones independientes del lenguaje, es decir, no solo útiles en Brainfuck, sino también en Python, C, Java y Fortran a la vez. Ideas generales que puede aplicar en muchos idiomas que funcionan de manera similar. No creo que sea necesario ser tan preciso y específico en los consejos y en una pregunta de CW. Se trata de ayudar a otros a jugar al golf, no de molestarlos.
Joey
14
Esperemos que nadie cree un lenguaje llamado <all languages>...
mbomb007

Respuestas:

72

Fusionar bucles

Por lo general, puede fusionar dos bucles consecuentes, o dos bucles anidados, en uno.

Antes de:

for (i=0; i<a; i++) foo();
for (i=0; i<b; i++) bar();

Después:

for (i=0; i<a+b; i++) i<a?foo():bar();
Ugoren
fuente
ugoren los bucles todavía no son lo mismo. @Gaffi tiene razón.
kaoD el
55
@kaoD, en ambos casos foose llama atiempos, barse llama btiempos. Esto se debe a que en "después", el ciclo ejecuta a+btiempos, la primera allamada foo, la siguiente llamada bar.
ugoren
Estoy mirando esto nuevamente (mucho, mucho más tarde), y no entiendo mi propia pregunta ahora. Tal vez no entendí la operación ternaria antes? Tal como lo veo ahora, tiene sentido.
Gaffi
1
Woops, lo leí muy tarde en la noche. ¡Tienes razón!
kaoD
3
Muy similar: for(y=0;y<Y;++y)for(x=0;x<X;++x)a menudo puede convertirse for(i=0;i<X*Y;++i)con xreemplazada por i%Xy yreemplazado por i/X.
Lynn
62

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).

Joey
fuente
12
+1 ¡Además de ser bueno para el golf, este es un buen ejercicio para cualquier programador en muchas situaciones del mundo real!
Gaffi
52

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.

Adrian McCarthy
fuente
44
Yo uso un spin-off de este método. Como los problemas en sí mismos suelen ser bastante simples, escribo un programa que hace el trabajo. Por lo general, esto es "legible para jugar al golf", por lo que es sucinto, pero hay nuevas líneas, etc. Copio este archivo a una nueva ubicación y lo golf, comprobando de vez en cuando que los programas devuelven los mismos valores para algunas entradas elegidas. Si alguna vez cometo un error dejándome con un programa roto, sin memoria de lo que cambié y sin comprender mi pieza de golf, tengo algo de una "especificación" guardada como fuente de referencia.
shiona
2
Me encanta este método, que es una razón por la que tiendo a incluir conjuntos de pruebas integrales para todos los problemas que escribo.
Joey
@RubberDuck El principio de no repetirse a menudo se sigue estrictamente.
Jonathan Frech
48

Intenta reducir las declaraciones lógicas

Por ejemplo, si Ay Bson booleanos y su idioma trata los booleanos como números en cierta medida, A and (not B)y A>Bson equivalentes. Por ejemplo en Python

if A and not B:
    foo()

es lo mismo que:

if A>B:
    foo()
Wrzlprmft
fuente
3
Nunca hubiera pensado en eso.
cjfaure
27
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.
scragar
55
@scragar: Correcto, pero este no es el punto de este consejo. (Sin embargo, es un consejo independiente valioso)
Wrzlprmft
3
@scragar, B>A or fooevaluaría foosi B==Ano es lo que queremos. (¿Correcto?)
msh210
2
Además, si tiene condiciones imbricadas largas (digamos con parámetros de 5/6), puede usar una tabla de Verdad y un mapa de Karnaugh para encontrar la expresión booleana más corta para ella
Katenkyo,
33

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).

Ugoren
fuente
44
en C puede usar argc desde main como 1. ver: codegolf.stackexchange.com/questions/1034/reinvent-the-for-loop/…
std''OrgnlDave
1
@ std''OrgnlDave, True, pero esta pregunta es sobre cosas comunes a todos los idiomas.
ugoren
33

Use unary ~para x+1yx-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 ~xpara guardar bytes. Esto no ocurre con demasiada frecuencia, pero observe lo que sucede si negamos ( -) ambas expresiones: ¡ x+1igual -~x! Del mismo modo, x-1es 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í:

(x+1)*(y-1)     ==>    -~x*~-y
Lynn
fuente
30

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 :

f () { echo a; echo b; }

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 {y echo.

f(){ echo a;echo b;}

En Common Lisp y PicoLisp , ()son metacaracteres. Considere este código para encontrar el promedio de dos números:

(/ (+ a b) 2)

Podemos jugar al golf 2 espacios.

(/(+ a b)2)

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.

#!ruby -an
i=$F.map &:to_i
puts"#{i.reduce &:+} #{i.reduce &:*}"

Cada uno &necesita un espacio antes de sí mismo. En Ruby, i=$F.map &:to_isignifica i=$F.map(&:to_i)donde &pasa un parámetro de bloque. Pero, i=$F.map&:to_isignifica i=$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.

kernigh
fuente
1
¿Por qué debe haber un espacio entre "{" y "echo", pero no entre ";" y "eco"?
Ryan
3
Usé los términos del manual para OpenBSD sh (1), que dice que "{" es una palabra reservada y ";" Es un meta-personaje. Debido a esto, "{echo" es una palabra pero "; echo" son dos palabras. Otros manuales pueden explicar esto de manera diferente. Además, el Z shell zsh tiene diferentes reglas.
kernigh
28

asignar funciones a nuevos nombres si se usan varias veces

x = SomeLongFunctionName
x(somedata)
x(somemoredata)
etc
Chaqueta de sport
fuente
Solo si usamos suficientes llamadas a x.
elipszilon
28

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.

monstruo de trinquete
fuente
8
26 para idiomas que no distinguen entre mayúsculas y minúsculas. :-)
Gaffi
12
A menudo $y _se puede usar como identificadores.
Griffin
44
@Gaffi: Y más que suficiente para los idiomas que permiten identificadores Unicode, a menos que la tarea lo limite a ASCII o cuente bytes en lugar de caracteres.
hammar
Si está contando bytes en lugar de Unicode, usar ascii extendido podría ser una forma de exprimir otros ~ 120 identificadores si los necesita (no es que para un script de golf deba necesitar más de 26 de todos modos)
scragar
2
@es un nombre de variable válido en T-SQL, úselo en lugar de @a.
BradC
25

Usa el operador condicional.

Un operador condicional

bool ? condition_true : condition_false

es más beneficioso, en cuanto al carácter, que una declaración IF .

if(a>b){r=a;}else{r=b;}

Se puede escribir como

r=a>b?a:b;
MrZander
fuente
25
Los idiomas que no tienen un ternario pueden usar a&&b||cen su lugar. Un poco más largo, pero aún más corto que un if.
Michael Kohl
Por otra parte, algunos no pueden usar ninguna de las dos opciones (VBA viene a mi mente), pero ambas siguen siendo buenas sugerencias. :-)
Gaffi
1
Gaffi: VBA tiene Iff, aunque es una función, por lo que está sujeto a la evaluación de todos los argumentos.
Joey
Usar ternary en declaraciones if también puede ser muy útilif(a ? b : c)
Jojodmo
44
@MichaelKohl nota que a&&b||cpuede regresar ccuando aes verdadero si bes falso, un pequeño caso marginal, pero no debemos olvidar eso ^^
Katenkyo
24

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.

Laikoni
fuente
23

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\nlugar de solo \ro \ncuando 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\nterminaciones de línea simplemente \ryendo 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.

Sean Latham
fuente
No creo haber visto un caso en el que esto haya contado realmente ...
Jacob
44
Acabo de tener este problema yo mismo (de ahí por qué lo estoy agregando).
Sean Latham
21

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.

Tobia
fuente
15
Creo que un mejor titular aquí sería "No maneje casos extremos no requeridos". La frase "Intentar encontrar lagunas" nos recuerda formas de evitar hacer lo que se especifica mediante una reinterpretación ingeniosa de las reglas, mientras que lo que ofrece es simplemente un buen consejo para no implementar en exceso su solución.
Jonathan Van Matre
1
Sí, ¡pero una ingeniosa reinterpretación de las reglas también forma parte del golf de código! (0 soluciones de char, etc.)
Tobia
8
Sin embargo, esa sería / debería ser una respuesta diferente. Hay una diferencia fundamental entre, por ejemplo, implementar una solución que solo funciona para ints porque OP no requiere soporte flotante, y una respuesta que imprime el texto "cualquier primo mayor que 100" porque "no dijiste que tenía que ser un número primo real ".
Jonathan Van Matre
Creo que algunos OP incluyen un aviso de "Casos de prueba sujetos a cambios; su código aún debe funcionar después del cambio", y realmente los cambian si ven solo una respuesta que codifica los casos de prueba.
Erik the Outgolfer
20

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 siempre xque no esté entre 0 e m(inclusive), y falso de lo contrario. Ahorra 6 bytes de la siguiente expresión equivalente más corta: x>=0&&x<=mpero obviamente solo funciona cuando mcumple 2 n -1.

Sean Latham
fuente
18

Reutilice parámetros de función en lugar de nuevas variables

Grifo
fuente
1
Bueno, por ejemplo, en C, su función principal siempre pasa el número de argumentos suministrados al programa (que es 1 - el nombre del programa - por 'predeterminado') así main(i){...que ahora tiene una variable con el valor de 1 sin tener que hacer cualquier tarea. 2 caracteres guardados allí ..
Griffin
66
Creo que es bastante específico para C. Los lenguajes de script no necesitan declaraciones, y en la mayoría de los lenguajes compilados, definir una variable no es más largo que definir un parámetro.
Ugoren
en java cuando necesite una matriz dentro de una función que tenga el mismo tipo que un parámetro, puede ahorrar algunos bytes colocando ese parámetro como último y convertirlo en un parámetro vararg; (lo usé para eliminar algunos bytes en una función para encontrar la palabra más larga en una oración)
masterX244
18

Mayor / menor que para guardar un dígito:

//use:
if(n>9){A}else{B}
//instead of:
if(n<10){B}else{A}

¡Solo recuerde cambiar el código de ifa elsey 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)

ajax333221
fuente
No estoy seguro de entender el punto de esto. ¿De qué se reduce esto?
Gaffi
@Gaffi, guardas un personaje y hacen exactamente lo mismo
ajax333221
vs. que alternativa? Lo siento, no trato de ser obstinado, simplemente no lo entiendo. (newb, aquí, aparentemente ...)
Gaffi
1
Ah, ya veo. Funciona en cualquier transición de enteros de 9 a 10, de 99 a 100, etc. ¡Lo siento, me tomó tanto tiempo! (Digo solo entero, porque puedo ver un problema con n = 9.5 ...)
Gaffi
8
También en algunos idiomas (si es compatible) si sus números son lo suficientemente grandes / pequeños, la notación científica en realidad puede ahorrarle algunos caracteres: if(n>99999)vsif(n<1e5)
scragar
16

Use> y <en lugar de> = y <=

Al comparar con valores enteros codificados, use >y en <lugar de >=y <=donde sea posible. Por ejemplo, usando

if(x>24&&x<51)

Es 2 bytes más corto que usar

if(x>=25&&x<=50)
Jojodmo
fuente
3
Relacionado: Si está seguro de que un resultado no puede ser negativo, puede usarlo en <1lugar de ==0como verificación cero (o en >0lugar de !=0la verificación reflejada).
Kevin Cruijssen
1
¿No deberías agregar una nota sobre xser un número entero?
Zacharý
15

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.

int main() {
bool m = false;
int n = 1000;
for (int i = 0; i < n; i++) {
if (i >= 100) {
m = true;
break; // remove this line
}
} 
return 0;
}
Gaffi
fuente
55
También puede simplificar la ifdeclaración de distancia en estos casos: m|=i>=100. (Y también puede simplificar el i>=100to i>99en este caso, pero eso no es muy relevante aquí)
marinus
15

utilizar - lugar de!=

para comparaciones numéricas:

Si a es igual a b, a-bresulta en 0, lo cual es falso. Cualquier otra cosa que no 0sea ​​la verdad; así que
si se usa en un contexto booleano, a-b<=>a!=b

Si lo usa con if/elseo con el operador ternario, esto también puede ahorrarle un byte para la igualdad:
a==b?c:d<=>a-b?d:c

Titus
fuente
12

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

["Foo""Bar""Baz""Quux"]  # 23 chars

se convierte

"Foo
Bar
Baz
Quux"n/  # 20 chars

Para algunos idiomas, el umbral es tan bajo como una cadena. Por ejemplo, en Java,

new String[]{"Foo"}  // 19 chars

se convierte

"Foo".split("~")  // 16 chars
Peter Taylor
fuente
66
La excepción notable es Ruby, que proporciona una matriz de cadenas-de-literales que se divide automáticamente en los espacios a costa de dos bytes: %w{Foo Bar Baz Quux}.
Martin Ender
1
Perl proporciona algo similar: se qw(Foo Bar Baz Quux)convierte en una lista de cadenas.
BenGoldberg
12

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.

anatolyg
fuente
10

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:

  • En todos los idiomas que conozco, los operadores bit a bit tienen una precedencia más alta que los operadores booleanos: (a&b)&&cno necesita paréntesis: a&b&&cal igual (a*b)+cque no.
  • a+(b<<c)puede reescribirse como a+b*2**c.
    Eso no guarda nada para este ejemplo, pero lo hará si ces un literal entero pequeño (<14).
  • Las operaciones bit a bit tienen una precedencia más baja que la mayoría de las operaciones aritméticas, por lo que si su lenguaje convierte implícitamente boolean a int, puede guardar un byte a<b&&c<dcon a<b&c<d(a menos que necesite la evaluación de cortocircuito)
Titus
fuente
7

For-loop más cortos

Si tiene Xdeclaraciones {dentro de }su ciclo for, puede mover las X-1declaraciones (dentro )del ciclo for después del segundo punto for(blah;blah;HERE)y coma para guardar 3 bytes. (separe las declaraciones usando una coma, )

En lugar de

for(int i=0;i<9;){s+=s.length();println(i++);}

puede mover una de las declaraciones a las (llaves del ciclo for )mientras deja la otra fuera

for(int i=0;i<9;println(i++))s+=s.length();

y ahorre 3 bytes (ahorró 1 byte más gracias a @ETHProductions)


En pocas palabras,

en lugar de

for(blah;blah;){blah 1;blah 2;...;blah X}

mueve las declaraciones para que termines con esto

for(blah;blah;blah 2,...,blah X)blah 1;

y guardar 3 bytes

Kritixi Lithos
fuente
@ETHproductions Gracias por jugar un consejo :)
Kritixi Lithos
Y si fores la declaración final, se ;convierte en opcional
elipszilon
7

Use unary ~para a-b-1ya+b+1

Además de las sugerencias de @Lynn con respecto a x+1-~x; y x-1~-x , también puedes jugar al golf a-b-1y a+b+1.

a-b-1    // 5 bytes
a+~b     // 4 bytes

a+b+1    // 5 bytes
a-~b     // 4 bytes

Puede parecer un consejo que no usará con tanta frecuencia, algo así como usarlo en ~xlugar de -x-1no 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.

Kevin Cruijssen
fuente
6

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:

if a>0 and a<10 and a+b==4 and a+3<1:

Se convierte

if all([a>0,a<10,a+b==4,a+3<1]):
LemonBoy
fuente
Eso es genial, ¡tendré que probarlo!
stokastic
44
¿Qué idiomas tienen all(array-of-Booleans)incorporado?
Peter Taylor
3
Ruby lo tiene. [a>0,a<10,a+b==4,a+3<1].all?
kernigh
44
Aunque si esto fuera Python, estaría usando algo comoif 10>a>0 and a+b==4>1>a+3:
Sp3000
@PeterTaylor Haskell también lo ha hecho
haskeller orgulloso
6

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):

p 0=1;p x=p(x-1)+p(x-1)

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):

p 0=1;p x=(\y->y+y)$p$x-1

Pero el compilador ya puede hacer eso por usted, ¡solo necesita establecerlo -Ocomo 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.

John Dvorak
fuente
@ETHproductions sí, lo siento, lo hice
John Dvorak
¿No debería ser el primer ejemplo p(x-1)*2?
Cyoce
5

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

if(25<x+=y)

en lugar de

x+=y;if(x>25)

O tal vez desee encontrar la longitud de una cadena después de recortarla:

strlen(s=trim(s))

Más bien que

s=trim(s);strlen(s)
orp
fuente
¿En qué idioma puedes hacer una tarea dentro de una llamada? o es una palabra clave arg?
gato
2
Creo que las asignaciones son expresiones (con el nuevo valor de la variable asignada como su valor de expresión) en al menos C, C ++, C # y Java. a = (b=c)+1;establece ben c, y luego establece aen b+1.
Lynn
@ Lynn Prueba a=1+b=c. Y puede agregar PHP y JavaScript a su lista.
Titus
2
Ruby hace esto lo mejor. Le da al =operador una mayor prioridad a la izquierda que a la derecha, por lo que 1+x=2es válido y se evalúa a3
Cyoce
@Cyoce afaik es así en todos los idiomas donde una tarea es una expresión.
Titus
5

Utilice la versión de idioma / compilador / peculiaridades del entorno / nuevas características

Esto es especialmente útil para los , 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.

programador 5000
fuente
4

Combine múltiples / anidados si las comprobaciones utilizando Y / O cuando sea posible.

es decir:

if (a && (b || c)) {

}

en lugar de:

if (a) {
    if (b) {
        //Do Stuff
    } elseif (c) {
        //Do same stuff
    }
}
Gaffi
fuente
55
Además, use condicionales de bits ( &, `|) para eliminar más caracteres.
FUZxxl
2
Aunque usar bit a bit en &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.
DollarAkshay
4

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 xcomo una cadena vacía como:

x:=""

o xcomo runa vacía (char) como:

x:=''

que

var x string

y

var x rune

Obviamente, se prefiere usar valores preexistentes, pero no es tan fácil.

gato
fuente