¿Qué consejos generales tienes para jugar al golf en C ++? Estoy buscando ideas que puedan aplicarse a los problemas de golf de código en general que sean al menos algo específicos para C ++ (por ejemplo, "eliminar comentarios" no es una respuesta). Por favor, publique un consejo por respuesta.
48
Respuestas:
El operador condicional ternario
?:
menudo se puede utilizar como soporte en por sencillaif
-else
declaraciones en un ahorro considerable.Tiene un valor especial porque puede usarse para seleccionar valores alternativos como en
fuente
e
yo
. Tenga en cuenta que esto es diferente de cómo funciona este operador en c donde este truco no funciona porque no puede ser un valor.std::endl
con'\n'
eso ahorra 5 caracteresA veces puede guardar dos caracteres utilizando el hecho de que las variables de duración de almacenamiento estático (que incluye especialmente todas las variables de alcance global) se inicializan automáticamente al cero al principio (a diferencia de las variables automáticas donde no tiene dicha garantía). Entonces en lugar de
puedes escribir
fuente
Algunos compiladores (por ejemplo, GCC) admiten constantes de varios caracteres . Esto puede guardar algunos caracteres cuando se requiere un valor entero grande. Ejemplo:
El valor es específico de la implementación. Por lo general, el valor de
'ab'
es256*'a'+'b'
o'a'+256*'b'
. Puede especificar hasta 4 caracteres entre comillas.fuente
Uno que me pareció útil:
Aprovechando el hecho de que los valores distintos de cero se evalúan
true
en expresiones booleanas, y eso sex&&y
evalúax*y
cuando se trata de valores booleanosevalúa a
Solo debe tener en cuenta los desbordamientos, como se señala a continuación.
fuente
x!=0 && y!=0
. Pero cuando se usa la multiplicación, debes tener cuidado con los desbordamientos. Cuando se usan enteros de 32 bits, x = y = 65536 (y varias otras combinaciones de potencias de dos) también producirían x * y = 0 .&&
tenga en cuenta que tiene un comportamiento de cortocircuito que le*
falta. Por ejemplo, no puede reemplazari++!=0&&j++!=0
coni++*j++
.Use los siguientes tipos:
Para palabras / tipos repetitivos, use
#defines
:Solo vale la pena si usa
while
mucho para compensar los 10 caracteres adicionales. ( Alrededor de 4. )fuente
Si está dispuesto a usar C ++ 0x, puede usar nuevas funciones como lambdas .
fuente
Cuando sea posible, cambie
&&
y||
a&
y|
respectivamente.Cuando se usan declaraciones if simples:
se puede cambiar a:
que salva a un personaje
fuente
En lugar de usar
while(1)
, usarfor(;;)
, guardar un personaje :)fuente
El uso del operador de coma en lugar de llaves abiertas y cerradas puede guardar algunos caracteres, si tiene una situación en la que sus cláusulas tienen más de una declaración:
vs.
Dos caracteres guardados en un IF simple, o tres en total para un IF / ELSE.
Como un punto de distinción entre C y C ++, el resultado de una expresión de coma en C ++ en su conjunto puede usarse como un valor l ... FWIW.
fuente
Dado que los elementos de la matriz se almacenan directamente uno tras otro en la memoria, en lugar de algo como esto:
Puedes hacer algo como esto:
Obviamente, ninguno de los anteriores es golf, para facilitar la lectura, pero el uso explícito de punteros puede ahorrarle mucho espacio.
fuente
for(int* i=array; i<array+25*25; i++)
? Entonces solo tiene que hacer un seguimiento de una variable.Es bastante obvio, pero si está utilizando una gran cantidad de la biblioteca estándar,
using namespace std;
puede guardar algunos caracteres.fuente
using std::name;
puede ser más corto.std::
cinco o más veces.Es útil recordar que
a[i]
es lo mismo que*(a+i)
.Reemplazar
a[0]
con*a
dos ahorro de caracteres. Además,a[i][0]
es equivalente*a[i]
y sea[0][i]
reduce ai[*a]
. Entonces, si está codificando un0
índice en su matriz, probablemente exista una mejor manera.fuente
En lugar de escribir grandes potencias de 10, usa la notación e . Por ejemplo,
a=1000000000
es más largo quea=1e9
. Esto se puede extender a otros números comoa=1e9+24
es mejor quea=1000000024
.fuente
1e9/x
no es lo mismo que1000000000/x
oint(1e9)/x
.Puede usar el operador ternario
?:
sin ninguna expresión en el bloque verdadero (guarda un byte)Compruébalo aquí
fuente
Encabezado más corto
Esto es específico de GCC, puede ser extensible a otros compiladores.
Encabezado precompilado.
En G ++,
bits/stdc++.h
el encabezado precompilado consiste en todos los demás encabezados. Si necesitaimport
2 diferentes, simplemente puede usar esto.Encabezado más corto.
Estos son todos los encabezados enumerados en http://en.cppreference.com/w/cpp/header :
Mostrar fragmento de código
ordenados en orden creciente de longitud.
Algunos de ellos ya son más largos
bits/stdc++.h
y otros requieren compatibilidad con C ++ 17. Algunos otros no son compatibles con TIO G ++ (por razones que no conozco). Filtrarlos tenemos:Mostrar fragmento de código
Puede suceder que algunos de ellos puedan ser reemplazados por otros más cortos. Solo busque binariamente si puede reemplazar la que necesita. En particular:
fuente
#import
en lugar de#include
darte un byte más.Además, el carácter de espacio entre
#import
y el encabezado no es necesariamente:Y si necesita algo del
stdlib
encabezado, puede importar cualquier encabezado con el contenedor STL (preferibleset
omap
) en lugar decstdlib
.fuente
Operaciones aritméticas en booleanos:
A pesar de que
es mejor que
no es tan bueno como
Además, usar #define en cualquier cosa que se use mucho. A menudo es más corto que usar funciones, ya que los nombres de tipo no son necesarios.
Combina las cosas tanto como sea posible:
es lo mismo que
fuente
x
como un valor yx++
como un valor. comportamiento indefinido y puntos de secuenciaUsa lambdas genéricas como plantillas baratas
Para otros tipos que no sean
int
, usarlos como argumentos de función puede ser costoso. Sin embargo, se introdujeron lambdas genéricas (en C ++ 14?) Y permiten que cualquier lambda sea una plantilla; el usoauto
de los tipos de argumento puede guardar bytes. Comparar:Las lambdas genéricas también son muy convenientes para aceptar iteradores: probablemente la mejor manera de aceptar entradas de matriz en C ++ es
[](auto a, auto z)
, dóndea
yz
se pasan comobegin()
yend()
de la matriz / vector / lista / etc.fuente
En mi primer intento de codificar golf para la tarea "Restar los siguientes números" , comencé desde la función (58 bytes)
luego a salvo 5 bytes con cambiar a lambda y mover la inicialización de
for
(53)y finalmente después de cambiar de
for
awhile
obtuve 51 bytes:El código de prueba sin golf es algo así como:
ACTUALIZAR:
En realidad
for
puede alcanzar la misma longitud quewhile
:fuente
Un poco tarde para la fiesta, supongo ...
Si desea convertir una expresión en -1 y 1 en lugar de 0 y 1, en lugar de esto:
hacer esto:
Puede guardar algunos bytes dependiendo del uso.
fuente
int x=(a*10>5)*2-1;
, ¿no podrías hacerloint x=a*10>5?1:-1;
, que es 1 byte más corto?Si desea intercambiar dos variables enteras a y b, entonces,
se puede usar, ahorrando 5 caracteres que la forma estándar
fuente
,t
en los ints creados anteriormente y luegot=a;a=b;b=t;
ya habrían sido 3 bytes más cortos que ela+=b;b=a-b;a-=b;
. Aún así, tua^=b^=a^=b;
es aún más corto que eso, entonces +1 de mi parte. No sé C ++, pero de hecho funciona . Como jugador de código Java, estoy triste porque no parece funcionar allí . :(a^=b;b^=a;a^=b;
funciona bien en Java.a^=b;b^=a;a^=b;
de hecho funciona, pero es más largo que el,t
+t=a;a=b;b=t;
. Perdón por mencionar Java, ya que está fuera de tema aquí. ¡Pero un buen consejo para los codegolfers de C ++!Utilice los componentes incorporados de GCC en lugar de importar
Si está utilizando un compilador GCC, a veces ayuda usar sus funciones integradas, como
__builtin_puts
o__builtin_clz
. Por ejemplo,44 bytes:
50 bytes:
fuente
Si está haciendo C ++ 11 o más reciente (que siempre debería ser el caso ahora), utilícelo
auto
para tipos complejos, si es posible.Ejemplo: 54 bytes en lugar de 66
Además, como el rendimiento no importa, para algunos desafíos, a
std::list
solo puede hacer el trabajo por unos pocos bytes menos:fuente
Las funciones a
<algorithm>
menudo requieren pasar, loa.begin(),a.end()
cual es realmente largo, en su lugar puede usar&a[0],&*end(a)
para guardar 3 bytes sia
esvector
ostring
.fuente
No uses
string("")
, usa""
. Ahorra 8 bytes.fuente
"" + 'a'
eschar* + char
, que es la suma del puntero, mientras questd::string("") + 'a'
esstd::string + char
- concatenación de cadenas.string()
trabajaría.