Conseils pour jouer au golf à Brachylog

19

Brachylog est un langage qui commence à prendre de l'importance dans le golf de code récemment (et vient de recevoir une mise à jour majeure avec une syntaxe terser). Comme Prolog, il a l'avantage de pouvoir souvent résoudre un problème (généralement via la force brute) simplement à partir d'une description suffisamment précise de ce à quoi ressemble un problème, une caractéristique qui signifie que sur le bon type de défi, il est souvent comparable au les meilleures langues de golf (et est connu pour battre Jelly de temps en temps).

Quels conseils avez-vous pour jouer au golf (c.-à-d. Écrire les programmes les plus courts possibles) dans Brachylog? Il s'agit principalement de conseils spécifiques à Brachylog en particulier, plutôt que de conseils applicables à un large éventail de langues. (Des conseils sur le golf dans les langues déclaratives en général peuvent potentiellement être appropriés ici, selon le niveau d'application qu'ils auront dans des langues autres que Brachylog, bien que voir également Conseils pour jouer au golf dans Prolog .)

Communauté
la source

Réponses:

4

Exploitez les prédicats imbriqués pour créer de nouvelles variables

Brachylog a beaucoup de cas de syntaxe spéciaux pour rendre ses deux variables spéciales ?(paramètre d'entrée / gauche) et .(paramètre de sortie / droite) plus terser à utiliser. Cela signifie que si vous n'avez pas besoin d'accéder à vos prédicats ?et ., mais avez besoin d'utiliser des variables, vous pouvez souvent enregistrer des octets via la création d'un prédicat imbriqué pour utiliser ses ? et ..

À titre d'exemple simple, considérons un programme qui ressemble à ceci:

… A … ∧A … B … B …

C'est une forme assez courante pour un programme plus long; après tout, il y a beaucoup de lacunes qui pourraient contenir n'importe quoi. Supposons que nous n'ayons ni besoin ?ni .à l'intérieur des trois espaces centraux. Ensuite, nous pourrions le réécrire comme ceci:

… { … & … . … } …

Ici, le prédicat imbriqué ?sert le rôle de A, et son .sert le rôle de B. Nous pouvons observer qu'il s'agit d'un octet plus court que le code d'origine; changer AABBen {?.}n'a aucun changement en termes d'octets, mais cela nous a permis de simplifier ∧?l'abréviation &.

Une astuce connexe consiste à changer

∧. … ?∧

à

~{ … }

(qui est un octet plus court), mais notez qu'il est presque toujours moins cher de faire en sorte que l'appelant échange les arguments à la place (sauf si le prédicat est appelé à partir d'au moins trois endroits différents dans le programme, ce qui est rare dans Brachylog).


la source
3

Fractionner les prédicats de longueur 2 à l'intérieur des métaprédicats

Ceci est mieux expliqué par l'exemple. Pour supprimer les premier et dernier éléments d'une liste, nous la décapitons et la découpons:

bk

Si nous voulions effectuer cette opération sur chaque élément d'une liste, nous pouvons utiliser une opération de carte:

{bk}ᵐ

Cependant, c'est un octet plus court pour diviser le prédicat en deux et mapper chaque partie séparément:

bᵐkᵐ

La même astuce peut être utilisée avec plusieurs métaprédicats:

{bk}ᵐ  →  bᵐkᵐ
{bk}ˢ  →  bˢkˢ
{bk}ᶠ  →  bᶠkˢ
~{bk}  →  ~k~b

Notez que pour certaines métaprédicates, comme , il n'y a pas de moyen général de le diviser en deux parties, mais il peut néanmoins être possible de trouver une décomposition qui fonctionne pour la tâche spécifique sur laquelle vous travaillez.


la source
3

Cast de la liste vide dans la chaîne vide

Parfois, lorsque vous travaillez avec des chaînes, l'algorithme que nous utilisons peut unifier ce que nous voulons avec la liste vide [], alors que nous préférons la chaîne vide "".

Nous pouvons convertir la liste vide en chaîne vide en utilisant ,Ẹ, ce qui ajoute la chaîne vide à sa variable de gauche (c'est un exploit de la façon dont ,est implémenté).

Cela présente également l'avantage de ne rien faire si la variable de gauche est une chaîne. Donc, si votre programme est

{  
   some predicate that should always output a string, 
   but actually outputs [] instead of "" in specific cases
}

alors

{
  some predicate that should always output a string, 
  but actually outputs [] instead of "" in specific cases
},Ẹ

fonctionnera comme vous le souhaitez.

Fatalize
la source
2

Un seul élément s'exécute dans une liste

Considérez cet extrait:

ḅ∋≠

Si l'entrée est une liste ou une chaîne, la sortie est unifiée avec une sous-liste / sous-chaîne de longueur 1 qui ne fait pas partie d'une série plus longue d'éléments égaux. Il divise la liste en blocs d'éléments égaux et trouve un bloc dont les éléments sont tous différents. Pour obtenir les éléments eux-mêmes au lieu des listes singleton, pointez hà la fin. J'ai utilisé cette construction ici avec opour trouver un caractère qui n'apparaît qu'une seule fois dans la chaîne d'entrée.

Zgarb
la source