Conseils pour jouer au golf à INTERCAL

10

Quels conseils généraux avez-vous pour jouer au golf à INTERCAL ? Je recherche des idées qui peuvent être appliquées aux défis de golf de code et qui sont également au moins quelque peu spécifiques à INTERCAL (c'est-à-dire que "supprimer les commentaires" n'est pas une réponse utile).

Je sais que les langues exotiques peuvent être vraiment utiles pour gagner des concours de golf, mais je ne vois pas beaucoup de code INTERCAL ici. Avez-vous des conseils qui peuvent aider les gens à obtenir des tailles de code compétitives avec INTERCAL? Cette langue pourrait-elle jamais être compétitive?

INTERCAL est tellement sous-utilisé qu'il n'a même pas de balise. Si triste...

Baconaro
la source
La plupart des langues n'ont pas ou n'ont pas besoin de leurs propres balises ici, car les défis spécifiques à la langue sont généralement découragés.
Alex A.
9
Un indice que ce n'est peut-être pas la meilleure langue de golf, à partir de sa page wikipedia:Despite the language's intentionally obtuse and wordy syntax,
isaacg

Réponses:

2

La suppression des espaces / du "bruit" peut aller plus loin que vous ne le pensez

INTERCAL est un langage insensible aux espaces. Contrairement à la plupart des langages insensibles aux espaces, l'insensibilité va beaucoup plus loin que vous ne le pensez.

