Golftipps in Befunge

12

Welche allgemeinen Tipps haben Sie zum Golfen in Befunge? Ich bin auf der Suche nach Ideen, die sich auf Code-Golf-Probleme im Allgemeinen anwenden lassen, die zumindest etwas spezifisch für Befunge sind (z. B. "Kommentare entfernen" ist keine Antwort). Bitte posten Sie einen Tipp pro Antwort.

Justin
quelle
Ich bin mir nicht sicher, ob dies generell in Befunge geändert werden sollte, aber Befunge 93 ist viel weniger ideal zum Golfen als 98.
Justin
6
Wir hatten kürzlich ein Befunge 93- Thema, aber ich denke, es wäre besser, dieses Thema zu verallgemeinern. Wäre das ok? (und vielleicht markieren Sie, welche Tipps für welche Version (en) gut sind, so wie Python-Tipps angeben, ob sie Python 2 / Python 3-spezifisch sind oder nicht)
Sp3000

Antworten:

9

Versuchen Sie bei Verwendung einer mehrzeiligen Schleife, so viel wie möglich davon zu verwenden:

>1234....v
^        <

vs

>1234v
^....<
Justin
quelle
7

Müssen Sie einen Wert nach einer Bedingung löschen (z. B. weil der andere Pfad vom Wert abhängt, dieser jedoch nicht)? Anstatt >$oder zu verwenden $<, sollten Sie davon ausgehen, dass Sie den Wahrheitswert der Variablen kennen, und _stattdessen Richtung und Popstack ändern.

Beispiel

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

wird verwandelt in

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

Vergiss nicht, dass 0das immer auf dem Stapel ist. Dies bedeutet zum Beispiel, dass mit einem leeren Stapel ggleichbedeutend ist mit 00gund pgleichbedeutend ist mit 000p.

Justin
quelle
5

Wenn Sie eine Zahl größer als 15 eingeben müssen ', rufen Sie mit den ASCII-Wert des nächsten Zeichens ab:

'*

42 drücken anstatt:

4a*2+
Justin
quelle
Oder 67*funktioniert auch
Türklinke
4
@Doorknob Vielleicht hätte ich eine Primzahl wählen sollen, um meinen Standpunkt klarer zu machen, aber 42 ist so eine tolle Zahl.
Justin
2
Beachten Sie, dass dieser Tipp nur für Befunge-96 und höher gilt. Befunge-93 hat den 'Befehl nicht unterstützt .
James Holderness
4

Verwenden Sie stattdessen |eine andere Zeile (häufig mit vielen zusätzlichen Leerzeichen) j. Beispielsweise:

01-`j@more code here

würde aufhören, wenn die Zahl oben auf dem Stapel negativ wäre, und ansonsten weitermachen. Wenn Sie mehrere Zeichen benötigen, geben Sie n*jan, nwie viele Zeichen Sie benötigen, wenn der übergebene Wert jlautet 0. Beispiel:

01-`4*j01-*more code

das würde eine negative Zahl negieren.

Justin
quelle
Beachten Sie, dass dieser Tipp nur für Befunge-96 und höher gilt. Befunge-93 hat den jBefehl nicht unterstützt .
James Holderness
4

Wenn Sie in Befunge-93 als Erstes eine Zeichenfolge auf den Stapel legen, kann es häufig passieren, dass Sie das Eröffnungszitat fallen lassen. Zum Beispiel das:

"!iH",,,@

könnte dazu vereinfacht werden:

!iH",,,@

Probieren Sie es online!

Was passiert, ist, dass der Interpreter zuerst versucht, die Zeichen in der Zeichenfolge ohne Anführungszeichen auszuführen. Die !führt eine harmlose nicht , und die iund Hsind keine gültigen Anweisungen, so dass sie ignoriert werden (obwohl bei einigen Implementierungen möglicherweise eine Warnung angezeigt wird).

Wenn das "angetroffen wird, wird dies als der Anfang der Zeichenfolge betrachtet. Da jedoch kein abschließendes Anführungszeichen vorhanden ist, wird das Feld vollständig umbrochen, bis "es ein zweites Mal angetroffen wird. Was dann auf den Stapel geschoben wird, ist folgendes:

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

Da wir uns nur um die letzten Charaktere kümmern, ist nichts anderes von Bedeutung. Nach dem Zitat können wir dann endlich die drei ,Befehle ausführen , die Nachricht ausschreiben und den @Befehl, der beendet wird.

