Quels conseils généraux avez-vous pour jouer au golf en C ++? Je recherche des idées pouvant être appliquées aux problèmes de code de golf en général, qui sont au moins quelque peu spécifiques au C ++ (par exemple, "supprimer les commentaires" n'est pas une réponse). Merci de poster un pourboire par réponse.
48
Réponses:
L'opérateur conditionnel ternaire
?:
peut souvent être utilisé comme support dans des simplesif
-else
déclarations à des économies considérables.Il a une valeur particulière en ce qu’il peut être utilisé pour sélectionner des valeurs alternatives comme dans
la source
e
eto
. Notez que ceci diffère de la façon dont cet opérateur fonctionne dans c où cette astuce ne fonctionne pas car elle ne peut pas être une valeur.std::endl
par'\n'
qui enregistre 5 caractèresParfois, vous pouvez enregistrer deux caractères en utilisant le fait que les variables de durée de stockage statique (qui incluent notamment toutes les variables de portée globales) sont automatiquement initialisées à zéro au début (contrairement aux variables automatiques pour lesquelles vous n'avez aucune garantie de ce type). Donc au lieu de
tu peux écrire
la source
Certains compilateurs (par exemple, GCC) prennent en charge les constantes à plusieurs caractères . Cela peut économiser quelques caractères lorsqu'une valeur entière importante est requise. Exemple:
La valeur est spécifique à l'implémentation. Habituellement, la valeur de
'ab'
est256*'a'+'b'
ou'a'+256*'b'
. Vous pouvez spécifier jusqu'à 4 caractères entre les guillemets.la source
Celui que j'ai trouvé pratique:
Profitant du fait que les valeurs non nulles sont évaluées à
true
des expressions booléennes, et quix&&y
évalue àx*y
quand traiter booléensévalue à
Vous devez juste être conscient des débordements, comme indiqué ci-dessous.
la source
x!=0 && y!=0
. Mais lorsque vous utilisez la multiplication, vous devez faire attention aux débordements. Lors de l'utilisation d'entiers 32 bits, x = y = 65 536 (et plusieurs autres combinaisons de puissances de deux) donnerait également x * y = 0 .&&
a un comportement de court-circuit qui*
manque. Par exemple, vous ne pouvez pas remplaceri++!=0&&j++!=0
pari++*j++
.Utilisez les types suivants:
Pour les mots / types répétitifs, utilisez
#defines
:Cela ne vaut que si vous utilisez
while
beaucoup pour compenser les 10 caractères supplémentaires. ( Environ 4. )la source
Si vous souhaitez utiliser C ++ 0x, vous pouvez utiliser de nouvelles fonctionnalités telles que lambdas .
la source
Si possible, changez
&&
et||
à&
et|
respectivement.Lorsque vous utilisez des instructions if simples:
peut être changé en:
ce qui sauve un personnage.
la source
Au lieu d'utiliser
while(1)
, utilisezfor(;;)
, en sauvegardant un caractère :)la source
L'utilisation de l'opérateur virgule au lieu d'accolades ouvrantes et fermantes peut enregistrer quelques caractères, si vous avez une situation dans laquelle vos clauses contiennent plusieurs instructions:
contre.
Deux caractères enregistrés sur un IF simple ou trois au total pour un IF / ELSE.
En tant que point de distinction entre C et C ++, le résultat d'une expression de virgule en C ++ dans son ensemble peut être utilisé sous la forme d'une valeur lvalue ... FWIW.
la source
Puisque les éléments de tableau sont stockés directement les uns après les autres en mémoire, au lieu de quelque chose comme ceci:
Vous pouvez faire quelque chose comme ça:
Évidemment, ni l’un ni l’autre des éléments ci-dessus n’est golfé, par souci de lisibilité, mais l’utilisation explicite de pointeurs peut vous faire économiser beaucoup d’espace.
la source
for(int* i=array; i<array+25*25; i++)
? Ensuite, vous ne devez suivre qu'une seule variable.C’est une évidence, mais si vous utilisez beaucoup de la bibliothèque standard, vous
using namespace std;
pourriez économiser quelques caractères.la source
using std::name;
peut souvent être plus court.std::
cinq fois ou plus.Il est utile de se rappeler que
a[i]
c'est la même chose que*(a+i)
.Remplacez
a[0]
par*a
pour deux économies de caractères. En outre,a[i][0]
est équivalent à*a[i]
eta[0][i]
réduit ài[*a]
. Donc, si vous codez en dur un0
index dans votre tableau, il existe probablement une meilleure solution.la source
Au lieu d'écrire de grandes puissances de 10, utilisez la notation e . Par exemple,
a=1000000000
est plus long quea=1e9
. Cela peut être étendu à d'autres numéros, commea=1e9+24
c'est mieux quea=1000000024
.la source
1e9/x
n'est pas la même chose que1000000000/x
ouint(1e9)/x
.Vous pouvez utiliser l'opérateur ternaire
?:
sans aucune expression dans le bloc true (il enregistre un octet)Vérifiez ici
la source
Tête plus courte
Ceci est spécifique à GCC, il peut être extensible à d’autres compilateurs.
En-tête précompilé.
En G ++,
bits/stdc++.h
l'en-tête précompilé est constitué de tous les autres en-têtes. Si vous avez besoin deimport
2 types différents, vous pouvez simplement l'utiliser.En-tête plus court.
Ce sont tous les en-têtes répertoriés sur http://fr.cppreference.com/w/cpp/header :
Afficher l'extrait de code
triés par ordre croissant de longueur.
Certains d'entre eux sont déjà plus longs que
bits/stdc++.h
, et certains nécessitent le support de C ++ 17. Certains autres ne sont pas pris en charge par TIO G ++ (pour des raisons que je ne connais pas). Filtrez-les nous avons:Afficher l'extrait de code
Il se peut que certaines d’entre elles puissent être remplacées par des plus courtes. Juste recherche binaire si celle dont vous avez besoin peut être remplacée. En particulier:
la source
#import
au lieu de#include
vous donne un octet supplémentaire.De plus, le caractère espace entre
#import
et en-tête n'est pas nécessairement:Et si vous avez besoin de quelque chose à partir de
stdlib
header, vous pouvez importer n'importe quel en-tête avec un conteneur STL (préférableset
oumap
) au lieu decstdlib
.la source
Opérations arithmétiques sur les booléens:
Bien que
est mieux que
ce n'est pas aussi bon que
En outre, en utilisant #define sur tout ce qui est beaucoup utilisé. Il est souvent plus court que d'utiliser des fonctions, car les noms de type ne sont pas nécessaires.
Combinez les choses autant que possible:
est le même que
la source
x
de lvalue etx++
de rvalue. comportement indéfini et points de séquenceUtilisez des lambdas génériques comme modèles bon marché
Pour les types autres que
int
, les utiliser comme arguments de fonction peut être coûteux. Cependant, des lambdas génériques ont été introduits (en C ++ 14?) Et permettent à tout lambda d'être un modèle - utiliserauto
des types d'argument pour économiser des octets. Comparer:Les lambdas génériques sont également très pratiques pour accepter des itérateurs. Le meilleur moyen d’accepter les entrées de tableau en C ++ est probablement le suivant
[](auto a, auto z)
: oùa
etz
sont passés commebegin()
etend()
du tableau / vecteur / liste / etc.la source
Dans ma première tentative de code de golf pour la tâche "Soustraire les nombres suivants" je suis parti de la fonction (58 octets)
puis sécurisez 5 octets avec passage à lambda et initialisation déplacée hors de
for
(53)et finalement, après avoir basculé de
for
à,while
j'ai obtenu 51 octets:Le code de test ungolfed est quelque chose comme:
MISE À JOUR:
En fait ,
for
peut atteindre la même longueur quewhile
:la source
Un peu tard pour la fête je suppose ...
Si vous voulez transformer une expression en -1 et 1 au lieu de 0 et 1, au lieu de ceci:
faire ceci:
Cela peut économiser des octets en fonction de l'utilisation.
la source
int x=(a*10>5)*2-1;
, ne pourriez-vous pas faireint x=a*10>5?1:-1;
, ce qui est plus court d'un octet?Si vous voulez échanger deux variables entières a et b alors,
peut être utilisé en économisant 5 caractères par rapport à la méthode standard
la source
,t
au début créé ett=a;a=b;b=t;
aurait déjà été 3 octets plus court que lea+=b;b=a-b;a-=b;
. Pourtant, votrea^=b^=a^=b;
est encore plus court que cela, donc +1 de moi. Je ne connais pas le C ++, mais ça fonctionne . En tant que golfeur de code Java, je suis triste que cela ne semble pas fonctionner là-bas . :(a^=b;b^=a;a^=b;
fonctionne très bien en Java.a^=b;b^=a;a^=b;
fonctionne bien, mais est plus long que le,t
+t=a;a=b;b=t;
. Désolé de mentionner Java, car il est hors sujet ici. Mais bon conseil pour les codegolfeurs C ++!Utiliser les fonctions intégrées de GCC au lieu d'importer
Si vous utilisez un compilateur GCC, il est parfois utile d’utiliser leurs fonctions internes, telles que
__builtin_puts
ou__builtin_clz
. Par exemple,44 octets:
50 octets:
la source
Si vous utilisez C ++ 11 ou plus récent (ce qui devrait toujours être le cas maintenant), utilisez-le
auto
pour les types complexes, si possible.Exemple: 54 octets au lieu de 66
En outre, comme les performances importent peu, il est possible que, pour certains problèmes,
std::list
il ne vous reste plus qu'à faire le travail pour quelques octets en moins:la source
Les fonctions dans
<algorithm>
souvent requièrent des passesa.begin(),a.end()
vraiment longues, mais vous pouvez utiliser&a[0],&*end(a)
pour économiser 3 octets sia
estvector
oustring
.la source
Ne pas utiliser
string("")
, utilisez""
. Il sauve 8 octets.la source
"" + 'a'
estchar* + char
, ce qui est plus de pointeur, tout enstd::string("") + 'a'
eststd::string + char
- concaténation de chaînes.string()
travaillerait.