Par exemple, il DO NOTs'agit de deux jetons, mais il peut être écrit DONOTsans que l'analyseur se plaint (dans pratiquement toutes les implémentations largement utilisées). (Bien sûr, vous pouvez également écrire DON'T, mais ce n'est pas plus tordu. Cela pourrait être plus facile à lire, cependant. PLEASEN'TEst probablement plus difficile à lire que PLEASE NOT, cependant.) En fait, il y a un débat quant à savoir si les espaces blancs font quelque chose; au moins un analyseur INTERCAL le permet même à l'intérieur des constantes numériques (pas que ce soit très utile lors du golf). Une chose à garder à l' esprit est que la suppression des espaces de DO READ OUTdonne qui peut confondre certains parseurs anciens INTERCAL en raison de l'embarquéDOREADOUTDO(bien que leurs auteurs considèrent généralement cela comme un bogue, et donc de nos jours cela fonctionne généralement dans un programme valide, il n'est pas conseillé de mettre un code comme celui-ci au voisinage d'une erreur de syntaxe, car il peut être beaucoup plus difficile de lever l'ambiguïté alors).

N'oubliez pas non plus que vous pouvez surcharger les caractères pour économiser de l'espace. En ASCII, vous ne pouvez vraiment retirer cela qu'avec '.!, mais c'est une astuce très utile en soi. (Lorsque vous n'utilisez pas de tableaux, il n'y a aucune possibilité d'ambiguïté de sparkears même lorsque tous vos caractères de regroupement sont les mêmes, donc pour les entrées de golf, il est recommandé de s'en tenir à 'moins qu'un indice de tableau ne nécessite vraiment un ".) Un rat de bibliothèque peut être représenté dans un octet en utilisant l' ?abréviation (C-INTERCAL) ou Latin-1 pour ¥(CLC-INTERCAL), plutôt que les trois dont INTERCAL-72 a besoin.


la source
2

Concentrez-vous sur le plus de travail possible en une seule déclaration

Les identificateurs de déclaration d'INTERCAL sont assez verbeux; DOest deux caractères de bruit sur chaque déclaration, le nom de la déclaration lui-même a également tendance à être assez long, et vous devez ajouter un de PLEASEtemps en temps pour garder l'analyseur heureux. (Le mieux que vous puissiez faire est un rapport de quatre DOpour un PLEASE, ce qui signifie que vous utilisez 14 caractères dans les identificateurs pour 5 commandes.) D'un autre côté, la syntaxe de l'expression est assez concise (ridicule, mais concise). Cela signifie qu'il est souvent utile d'intégrer une partie de votre programme dans une seule expression, même si l'utilisation de plusieurs instructions serait une manière plus «naturelle» de faire les choses.

Par exemple, si vous souhaitez attribuer #1à .1et #2à .2, au lieu de le faire de la manière évidente INTERCAL-72:

DO.1<-#1DO.2<-#2

il vaut vraiment la peine d'envisager de surcharger une variable aléatoire pour vous permettre d'affecter les deux à la fois:

DO:1<-#1$#2

(avec :1/!1$.2'jeté quelque part plus tôt dans le programme; notez que cette notation est postérieure à INTERCAL-72 d'une certaine manière, vous devrez donc utiliser un INTERCAL moderne pour que cela fonctionne). Cela n'est que légèrement plus long, même si vous tenez compte de la configuration, et devient plus court si vous en avez besoin ou si vous pouvez vous en occuper simultanément .1et à .2plusieurs reprises.

Il ne s'agit pas seulement de calculer les commandes où cette astuce fonctionne. Si vous devez cacher une variable deux fois, ne le faites pas comme ceci:

DOSTASH.1DOSTASH.1

mais comme ça:

DOSTASH.1+.1

(La +notation fonctionne pour la plupart des commandes où elle pourrait avoir un sens conceptuel.)


la source
2

Utilisez un seul CV pour tous les modèles INTERCAL-72 en cas de restructuration

Si vous devez écrire l'équivalent d'une instruction "if", la méthode normale utilisant le code INTERCAL-72 est de faire NEXTdeux fois, puis de faire un calcul RESUME. (Dans le code moderne, souvent un calcul COME FROMsera meilleur, mais cette astuce suppose que votre code préfère NEXT.) Vous devez presque certainement payer les octets pour le premier NEXT, car il saute d'une branche du "si" à l'autre. Partager le second NEXTn'est pas non plus trivial, sauf si vous avez beaucoup de déclarations «si» qui vont au même endroit en voyant a #1. Cependant, le RESUMEpeut être n'importe où dans le programme (car le contrôle va le laisser instantanément n'importe où).

Il y a deux façons de gérer cela. Si vous avez beaucoup d'instructions "si", alors le RESUMEgarantit probablement un numéro de ligne à un chiffre, de sorte que votre deuxième NEXTinstruction puisse être aussi courte que possible. Si possible, essayez d'en faire un calcul RESUMEqui se produirait naturellement dans votre code (certes, c'est difficile, car il est rare que ceux-ci apparaissent dans le "flux normal" de code plutôt que d'être NEXTédités); alors, le seul coût est le numéro de ligne. Vous devrez utiliser une seule variable booléenne pour tous ces NEXTs; le consensus universel ici est d'utiliser .5, principalement parce que c'est la variable que la bibliothèque standard utilise pour les valeurs de retour booléennes.

Alternativement, il est possible d'utiliser une fonctionnalité non documentée (techniquement sous-documentée, car j'ai glissé un indice dans la documentation INTERCAL lorsque j'ai remarqué) de la bibliothèque standard. Parce qu'un emplacement central pour a RESUMEest si utile, la bibliothèque standard en utilise un en interne. Les numéros de ligne dans INTERCAL sont globaux (avec des conventions d'espacement de noms, mais qui peuvent être rompus si vous savez ce que vous faites), vous pouvez donc accéder NEXTdirectement aux internes de la bibliothèque standard si vous le souhaitez, et en particulier, NEXTà son emplacement central de CV . Ceci est suffisamment populaire dans le code INTERCAL existant pour que les remplacements de bibliothèque standard aient tendance à l'implémenter pour éviter de casser les programmes existants.

La ligne en question est (littéralement ou efficacement, selon la mise en œuvre):

(1001) DO RESUME .5

La principale raison de ne pas l'utiliser est son numéro de ligne longue; si vous avez besoin de faire beaucoup de constructions if de style INTERCAL-72, il sera préférable d'utiliser la vôtre pour lui donner un nombre plus court.

Bien sûr, vous pouvez combiner les techniques en écrivant quelque chose comme

(9)DO(1001)NEXT

qui n'est que légèrement plus longue que

(9)DORESUME.5

et a l'avantage que les booléens deviennent #2et #3(ce qui est plus difficile à lire, mais normalement plus facile à générer). En fait, cela pourrait même valoir la peine de mettre du code supplémentaire à gérer #0et #1si vous allez beaucoup différer (mais le calcul COME FROMfonctionnera probablement mieux dans ce cas, sauf si vos exigences sont très étranges).


la source
2

INTERCAL ne spécifie pas de priorité, mais il ne fait pas non plus d' erreur sur la priorité ambiguë

Une expression comme

#1$#2~#3

est ambigu et pourrait signifier

'#1$#2'~#3

ou

#1$'#2~#3'

La spécification INTERCAL ne permet pas de savoir ce qui est voulu, et en général il n'y a pas de norme (bien que C-INTERCAL et CLC-INTERCAL s'efforcent de se faire correspondre dans les cas les plus simples). Cela dit, l'original n'est pas incorrect ; c'est ambigu et je ne conseillerais pas de l'utiliser dans le code de production (mais alors, je ne conseillerais pas d'utiliser INTERCAL lui-même dans le code de production), mais cela aura un certain sens dans la majorité des compilateurs.

En d'autres termes, il peut être utile de simplement supprimer les caractères de regroupement et d'espérer que votre programme fonctionne toujours. La plupart des interprètes analysent systématiquement toute expression ambiguë donnée, donc pour chaque paire de caractères de regroupement, il y a 1 chance sur 2 que ce n'est pas nécessaire; cela peut représenter pas mal d'économies. (Malheureusement, parseurs INTERCAL ont tendance à être assez déroutant que personne est tout à fait sûr de ce que les règles en fait sont , mais il peut normalement être déterminées par l' expérience. Dans les cas les plus simples, les opérateurs ont tendance à tous ont la même priorité et d'avoir une associativité cohérente.)


la source
2

Dans C-INTERCAL, envisagez d'abréger le code à l'aide de CREATE

L' CREATEinstruction vous permet de créer une nouvelle syntaxe. Ceci est particulièrement utile dans le golf car il vous permet de donner des noms plus courts aux déclarations. Vous pouvez également l'utiliser pour "définir une fonction" de manière efficace en créant un nouvel opérateur (ce qui a l'énorme avantage qu'il vous permet d'appeler la fonction au milieu d'une expression).

Le coût de configuration ici est assez élevé, mais s'il existe une construction que vous utilisez beaucoup, inventer une syntaxe plus courte sera probablement une bonne idée.


la source