Beachten Sie, dass dies in Befunge-98 normalerweise nicht funktioniert, da eine nicht erkannte Anweisung den Interpreter zum Reflektieren veranlasst, anstatt ihn zu ignorieren.

James Holderness
quelle
In Befunge-98 können Sie stattdessen die erforderliche Zeichenfolge wie folgt am Ende der Zeile einfügen . ",,,@!iH. Beachten Sie, dass Pyfunge ein zusätzliches Leerzeichen hinzufügt, während FBBI dies nicht tut.
Jo King
@JoKing Ich wollte das nicht vorschlagen, da sich das Verhalten, wie Sie betonten, von einem Interpreter zum nächsten unterscheidet. Und selbst wenn es zu funktionieren scheint, ist es inkonsistent (beachten Sie in diesem Fall den zusätzlichen Platz im FBBI ), so dass es möglicherweise ein Fehler ist, der irgendwann behoben wird.
James Holderness
Hmm ... Ich denke, der Raum könnte tatsächlich Teil der Spezifikation sein. Ich erinnere mich, dass ich irgendwo gelesen habe, dass mehrere Leerzeichen übersprungen und als ein Leerzeichen gezählt werden. Beispiel in PyFunge und FBBI. FBBI scheint jede Zeile bis zur Länge der längsten Zeile aufzufüllen, während PyFunge die zusätzlichen Leerzeichen implizit hinzufügt.
Jo King
Sie haben Recht - die Spezifikation besagt, dass mehrere Leerzeichen in einer Zeichenfolge als ein einzelnes Leerzeichen behandelt werden sollen. Tatsächlich wurde diese Regel speziell vorgeschlagen, um das Problem des Umschließens von Zeichenfolgen in einem unendlichen Spielfeld zu lösen (daher ist PyFunge eindeutig die richtige AFAIC). Die Beschreibung des Umhüllungsalgorithmus in der Spezifikation kann jedoch leicht interpretiert werden, sodass ich nachvollziehen kann, warum einige Implementierungen die Dinge möglicherweise anders ausführen. Aber unter dem Strich ist dies ein ziemlich kompliziertes Problem, und ich denke, es wäre besser, es als separaten Tipp speziell für Befunge-97/98 zu behandeln.
James Holderness
4

In Befunge-93 kann es oft vorteilhaft sein, eine Schleife in eine einzige Zeile zu reduzieren, wobei der Schleifenabschnitt des Codes in beide Richtungen ausgeführt wird.

Betrachten Sie beispielsweise den folgenden Code, der den Buchstaben aachtmal ausgibt :

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

