Conseils pour jouer au golf à Befunge

12

Quels conseils généraux avez-vous pour jouer au golf à Befunge? Je cherche des idées qui peuvent être appliquées aux problèmes de golf de code en général qui sont au moins quelque peu spécifiques à Befunge (par exemple, "supprimer les commentaires" n'est pas une réponse). Veuillez poster un pourboire par réponse.

Justin
la source
Je ne sais pas si cela devrait être changé en Befunge en général, mais le Befunge 93 est beaucoup moins idéal pour le golf que le 98.
Justin
6
Nous avons eu un sujet récent sur Befunge 93 , mais je pense qu'il serait préférable de généraliser ce sujet à la place. Est-ce que ça va? (et peut-être marquer quelles astuces sont bonnes pour quelle (s) version (s), de la même manière que les astuces Python indiquent si elles sont spécifiques à Python 2 / Python 3)
Sp3000

Réponses:

9

Lorsque vous utilisez une boucle multi-lignes, essayez d'en utiliser autant que possible:

>1234....v
^        <

contre

>1234v
^....<
Justin
la source
7

Besoin de supprimer une valeur après un conditionnel (par exemple parce que l'autre chemin dépend de la valeur, mais pas celui-ci)? Au lieu d'utiliser >$ou $<, profitez du fait que vous connaissez la valeur de vérité de la variable et utilisez à la _place pour changer à la fois la direction et la pile de pop.

Exemple

'* : v           >$ .. @          Prints number in binary followed by the original
                                  decimal number.
     > :2%\2/ :!#^_ \.

se transforme en

'* : v           _  .. @          Since we know that the topmost value on the stack
                                  will be 0, we combine `>$` into `_`.
     > :2%\2/ :!#^_ \.
Luciole
la source
6

N'oubliez pas que 0c'est toujours sur la pile. Par exemple, cela signifie que, avec une pile vide, gest équivalent à 00get pest équivalent à 000p.

Justin
la source
5

Si vous devez pousser un nombre supérieur à 15, utilisez 'pour récupérer la valeur ASCII du caractère suivant:

'*

pousser 42 plutôt que:

4a*2+
Justin
la source
Ou, 67*
ça
4
@ Doorknob J'aurais peut-être dû choisir un nombre premier pour mieux faire comprendre mon point, mais 42 est un si grand nombre.
Justin
2
Notez que cette astuce ne s'applique qu'à Befunge-96 et versions ultérieures. Befunge-93 n'a pas soutenu l' 'instruction.
James Holderness
4

Au lieu d'utiliser |, nécessitant une autre ligne (souvent avec de nombreux espaces supplémentaires), essayez d'utiliser j. Par exemple:

01-`j@more code here

s'arrêterait si le nombre en haut de la pile était négatif et continuerait dans le cas contraire. Si vous avez besoin de plusieurs caractères, utilisez n*jnest le nombre de caractères dont vous avez besoin lorsque la valeur transmise jest 0. Exemple:

01-`4*j01-*more code

ce qui annulerait un nombre négatif.

Justin
la source
Notez que cette astuce ne s'applique qu'à Befunge-96 et versions ultérieures. Befunge-93 n'a pas soutenu l' jinstruction.
James Holderness
4

Dans Befunge-93, si la première chose que vous poussez sur la pile est une chaîne, vous pouvez souvent vous en sortir en supprimant la citation d'ouverture. Par exemple ceci:

"!iH",,,@

pourrait être simplifié à ceci:

!iH",,,@

Essayez-le en ligne!

Ce qui se passe, c'est que l'interpréteur essaie d'abord d'exécuter les caractères de la chaîne non citée. Le !exécute une action non inoffensive et les instructions iet Hne sont pas valides, elles sont donc ignorées (bien que sur certaines implémentations, un avertissement puisse s'afficher).

Lorsque le "est rencontré, cela est considéré comme le début de la chaîne, mais comme il n'y a pas de guillemet de fermeture, il s'enroule tout autour du champ de jeu jusqu'à ce que le "soit rencontré une deuxième fois. Ce qui finit par être poussé sur la pile est alors le suivant:

,,,@  ···72 spaces···  !iH

Puisque nous ne nous soucions que des derniers personnages, cependant, aucune de ces autres choses n'a d'importance. Donc, après le devis, nous arrivons enfin à exécuter les trois ,commandes, en écrivant le message et la @commande, qui se termine.

Notez que cela ne fonctionnera généralement pas dans Befunge-98, car une instruction non reconnue entraînera la réflexion de l'interpréteur au lieu de l'ignorer.

James Holderness
la source
Dans Befunge-98, vous pouvez à la place mettre la chaîne requise à la fin de la ligne, comme ceci; ",,,@!iH. Notez que Pyfunge ajoute un espace supplémentaire, contrairement à FBBI.
Jo King
@JoKing Je ne voulais pas suggérer cela, car, comme vous l'avez souligné, le comportement diffère d'un interprète à l'autre. Et même quand cela semble fonctionner, c'est incohérent (notez l'espace supplémentaire dans FBBI dans ce cas ), donc c'est très probablement un bogue qui pourrait finir par être corrigé à un moment donné.
James Holderness
Hmm ... Je pense que l'espace pourrait en fait faire partie de la spécification. Je me souviens avoir lu quelque part que plusieurs espaces seront ignorés et comptés comme un seul espace. Exemple dans PyFunge et FBBI. FBBI semble remplir chaque ligne à la longueur de la ligne la plus longue tandis que PyFunge ajoute implicitement les espaces supplémentaires.
Jo King
Vous avez raison - la spécification dit que plusieurs espaces dans une chaîne doivent être traités comme un seul espace. En fait, cette règle a été spécifiquement proposée pour traiter le problème de l'enroulement des cordes dans un champ de jeu infini (donc PyFunge est clairement correct AFAIC). Mais la description de la spécification de l'algorithme d'encapsulation est quelque peu ouverte à l'interprétation, donc je peux comprendre pourquoi certaines implémentations peuvent faire les choses différemment. Mais l'essentiel est que c'est un problème assez compliqué, et je pense qu'il serait mieux couvert comme une astuce distincte spécifique à Befunge-97/98.
James Holderness
4

Dans Befunge-93, il peut souvent être avantageux d'aplatir une boucle en une seule ligne, la section de boucle du code étant exécutée dans les deux sens.

Par exemple, considérez le code ci-dessous, qui génère la lettre ahuit fois:

"a"9>1-:#v_@
    ^\,:\<

Cela peut s'aplatir être aplati en une seule ligne en intercalant la séquence de boucle avec des instructions de pont ( #):

"a"9>1#\-#,:#:>#\_@

Essayez-le en ligne!

Si vous regardez simplement les caractères non blancs, vous pouvez avoir l'impression que c'est plus long que l'original. Mais une fois que vous prenez en compte le saut de ligne et le remplissage supplémentaire requis dans la version à deux lignes, vous finissez par économiser quatre octets.

Dans ce cas particulier, le code doit être encore plus compressé en notant que cette séquence :#:peut simplement être remplacée par :.

"a"9>1#\-#,:>#\_@

Essayez-le en ligne!

En fait, chaque fois que vous répétez la même instruction de chaque côté d'une #commande, vous pouvez simplifier celle-ci en une seule instruction, c'est donc quelque chose que vous devriez toujours rechercher lorsque vous aplatissez une boucle.

Pour comprendre comment cela fonctionne, il peut être utile d'écrire la séquence de boucle deux fois, une fois avec tous les caractères suivant la #suppression (ie ce qui se passe lors de l'exécution de gauche à droite), et une fois avec les caractères précédant la #suppression (ie exécution de droite à gauche ).

"a"9>1#\-#,:>#\_@
    >1  -  :>  _      ; executing left to right
    >  \  ,:  \_      ; executing right to left

Vous pouvez maintenant voir clairement comment cela correspond à la version originale à deux lignes du code.

James Holderness
la source
3

Sortie par code de sortie, où il s'agit d'un formulaire de sortie autorisé. Si le défi vous demande d'imprimer un numéro, vous pouvez enregistrer un octet en terminant le programme avec qau lieu de.@

pppery
la source
2
Notez que cette astuce ne s'applique qu'à Befunge-98 et versions ultérieures. Dans les versions antérieures de Befunge, l' qinstruction avait une fonction différente (mode file d'attente) ou n'était pas prise en charge.
James Holderness
3

Dans Befunge-93, la commande de saisie de caractères ( ~) peut souvent être utilisée comme raccourci pour -1, car c'est la valeur qu'elle renvoie sur EOF.

Par exemple, le code ci-dessous affichera -1:

~.@

Essayez-le en ligne!

Ceci n'est pas recommandé dans le code de production, car lorsqu'il est exécuté dans un environnement interactif, le programme s'arrête et attend l'entrée utilisateur. Et évidemment, si l'utilisateur devait saisir quelque chose, le résultat ne serait plus -1.

Cela dit, la règle sur PPCG est qu'un programme peut supposer un flux d'entrée vide , et c'est ainsi qu'il serait généralement exécuté sur TIO .

Notez également que vous n'êtes pas nécessairement empêché d'utiliser cette astuce simplement parce que votre programme doit lire quelque chose dans le flux d'entrée. Vous devez juste vous assurer de traiter vos entrées à l'avance, après quoi toutes les utilisations futures de ~devraient retourner -1.

James Holderness
la source
2

Utilisez la direction de l'IP lorsque vous traitez avec _ou |, plutôt que d'utiliser un caractère supplémentaire pour !.

Exemple réel (de ce post ):

#v~
,>:!#@_

Peut être changé en

#v~
:<,_@#
Justin
la source
2

N'oubliez pas que 0kcela n'exécute pas l'instruction suivante. Cela signifie qu'au lieu de faire:

;some boolean test;!jv;code if false;
       ;code if true;<

Vous pouvez enregistrer un personnage en faisant

;some boolean test;kv;code if false;
      ;code if true;<
Justin
la source
Notez que cette astuce ne s'applique qu'à Befunge-98 et versions ultérieures. Les versions antérieures de Befunge ne prenaient pas en charge l' kinstruction.
James Holderness
1

N'oubliez pas l' kopérateur. Au lieu de "!dlroW olleH",,,,,,,,,,,,@, faites "!dlroW olleH"bk,@. Notez que kfait l'opération sur la cellule qu'il est à donc 9k,imprimerait pas 9 fois mais 10; 9 fois avec le k, et une fois avec ,.

Justin
la source
1
Notez que cette astuce ne s'applique qu'à Befunge-98 et versions ultérieures. Les versions antérieures de Befunge ne prenaient pas en charge l' kinstruction.
James Holderness
1

Lorsque vous poussez de petits nombres sur la pile, vous pouvez probablement trouver assez facilement ce 45*qui vous obtiendra 20et 67*vous obtiendra 42. En ce qui concerne les nombres plus importants, cependant, vous avez vraiment besoin d'un programme qui peut calculer la représentation la plus efficace pour vous.

L'option la plus simple pour cela est l' interface en ligne de Mike Schwörer pour BefunRep . Vous tapez simplement un nombre et il crachera une représentation Befunge équivalente. Ce n'est pas toujours le plus optimal, mais il est assez proche et il est presque certain d'être meilleur que tout ce que vous pourriez trouver à la main.

Le système en ligne est limité aux nombres compris entre 0 et 16777215, donc si vous avez besoin de quelque chose de plus grand que cela, vous voudrez télécharger l' utilitaire BefunRep autonome et exécuter les calculs vous-même.

Si vous programmez en Befunge-98, une autre option à considérer est Fungify . En général, il n'est pas aussi optimal que BefunRep, mais pour certains des nombres inférieurs, où les chiffres hexadécimaux et les guillemets simples sont les plus efficaces, il peut parfois produire de meilleurs résultats.

James Holderness
la source
Lorsque vous poussez de petits nombres dans Befunge 98, vous utilisez '. Par exemple pour 42:'*
Justin
@Justin J'ai mentionné cela dans le dernier paragraphe, mais le but de cette astuce est que vous n'avez pas besoin de connaître beaucoup de ces astuces pour générer des nombres si vous utilisez simplement un outil pour le faire pour vous.
James Holderness