Conseils pour jouer au golf dans <toutes les langues>


81

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


5
"Majorité" par quelle métrique?
cessé de tourner dans le sens anti-horaire

2
@leftaroundabout par la métrique du même mot
ajax333221

8
Le problème est que beaucoup de langages sont expérimentaux (souvent de courte durée) avec des paradigmes très atypiques, pour lesquels les expressions de programmation typiques n'ont aucun sens. Donc, "la majorité de toutes les langues", il est pratiquement impossible à remplir. Vous devriez le restreindre d'une certaine manière, par exemple à "la majorité des langues utilisées régulièrement sur codegolf.SE". Pour le moment, les réponses ressemblent beaucoup à "la majorité des langues dérivées à distance de C", mais celles-ci, bien que la grande majorité de tout le code écrit y soit écrit, ne sont pas la majorité des langues .
cessé de tourner dans le sens anti-horaire

3
leftroundabout, je suppose que nous savons tous ce qu’ils veulent dire. Il s’agit essentiellement d’optimisations indépendantes du langage, c’est-à-dire non seulement utiles dans Brainfuck, mais peut-être aussi Python, C, Java et Fortran à la fois. Idées générales que vous pouvez appliquer dans de nombreuses langues et qui fonctionnent de la même manière. Je ne pense pas qu'il soit nécessaire d'être aussi précis et spécifique dans les astuces et les questions de CW. Il s’agit d’aider les autres à jouer au golf et non de les faire chier.
Joey

14
Espérons que personne ne crée un langage appelé <all languages>...
mbomb007 4/04/16

Réponses:


72

Fusionner des boucles

Vous pouvez généralement fusionner deux boucles consécutives, ou deux boucles imbriquées, en une seule.

Avant:

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

Après:

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

Ugoren les boucles ne sont toujours pas les mêmes. @ Gaffi a raison.
KaoD

5
@kaoD, dans les deux cas foos'appelle afois, bars'appelle bfois. En effet, dans "après", la boucle exécute des a+btemps, le premier aappel foo, les suivants bar.
Ugoren

Je regarde cela à nouveau (beaucoup, beaucoup plus tard), et je ne comprends pas ma propre question maintenant. J'ai peut-être pas compris l'opération ternaire avant? La façon dont je vois les choses maintenant a du sens.
Gaffi

1
Woops, j'ai lu ça très tard dans la nuit. Vous avez raison!
KaoD

3
Très similaire: for(y=0;y<Y;++y)for(x=0;x<X;++x)peut souvent être for(i=0;i<X*Y;++i)avec xremplacés par i%Xet yremplacé par i/X.
Lynn

62

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


12
+1 En plus d'être bon pour le golf, c'est un bon exercice pour tout programmeur dans de nombreuses situations du monde réel!
Gaffi

52

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.


4
J'utilise une retombée de cette méthode. Comme les problèmes eux-mêmes sont généralement assez simples, j’écris un programme qui fait le travail. Habituellement, cela est "lisible au golf", de sorte que c'est succinct, mais les nouvelles lignes, etc. sont là. Je copie ce fichier dans un nouvel emplacement et le lance, vérifiant de temps en temps que les programmes renvoient les mêmes valeurs pour certaines entrées choisies. Si jamais je fais une erreur en me laissant avec un programme cassé, sans souvenir de ce que j'ai changé et sans compréhension de mon morceau joué au golf, j'ai une sorte de "spécification" sauvegardée en tant que source de référence.
Shiona

2
J'aime cette méthode, qui est l'une des raisons pour lesquelles j'ai tendance à inclure des suites de tests complètes pour tous les problèmes que j'écris.
Joey

@RubberDuck Le principe « Ne te répète pas » est souvent strictement suivi.
Jonathan Frech

48

Essayez de réduire les déclarations logiques

Par exemple, si Aet Bsont des booléens et que votre langue considère les booléens comme des nombres dans une certaine mesure A and (not B)et A>Bsont équivalents. Par exemple en Python

if A and not B:
    foo()

est le même que:

if A>B:
    foo()

3
Je n'aurais jamais pensé à ça.
cjfaure

27
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.
Scragar

5
@ scragar: Correct, mais ce n'est pas le but de cette astuce. (C'est un conseil indépendant précieux cependant.)
Wrzlprmft le

3
@ scragar, B>A or fooévaluerait foosi B==Ace n'est pas ce que nous voulons. (Droit?)
msh210

