Le but de cet article est de rassembler tous les conseils de golf qui peuvent être facilement appliqués à <all languages>
un spécifique.
Poster uniquement des réponses indiquant que sa logique peut être appliquée à la plupart des langues
S'il vous plaît, un pourboire par réponse
<all languages>
...Réponses:
Fusionner des boucles
Vous pouvez généralement fusionner deux boucles consécutives, ou deux boucles imbriquées, en une seule.
Avant:
Après:
la source
foo
s'appellea
fois,bar
s'appelleb
fois. En effet, dans "après", la boucle exécute desa+b
temps, le premiera
appelfoo
, les suivantsbar
.for(y=0;y<Y;++y)for(x=0;x<X;++x)
peut souvent êtrefor(i=0;i<X*Y;++i)
avecx
remplacés pari%X
ety
remplacé pari/X
.Juste pour mentionner l'évidence:
Questionnez votre choix d'algorithme et essayez quelque chose de complètement nouveau.
Lorsque vous jouez au golf (des problèmes particulièrement difficiles entraînant des programmes plus longs), vous pouvez trop souvent vous en tenir au chemin que vous avez choisi au préalable sans essayer d’autres options fondamentales . Bien sûr, vous pouvez micro-golfer une ou plusieurs lignes à la fois ou une partie de l’idée générale, mais souvent, ne tentez pas une solution totalement différente.
Cela était particulièrement visible dans Hitting 495 (Kaprekar), où s'écarter de l'algorithme actuel et rechercher des motifs que l'on pouvait appliquer pour obtenir le même résultat était plus court dans de nombreuses langues (mais pas J).
L'inconvénient est que vous pouvez éventuellement résoudre la même chose une demi-douzaine de fois. Mais cela fonctionne vraiment dans toutes les langues sauf HQ9 + (où trouver un autre moyen de sortir Hello World serait un peu futile).
la source
Utiliser le développement piloté par les tests
Si le code doit gérer différentes entrées, alors écrivez des tests complets et facilitez leur exécution très rapidement. Cela vous permet d'essayer des transformations risquées, une étape à la fois. Le golf devient alors comme une refonte avec une intention perverse.
la source
Essayez de réduire les déclarations logiques
Par exemple, si
A
etB
sont des booléens et que votre langue considère les booléens comme des nombres dans une certaine mesureA and (not B)
etA>B
sont équivalents. Par exemple en Pythonest le même que:
la source
B>A or foo()
serait un moyen encore plus court d’exprimer cela, tirez parti de l’évaluation paresseuse des expressions booléennes pour s’assurer qu’elle ne calcule les choses que s’il le faut.B>A or foo
évalueraitfoo
siB==A
ce n'est pas ce que nous voulons. (Droit?)Initialisez les variables en utilisant les valeurs que vous avez déjà.
Au lieu de
x=1
, essayez de rechercher quelque chose qui est déjà égal à 1.Par exemple, la valeur de retour d'une fonction:
printf("..");x=0;
->x=!printf("..");
. C'est plus facile avec 0, parce que vous pouvez toujours nier, ou quand tout ce dont vous avez besoin est la bonne valeur de vérité (et ne vous souciez pas de savoir si c'est 1 ou 19).la source
Utilisez unaire
~
pourx+1
etx-1
Cette astuce s’applique aux langues qui ont un opérateur de négation
~
unaire unaire et un opérateur de négation régulière unaire-
.Si votre programme contient par hasard l'expression
-x-1
, vous pouvez la remplacer par~x
pour sauvegarder des octets. Cela ne se produit pas très souvent, mais regardez ce qui se passe si nous négons (-
) les deux expressions:x+1
égal à-~x
! De même,x-1
égal~-x
. (Pensez de quelle manière le tilde pointe: droite est+
, gauche est-
.)Ceci est utile car, dans toutes les langues auxquelles je peux penser, ces opérateurs ont une priorité plus élevée que la plupart des opérateurs. Cela vous permet d'économiser sur les parenthèses. Regardez comment nous économisons quatre octets ici:
la source
Squeeze les espaces
Connaître les règles pour les espaces dans votre langue. Certains signes de ponctuation, ou autres caractères, peuvent ne nécessiter aucun espace. Considérez cette fonction shell Bourne :
Dans Bourne Shell, ce
();
sont des métacaractères et ils n'ont pas besoin d'espaces. Cependant, il{}
existe des mots et des espaces, à moins qu'ils ne soient à côté de métacaractères. Nous pouvons jouer au golf à côté de 4 espaces();
, mais nous devons garder l’espace entre{
etecho
.Dans Common Lisp et PicoLisp ,
()
sont des métacaractères. Considérez ce code pour trouver la moyenne de deux nombres:Nous pouvons jouer au golf 2 espaces.
Certaines langues ont des règles étranges et subtiles pour les espaces. Considérez ce programme Ruby, qui affiche la somme et le produit d’une ligne d’entiers.
Chacun a
&
besoin d'un espace devant lui-même. En Ruby,i=$F.map &:to_i
signifiei=$F.map(&:to_i)
où&
passe un paramètre de bloc. Mais,i=$F.map&:to_i
signifiei=$F.map.&(:to_i)
où&
est un opérateur binaire.Cette bizarrerie se produit dans des langages, tels que Perl ou Ruby, qui utilisent une ponctuation ambiguë. En cas de doute, utilisez un REPL ou écrivez des programmes courts pour tester les règles d’espace.
la source
attribuer de nouveaux noms aux fonctions si utilisé plusieurs fois
la source
x
.Noms variables d'une seule lettre
Vous en avez 52; utilisez-les tous! N'ayez pas peur d'essayer différentes approches et de comparer les longueurs. Connaître la langue et les raccourcis / fonctions de bibliothèque disponibles.
la source
$
et_
peut être utilisé comme identifiant.@
est un nom de variable valide dans T-SQL, utilisez-le à la place de@a
.Utilisez l'opérateur conditionnel.
Un opérateur conditionnel
est plus bénéfique, caractère sage, qu'une déclaration IF .
peut être écrit comme
la source
a&&b||c
place. Un peu plus long, mais toujours plus court qu'unif
.Iff
, bien que ce soit une fonction, donc soumise à une évaluation de tous les arguments.if(a ? b : c)
a&&b||c
peut revenirc
quanda
est vrai si et sib
c'est faux, un petit cas limite, mais nous ne devrions pas l'oublier ^^Ecrire une explication de votre code
Ecrire une explication vous oblige à examiner à nouveau chaque partie de votre code et à rendre explicites vos pensées et vos choix en écrivant un certain passage. En faisant cela, vous pouvez trouver que différentes approches sont possibles, ce qui peut économiser certains octets, ou que vous avez inconsciemment émis des hypothèses qui ne sont pas nécessairement valables.
Cette astuce est similaire à Questionnez votre choix d’algorithme et essayez quelque chose de tout à fait nouveau ; Cependant, j’ai constaté qu’il est parfois crucial de noter comment chaque partie est censée fonctionner, pour prendre conscience des alternatives.
En prime, les réponses comprenant une explication sont plus intéressantes pour les autres utilisateurs et sont donc plus susceptibles d'être votées.
la source
Vérifiez votre nombre de personnages
Cela sonne comme une évidence, mais en faisant attention, vous pourrez peut-être "sauver" quelques personnages sans rien faire!
Si vous utilisez Windows, vous pouvez saisir
\r\n
au lieu de simplement\r
ou\n
lorsque vous appuyez sur Entrée - en ajoutant un octet supplémentaire par ligne! Tournez les caractères de contrôle pour vérifier que vous ne le faites pas.Dans Notepad ++, vous pouvez convertir toutes les
\r\n
fins de ligne en simplement\r
en allant àEdit > EOL Conversion > UNIX/OSX Format
.Assurez-vous également de ne pas inclure d'espaces de fin dans le nombre de vos personnages! Le saut de ligne sur la dernière ligne de votre code est également sans conséquence, vous n'avez donc pas besoin de le compter.
la source
Lire la question attentivement
Le golf de code consiste tout autant à comprendre la question (ce qui est demandé et ce qui n’est pas demandé, même si cela serait implicite dans tout autre paramètre) que de produire un code qui ne peut (que) satisfaire ce qui est demandé.
Toute entrée autre que celle explicitement demandée ne doit pas être traitée. S'il existe des cas de test et aucune exigence générique, votre code peut uniquement fonctionner dans ces cas. Etc.
la source
Utilisez les opérations au niveau des bits pour vérifier les nombres compris entre 0 et 2 n -1
Peut-être un peu un cas de pointe, mais il pourrait être utile parfois. Il repose sur le fait que tous les nombres auxquels m = 2 n -1 ont les n bits les plus à droite sont définis sur 1.
Ainsi, 7 10 == 00000111 2 , 15 10 == 00001111 2 , 31 10 == 00011111 2 et ainsi de suite.
Le truc c'est
x&~m
. Cela retournera vrai chaque fois quex
n'est pas compris entre 0 etm
(inclus) et faux sinon. Il enregistre 6 octets dans l'expression équivalente la plus courte suivante:,x>=0&&x<=m
mais ne fonctionne évidemment que lorsquem
satisfait 2 n -1.la source
Réutiliser des paramètres de fonction à la place de nouvelles variables
la source
main(i){...
vous avez maintenant une variable avec la valeur 1 sans avoir à faire des affectations. 2 caractères sauvegardés là-bas ..Plus grand / moins que pour enregistrer un chiffre:
Rappelez-vous simplement d’échanger le code entre
if
leelse
et ils feront exactement la même chose (ou inverseront les côtés de l’inégalité)!Remarque: ceci peut être appliqué avec n'importe quelle puissance de 10 et leurs négatifs:
...-100, -10, 10, 100...
(lien source)
la source
if(n>99999)
vsif(n<1e5)
Utilisez> et <au lieu de> = et <=
Lors de la vérification par rapport à des valeurs entières codées en dur, utilisez
>
et<
au lieu de>=
et<=
si possible. Par exemple, en utilisant2 octets de moins que d'utiliser
la source
<1
lieu de==0
zéro vérification (ou au>0
lieu de!=0
la vérification en miroir).x
être un entier?Évitez les ruptures de boucle prématurées
Si vous parcourez une boucle pour rechercher une ou plusieurs instances d'une vérification booléenne, un programme plus efficace pourrait permettre de sortir de la boucle avec la première valeur vraie. Toutefois, la suppression de la rupture et la mise en boucle de toutes les itérations permettent un code plus court.
la source
if
déclaration loin dans ces cas:m|=i>=100
. (Et vous pouvez également simplifier l'i>=100
à ,i>99
dans ce cas , mais ce n'est pas ici très pertinent)utiliser
-
au lieu de!=
pour les comparaisons numériques:
Si a est égal à b, il en
a-b
résulte une0
fausseté. Quelque chose d'autre que la0
vérité; doncsi utilisé dans un contexte booléen,
a-b
<=>a!=b
Si vous l'utilisez avec
if/else
ou avec l'opérateur ternaire, cela peut également vous faire économiser un octet pour l'égalité:a==b?c:d
<=>a-b?d:c
la source
Fractionner les chaînes pour les tableaux longs
La plupart des langues ont le moyen de diviser une chaîne en un tableau de chaînes autour d'un jeton. Cela sera inévitablement plus court qu'un littéral de tableau une fois que la longueur aura atteint un seuil dépendant de la langue, car le temps système supplémentaire par chaîne sera une copie d'un jeton à un caractère plutôt que (au moins) deux délimiteurs de chaîne.
Par exemple dans GolfScript
devient
Pour certaines langues, le seuil est aussi bas qu'une chaîne. Par exemple à Java,
devient
la source
%w{Foo Bar Baz Quux}
.qw(Foo Bar Baz Quux)
devient une liste de chaînes.Comprendre ce que les autres ont fait
En plus d'être amusant, si vous examinez le code d'autres personnes, vous pouvez parfois découvrir un bon algorithme auquel vous n'avez pas pensé, ou une astuce (parfois évidente) que vous oubliez.
Parfois, il existe une réponse que vous pouvez traduire dans une autre langue et bénéficier des avantages de cette dernière.
la source
connaître votre priorité d'opérateur
Chaque fois que vous combinez plusieurs expressions, consultez le tableau de priorité des opérateurs de votre langue pour savoir si vous pouvez réorganiser les éléments pour enregistrer les parenthèses.
Exemples:
(a&b)&&c
ne nécessite pas de parenthèses:a&b&&c
tout comme(a*b)+c
ne le fait pas.a+(b<<c)
peut être réécrit commea+b*2**c
.Cela n’économise rien pour cet exemple, mais il le sera s’il
c
s’agit d’un petit littéral entier (<14).a<b&&c<d
aveca<b&c<d
(sauf si vous avez besoin de l'évaluation du court-circuit).la source
Des boucles plus courtes
Si vous avez des
X
instructions{
dans}
votre boucle for, vous pouvez déplacer desX-1
instructions(
dans)
la boucle for après le deuxième point-virgulefor(blah;blah;HERE)
pour enregistrer 3 octets. (séparez les déclarations en utilisant une virgule,
)Au lieu de
vous pouvez déplacer l'une des déclarations dans les
(
accolades de la boucle for,)
tout en laissant l'autreet économisez 3 octets (sauvegardez 1 octet supplémentaire grâce à @ETHProductions)
Mettre tout simplement,
au lieu de
déplacez les déclarations afin que vous vous retrouviez avec cette
et économisez 3 octets
la source
for
est la déclaration finale, le;
devient optionnelUtilisez unaire
~
poura-b-1
eta+b+1
En plus des suggestions de @Lynn concernant
x+1
→-~x
; etx-1
→~-x
, vous pouvez aussi jouer au golfa-b-1
eta+b+1
.Cela peut ressembler à un conseil que vous n'utiliserez pas très souvent, un peu comme si vous utilisiez
~x
au lieu de-x-1
ne pas arriver souvent, mais je l'ai déjà utilisé suffisamment de fois pour le voir comme un conseil utile ici. Surtout avec l'indexation par tableau, vous pouvez utiliser les exemples ci-dessus dans certains cas.la source
Compresse ou / et traînées
Truc simple que j'ai trouvé en essayant de réduire une longue série de conditions enchaînées par ands (ou ors, dans ce cas, remplacez simplement "all" par "any").
Par exemple:
Devient
la source
all(array-of-Booleans)
intégrées?[a>0,a<10,a+b==4,a+3<1].all?
if 10>a>0 and a+b==4>1>a+3:
Fiez-vous au compilateur pour fournir les performances requises.
Assurez-vous de savoir quelles optimisations sont garanties par le compilateur et à quels niveaux d'optimisation, et utilisez-les généreusement. Et même si les performances ne sont pas une
préoccupation, vous pouvez toujours tester avec des optimisations, puis ne négligez qu'un seul caractère, car votre code est toujours valide sur le plan technique sans l'indicateur de compilation.Considérez la fonction Haskell suivante pour calculer 2 ^ n (en ignorant le fait que Haskell a déjà un opérateur d’exponentiation intégré ou trois) (23 caractères):
Le problème est que - c'est terriblement lent, ça tourne dans le temps exponentiel. Cela pourrait rendre votre code non testable ou échouer les contraintes de performance données par la question. Vous pourriez être tenté d'utiliser une variable temporaire ou un littéral de fonction immédiatement appelé pour éviter les appels de fonction répétés (25 caractères):
Mais le compilateur peut déjà le faire pour vous, il vous suffit de le définir
-O
comme indicateur de compilateur! Au lieu de dépenser quelques caractères supplémentaires par site pour éliminer manuellement les sous-expressions courantes, il vous suffit d'indiquer au compilateur de faire les optimisations de base à votre place pour un total de un ou deux caractères sur l'ensemble du programme.la source
p(x-1)*2
?Peut-être un peu évident mais ...
Utiliser les valeurs de retour d'opérateur
Gardez à l'esprit que l'opérateur d'affectation renvoie une valeur!
Par exemple, si vous voulez ajouter y à x et vérifier si x est supérieur à quelque chose, vous pouvez faire
au lieu de
Ou peut-être souhaitez-vous trouver la longueur d'une chaîne après l'avoir coupée:
Plutôt que
la source
a = (b=c)+1;
définitb
surc
, puis définita
surb+1
.a=1+b=c
. Et vous pouvez ajouter PHP et JavaScript à votre liste.=
opérateur une priorité plus élevée sur la gauche que sur la droite. Il1+x=2
est donc valide et est évalué à3
Utiliser les bizarreries / nouvelles fonctionnalités de la langue / du compilateur / de l'environnement
Ceci est particulièrement utile pour les polyglottes , mais peut s’appliquer à d’autres défis. Parfois, un bogue du compilateur peut ignorer un octet, un bogue d'implémentation peut vous permettre de sauvegarder quelques caractères, ou une fonctionnalité très avancée peut améliorer votre score.
la source
Combinez plusieurs / imbriqués si des vérifications utilisant Et / Ou lorsque cela est possible.
c'est à dire:
au lieu de:
la source
&
, `|) pour supprimer plus de caractères.&
au lieu de&&
supprimer 1 caractère dans certains cas, cela gâche la priorité de l'opérateur et vous devrez mettre des parenthèses pour que cela fonctionne. Utilisez-le à bon escient.Trouvez de meilleurs moyens d'initialiser vos variables
Quelques autres réponses étaient sur le point de le mentionner déjà, mais dans beaucoup de langues (strictement typées?), Il est plus court d'initialiser
x
une chaîne vide comme:ou en
x
tant que rune vide (personnage) comme:que
et
L'utilisation de valeurs préexistantes est évidemment préférable, mais pas si facile.
la source