Dies kann zu einer einzelnen Zeile reduziert werden, indem die Schleifensequenz mit Brückenbefehlen ( #) durchsetzt wird:

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

Probieren Sie es online!

Wenn Sie sich nur die Zeichen ohne Leerzeichen ansehen, haben Sie möglicherweise den Eindruck, dass diese länger sind als das Original. Wenn Sie jedoch den Zeilenvorschub und den zusätzlichen Abstand berücksichtigen, der in der zweizeiligen Version erforderlich ist, sparen Sie tatsächlich vier Bytes.

In diesem speziellen Fall kann der Code noch weiter komprimiert werden, indem festgestellt wird, dass diese Sequenz :#:einfach durch ersetzt werden kann :.

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

Probieren Sie es online!

Tatsächlich können Sie jedes Mal, wenn Sie denselben Befehl auf beiden Seiten eines #Befehls wiederholen, diesen auf den einen Befehl vereinfachen. Dies ist also etwas, worauf Sie beim Reduzieren einer Schleife immer achten sollten.

Um zu verstehen, wie dies funktioniert, kann es hilfreich sein, die Schleifenfolge zweimal zu schreiben, einmal mit allen Zeichen nach dem #Entfernen (dh was passiert, wenn von links nach rechts ausgeführt wird) und einmal mit den Zeichen vor dem #Entfernen (dh von rechts nach links ausgeführt wird) ).

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

Sie können jetzt deutlich sehen, wie dies mit der ursprünglichen zweizeiligen Version des Codes übereinstimmt.

James Holderness
quelle
3

Ausgabe über Exit-Code, wobei dies ein zulässiges Ausgabeformular ist. Wenn Sie aufgefordert werden, eine Nummer auszudrucken, können Sie ein Byte speichern, indem Sie das Programm mit qanstelle von beenden.@

Pfeffer
quelle
2
Beachten Sie, dass dieser Tipp nur für Befunge-98 und höher gilt. In früheren Befunge-Versionen hatte der qBefehl eine andere Funktion (Warteschlangenmodus) oder wurde nicht unterstützt.
James Holderness
3

In Befunge-93 kann der Zeicheneingabebefehl ( ~) häufig als Abkürzung für -1 verwendet werden, da dies der Wert ist, der bei EOF zurückgegeben wird.

Der folgende Code gibt beispielsweise -1 aus:

~.@

Probieren Sie es online!

Dies wird im Produktionscode nicht empfohlen, da das Programm beim Ausführen in einer interaktiven Umgebung anhält und auf Benutzereingaben wartet. Und wenn der Benutzer etwas eingibt, ist das Ergebnis natürlich nicht mehr -1.

Die Regel für PPCG lautet jedoch, dass ein Programm möglicherweise einen leeren Eingabestream annimmt , und so würde es normalerweise auf TIO ausgeführt .

Beachten Sie auch, dass Sie nicht unbedingt daran gehindert sind, diesen Trick zu verwenden, nur weil Ihr Programm etwas aus dem Eingabestream lesen muss. Sie müssen nur sicherstellen, dass Sie Ihre Eingaben vorab verarbeiten. Danach ~sollten alle zukünftigen Verwendungen von -1 zurückgeben.

James Holderness
quelle
2

Verwenden Sie beim Umgang mit _oder die Richtung der IP |, anstatt ein zusätzliches Zeichen für zu verwenden !.

Echtes Beispiel (aus diesem Beitrag ):

#v~
,>:!#@_

Kann geändert werden zu

#v~
:<,_@#
Justin
quelle
2

Vergiss nicht, dass 0kder nächste Befehl nicht ausgeführt wird. Dies bedeutet, dass anstatt zu tun:

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

Sie können einen Charakter speichern, indem Sie tun

;some boolean test;kv;code if false;
      ;code if true;<
Justin
quelle
Beachten Sie, dass dieser Tipp nur für Befunge-98 und höher gilt. Frühere Versionen von Befunge haben die kAnweisung nicht unterstützt .
James Holderness
1

Vergessen Sie nicht den kBediener. Anstatt zu "!dlroW olleH",,,,,,,,,,,,@tun "!dlroW olleH"bk,@. Beachten Sie, dass kdie Operation funktioniert auf der Zelle , dass sie an ist , so 9k,würde nicht gedruckt 9mal aber 10; 9 mal mit kund einmal mit ,.

Justin
quelle
1
Beachten Sie, dass dieser Tipp nur für Befunge-98 und höher gilt. Frühere Versionen von Befunge haben die kAnweisung nicht unterstützt .
James Holderness
1

Wenn Sie kleine Zahlen auf den Stapel schieben, können Sie wahrscheinlich leicht genug herausfinden, dass 45*Sie 20und bekommen67* Sie erhalten 42. Bei größeren Zahlen benötigen Sie jedoch ein Programm, mit dem Sie die effizienteste Darstellung berechnen können.

Die einfachste Möglichkeit hierfür ist die Online-Oberfläche von Mike Schwörer für BefunRep . Sie geben einfach eine Zahl ein und es wird eine äquivalente Befunge-Darstellung ausgespuckt. Es ist nicht immer das Optimalste, aber es ist nah genug, und es ist mit ziemlicher Sicherheit besser als alles, was man sich mit der Hand einfallen lässt.

Das Online-System ist auf Zahlen im Bereich von 0 bis 16777215 beschränkt. Wenn Sie also etwas Größeres benötigen, sollten Sie das eigenständige BefunRep-Dienstprogramm herunterladen und die Berechnungen selbst ausführen.

Wenn Sie in Befunge-98 programmieren, sollten Sie auch Fungify in Betracht ziehen . Im Allgemeinen ist es nicht annähernd so optimal wie BefunRep, aber für einige der niedrigeren Zahlen, bei denen Hexadezimalziffern und einfache Anführungszeichen am effektivsten sind, können manchmal bessere Ergebnisse erzielt werden.

James Holderness
quelle
Wenn Sie in Befunge 98 kleine Zahlen eingeben, verwenden Sie '. ZB für 42:'*
Justin
@Justin Ich habe das im letzten Absatz erwähnt, aber der springende Punkt in diesem Tipp ist, dass Sie nicht viele dieser Tricks kennen müssen, um Zahlen zu generieren, wenn Sie nur ein Tool verwenden, um dies für Sie zu tun.
James Holderness