2
De plus, si vous avez de longues conditions imbriquées (par exemple avec 5/6 paramètres), vous pouvez utiliser une table de vérité et une carte de Karnaugh pour trouver l'expression booléenne la plus courte
Katenkyo

33

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


4
voir C
std''OrgnlDave

1
@ std''OrgnlDave, c'est vrai, mais cette question concerne des choses communes à toutes les langues.
Ugoren

33

Utilisez unaire ~pour x+1etx-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 ~xpour 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:

(x+1)*(y-1)     ==>    -~x*~-y

30

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 :

f () { echo a; echo b; }

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

f(){ echo a;echo b;}

Dans Common Lisp et PicoLisp , ()sont des métacaractères. Considérez ce code pour trouver la moyenne de deux nombres:

(/ (+ a b) 2)

Nous pouvons jouer au golf 2 espaces.

(/(+ a b)2)

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.

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

Chacun a &besoin d'un espace devant lui-même. En Ruby, i=$F.map &:to_isignifie i=$F.map(&:to_i)&passe un paramètre de bloc. Mais, i=$F.map&:to_isignifie i=$F.map.&(:to_i)&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.


1
Pourquoi faut-il un espace entre "{" et "echo", mais pas entre ";" et "echo"?
Ryan

3
J'ai utilisé les termes du manuel pour OpenBSD sh (1), qui dit que "{" est un mot réservé et ";" est un méta-personnage. Pour cette raison, "{écho" est un mot mais "; écho" est deux mots. D'autres manuels pourraient expliquer cela différemment. En outre, le shell Zsh zsh a des règles différentes.
Kernigh

28

attribuer de nouveaux noms aux fonctions si utilisé plusieurs fois

x = SomeLongFunctionName
x(somedata)
x(somemoredata)
etc

Seulement si nous utilisons assez d’appels pour x.
Elipszilon

28

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.


8
26 pour les langages non sensibles à la casse. :-)
Gaffi

12
Souvent $et _peut être utilisé comme identifiant.
Griffin

4
@Gaffi: Et plus que suffisant pour les langues autorisant les identifiants Unicode, à moins que la tâche ne vous limite à ASCII ou ne compte pas d'octets, mais plutôt de caractères.
hammar

Si vous comptez les octets au lieu de l'unicode, utiliser l'ASCII étendu pourrait être un moyen de réduire environ 120 autres identifiants si vous en avez besoin (pas de toute façon pour un script de golf)
scragar le

2
@est un nom de variable valide dans T-SQL, utilisez-le à la place de @a.
BradC

25

Utilisez l'opérateur conditionnel.

Un opérateur conditionnel

bool ? condition_true : condition_false

est plus bénéfique, caractère sage, qu'une déclaration IF .

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

peut être écrit comme

r=a>b?a:b;

25
Les langues qui n'ont pas de ternaire peuvent utiliser à la a&&b||cplace. Un peu plus long, mais toujours plus court qu'un if.
Michael Kohl

Là encore, certains ne peuvent utiliser aucune de ces options (VBA me vient à l’esprit), mais les deux suggestions restent valables. :-)
Gaffi

1
Gaffi: VBA a Iff, bien que ce soit une fonction, donc soumise à une évaluation de tous les arguments.
Joey

L'utilisation de ternary dans les déclarations if peut également être très utileif(a ? b : c)
Jojodmo

4
@MichaelKohl note que a&&b||cpeut revenir cquand aest vrai si et si bc'est faux, un petit cas limite, mais nous ne devrions pas l'oublier ^^
Katenkyo

24

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.


23

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\nau lieu de simplement \rou \nlorsque 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\nfins de ligne en simplement \ren 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.


Je ne pense pas avoir jamais vu un cas où cela a réellement compté ...
Jacob

4
Je viens d'avoir ce problème moi-même (par conséquent, pourquoi je l'ajoute).
Sean Latham

21

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.


15
Je pense qu'un meilleur titre ici serait "Ne traitez pas les cas non obligatoires". L'expression "Essayer de trouver des échappatoires" évoque des moyens d'éviter de procéder de la sorte à une réinterprétation astucieuse des règles, alors que ce que vous proposez est simplement le bon conseil pour ne pas trop implémenter votre solution.
Jonathan Van Matre

1
Oui, mais une réinterprétation astucieuse des règles fait également partie du code golf! (0 solutions, etc.)
Tobia

8
Ce serait / devrait être une réponse différente, cependant. Par exemple, il existe une différence fondamentale entre, par exemple, l’implémentation d’une solution ne fonctionnant que pour ints car OP n’exige pas de prise en charge flottante, et une réponse indiquant le texte "tout nombre supérieur à 100", car "vous n’avez pas dit qu’il fallait le faire." être un nombre premier réel ".
Jonathan Van Matre

Je pense que certains PO incluent un avis "Les cas de test sont sujets à modification; votre code doit toujours fonctionner après le changement", et réellement les modifier s'ils ne voient qu'une seule réponse coder en dur les cas de test.
Erik l'Outgolfer

20

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 que xn'est pas compris entre 0 et m(inclus) et faux sinon. Il enregistre 6 octets dans l'expression équivalente la plus courte suivante:, x>=0&&x<=mmais ne fonctionne évidemment que lorsque msatisfait 2 n -1.


18

Réutiliser des paramètres de fonction à la place de nouvelles variables


1
Par exemple, en C, votre fonction principale reçoit toujours le nombre d’arguments fournis au programme (qui est 1 - le nom du programme - par 'défaut'). Ainsi, main(i){...vous avez maintenant une variable avec la valeur 1 sans avoir à faire des affectations. 2 caractères sauvegardés là-bas ..
Griffin

6
Je pense que c'est assez spécifique au C. Les langages de script n'ont pas besoin de déclarations et, dans la plupart des langages compilés, définir une variable ne dépasse pas la définition d'un paramètre.
Ugoren

en java lorsque vous avez besoin d'un tableau dans une fonction qui a le même type qu'un paramètre, vous pouvez économiser quelques octets en plaçant ce paramètre en dernier et en faisant un paramètre vararg; (utilisé cela pour supprimer quelques octets sur une fonction pour trouver le mot le plus long d'une phrase)
masterX244

18

Plus grand / moins que pour enregistrer un chiffre:

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

Rappelez-vous simplement d’échanger le code entre ifle elseet 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)


Je ne suis pas sûr de comprendre le but de ceci. De quoi cela réduit-il?
Gaffi

@ Gaffi vous enregistrez un caractère et ils font exactement la même chose
ajax333221

contre quelle alternative? Désolé, ne pas essayer d'être obstiné, je ne comprends pas. (newb, ici, apparemment ...)
Gaffi

1
Ah, je vois. Fonctionne sur toute transition entière de 9 à 10, de 99 à 100, etc. Désolé, cela m'a pris si longtemps! (Je ne dis que des nombres entiers, car je vois un problème avec n = 9,5 ...)
Gaffi

8
Également dans certaines langues (si elles sont prises en charge), si vos nombres sont suffisamment grands / petits, la notation scientifique peut en réalité vous faire économiser des caractères: if(n>99999)vsif(n<1e5)
scragar

16

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 utilisant

if(x>24&&x<51)

2 octets de moins que d'utiliser

if(x>=25&&x<=50)

3
Related: Si vous êtes sûr un résultat ne peut pas être négatif, vous pouvez utiliser au <1lieu de ==0zéro vérification (ou au >0lieu de !=0la vérification en miroir).
Kevin Cruijssen

1
Ne devriez-vous pas ajouter une note sur le fait d' xêtre un entier?
Zacharý

15

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

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;
}

5
Vous pouvez également simplifier la ifdéclaration loin dans ces cas: m|=i>=100. (Et vous pouvez également simplifier l' i>=100à , i>99dans ce cas , mais ce n'est pas ici très pertinent)
marinus

15

utiliser -au lieu de!=

pour les comparaisons numériques:

Si a est égal à b, il en a-brésulte une 0fausseté. Quelque chose d'autre que la 0vérité; donc
si utilisé dans un contexte booléen, a-b<=>a!=b

Si vous l'utilisez avec if/elseou avec l'opérateur ternaire, cela peut également vous faire économiser un octet pour l'égalité:
a==b?c:d<=>a-b?d:c


12

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

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

devient

"Foo
Bar
Baz
Quux"n/  # 20 chars

Pour certaines langues, le seuil est aussi bas qu'une chaîne. Par exemple à Java,

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

devient

"Foo".split("~")  // 16 chars

6
L'exception notable est Ruby, qui fournit une chaînes-de-littéral de tableau qui divise automatiquement sur les espaces au coût de deux octets: %w{Foo Bar Baz Quux}.
Martin Ender

1
Perl fournit quelque chose de similaire: qw(Foo Bar Baz Quux)devient une liste de chaînes.
BenGoldberg

12

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.


10

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:

  • Dans toutes les langues que je connais, les opérateurs au niveau des bits ont une priorité plus élevée que les opérateurs booléens: (a&b)&&cne nécessite pas de parenthèses: a&b&&ctout comme (a*b)+cne le fait pas.
  • a+(b<<c)peut être réécrit comme a+b*2**c.
    Cela n’économise rien pour cet exemple, mais il le sera s’il cs’agit d’un petit littéral entier (<14).
  • Les opérations au niveau des bits ont une priorité inférieure à la plupart des opérations arithmétiques, donc si votre langage convertit implicitement boolean en entier, vous pouvez enregistrer un octet a<b&&c<davec a<b&c<d(sauf si vous avez besoin de l'évaluation du court-circuit).

7

Des boucles plus courtes

Si vous avez des Xinstructions {dans }votre boucle for, vous pouvez déplacer des X-1instructions (dans )la boucle for après le deuxième point-virgule for(blah;blah;HERE)pour enregistrer 3 octets. (séparez les déclarations en utilisant une virgule ,)

Au lieu de

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

vous pouvez déplacer l'une des déclarations dans les (accolades de la boucle for, )tout en laissant l'autre

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

et économisez 3 octets (sauvegardez 1 octet supplémentaire grâce à @ETHProductions)


Mettre tout simplement,

au lieu de

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

déplacez les déclarations afin que vous vous retrouviez avec cette

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

et économisez 3 octets


@ETHproductions Merci d'avoir joué un conseil de golf :)
Kritixi Lithos

Et si le forest la déclaration finale, le ;devient optionnel
elipszilon

7

Utilisez unaire ~pour a-b-1eta+b+1

En plus des suggestions de @Lynn concernant x+1-~x; et x-1~-x , vous pouvez aussi jouer au golf a-b-1et a+b+1.

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

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

Cela peut ressembler à un conseil que vous n'utiliserez pas très souvent, un peu comme si vous utilisiez ~xau lieu de -x-1ne 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.


6

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:

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

Devient

if all([a>0,a<10,a+b==4,a+3<1]):

C'est cool, je vais devoir l'essayer!
Stokastic

4
Quelles sont les langues all(array-of-Booleans)intégrées?
Peter Taylor

3
Ruby l'a. [a>0,a<10,a+b==4,a+3<1].all?
Kernigh

4
Bien que si c'était Python, vous utiliseriez quelque chose comme:if 10>a>0 and a+b==4>1>a+3:
Sp3000

@PeterTaylor Haskell a aussi
fier haskeller

6

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

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

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

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

Mais le compilateur peut déjà le faire pour vous, il vous suffit de le définir -Ocomme 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.


@ETHproductions Oui, désolé, je l'ai fait
John Dvorak, le

Le premier exemple ne devrait-il pas simplement être p(x-1)*2?
Cyoce

5

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

if(25<x+=y)

au lieu de

x+=y;if(x>25)

Ou peut-être souhaitez-vous trouver la longueur d'une chaîne après l'avoir coupée:

strlen(s=trim(s))

Plutôt que

s=trim(s);strlen(s)

Dans quelle langue pouvez-vous effectuer une affectation dans un appel? ou est-ce un mot clé arg?
Chat

2
Je pense que les assignations sont des expressions (avec la nouvelle valeur de la variable affectée comme valeur d'expression) au moins en C, C ++, C # et Java. a = (b=c)+1;définit bsur c, puis définit asur b+1.
Lynn

@ Lynn Essayez a=1+b=c. Et vous pouvez ajouter PHP et JavaScript à votre liste.
Titus

2
Ruby fait le meilleur. Il donne à l' =opérateur une priorité plus élevée sur la gauche que sur la droite. Il 1+x=2est donc valide et est évalué à3
Cyoce 7/02/17

@Cyoce autant que je sache, c'est ainsi dans toutes les langues où une affectation est une expression.
Titus

5

Utiliser les bizarreries / nouvelles fonctionnalités de la langue / du compilateur / de l'environnement

Ceci est particulièrement utile pour les , 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.


4

Combinez plusieurs / imbriqués si des vérifications utilisant Et / Ou lorsque cela est possible.

c'est à dire:

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

}

au lieu de:

if (a) {
    if (b) {
        //Do Stuff
    } elseif (c) {
        //Do same stuff
    }
}

5
Utilisez également bitty conditionals ( &, `|) pour supprimer plus de caractères.
FUZxxl

2
Bien que l'utilisation au niveau des bits &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.
DollarAkshay

4

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 xune chaîne vide comme:

x:=""

ou en xtant que rune vide (personnage) comme:

x:=''

que

var x string

et

var x rune

L'utilisation de valeurs préexistantes est évidemment préférable, mais pas si facile.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.