Tipps zum Golfen in INTERCAL

10

Welche allgemeinen Tipps haben Sie zum Golfen in INTERCAL ? Ich suche nach Ideen, die auf Code-Golf-Herausforderungen angewendet werden können und zumindest für INTERCAL etwas spezifisch sind (dh "Kommentare entfernen" ist keine nützliche Antwort).

Ich weiß, dass exotische Sprachen sehr nützlich sein können, um Golfwettbewerbe zu gewinnen, aber ich sehe hier nicht viel INTERCAL-Code. Haben Sie Ratschläge, die Menschen dabei helfen können, mit INTERCAL wettbewerbsfähige Codegrößen zu erhalten? Könnte diese Sprache jemals wettbewerbsfähig sein?

INTERCAL ist so wenig ausgelastet, dass es nicht einmal ein Tag hat. So traurig...

Baconaro
quelle
Die meisten Sprachen haben oder benötigen hier keine eigenen Tags, da von sprachspezifischen Herausforderungen im Allgemeinen abgeraten wird.
Alex A.
9
Ein Hinweis, dass dies möglicherweise nicht die beste Despite the language's intentionally obtuse and wordy syntax,
Golfsprache ist

Antworten:

2

Die Entfernung von Leerzeichen / "Rauschen" kann weiter gehen als erwartet

INTERCAL ist eine Leerzeichen-unempfindliche Sprache. Im Gegensatz zu den meisten Whitespace-unempfindlichen Sprachen geht die Unempfindlichkeit jedoch viel weiter als erwartet.

Zum Beispiel sind DO NOTes zwei Token, die aber geschrieben DONOTwerden können, ohne dass sich der Parser beschwert (in so ziemlich jeder weit verbreiteten Implementierung). (Natürlich können Sie auch schreiben DON'T, aber es ist kein Terser. Es ist jedoch möglicherweise einfacher zu lesen. Es PLEASEN'Tist wahrscheinlich schwieriger zu lesen als PLEASE NOT.) Tatsächlich gibt es einige Debatten darüber, ob Leerzeichen überhaupt etwas bewirken. Mindestens ein INTERCAL-Parser erlaubt es sogar innerhalb numerischer Konstanten (nicht, dass dies beim Golfen sehr nützlich ist). Eine Sache, die Sie beachten sollten, ist das Entfernen von Leerzeichen aus DO READ OUTGive, was einige ältere INTERCAL-Parser aufgrund der Einbettung verwirren kannDOREADOUTDO(Obwohl ihre Autoren dies im Allgemeinen als Fehler betrachten und es heutzutage normalerweise in einem gültigen Programm funktioniert, ist es nicht ratsam, Code wie diesen in die Nähe eines Syntaxfehlers zu stellen, da es dann viel schwieriger sein kann, ihn zu disambiguieren).

Denken Sie auch daran, dass Sie Zeichen überstanzen können, um Platz zu sparen. In ASCII können Sie dies nur mit '.→ wirklich durchziehen !, aber das ist ein sehr nützlicher Trick für sich. (Wenn Sie keine Arrays verwenden, besteht keine Möglichkeit einer Mehrdeutigkeit, selbst wenn alle Gruppierungszeichen gleich sind. Für Golfeinträge wird daher empfohlen, sich nur daran zu halten, es 'sei denn, ein Array-Index erfordert wirklich a ".) Ein Bücherwurm kann es sein dargestellt in einem Byte durch Verwendung der ?Abkürzung (C-INTERCAL) oder Latin-1 für ¥(CLC-INTERCAL) anstelle der drei, die INTERCAL-72 benötigt.


quelle
2

Konzentrieren Sie sich darauf, so viel Arbeit wie möglich in einer Aussage zu erledigen

Die Anweisungskennungen von INTERCAL sind ziemlich ausführlich. DOWenn jede Anweisung zwei Rauschzeichen enthält, ist der Name der Anweisung selbst in der Regel ziemlich lang, und Sie müssen ab und zu ein Zeichen einfügen, PLEASEum den Parser bei Laune zu halten. (Das Beste, was Sie tun können, ist ein Verhältnis von vier DOzu eins PLEASE, was bedeutet, dass Sie 14 Zeichen in Bezeichnern für jeweils 5 Befehle verwenden.) Andererseits ist die Ausdruckssyntax ziemlich knapp (lächerlich, aber knapp). Dies bedeutet, dass es sich oft lohnt, einen Teil Ihres Programms in einen einzelnen Ausdruck einzufügen, selbst wenn die Verwendung mehrerer Anweisungen eine "natürlichere" Vorgehensweise darstellt.

Zum Beispiel, wenn Sie wollen zuweisen #1zu .1und #2zu .2, statt es in der offensichtlichen INTERCAL-72 Art und Weise:

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

Es lohnt sich dringend, eine Zufallsvariable zu überladen, damit Sie beide gleichzeitig zuweisen können:

DO:1<-#1$#2

(mit :1/!1$.2'irgendwo früher im Programm eingeworfen; beachten Sie, dass diese Notation INTERCAL-72 in gewisser Weise nachdatiert, sodass Sie ein modernes INTERCAL verwenden müssen, damit dies funktioniert). Dies ist nur geringfügig länger, selbst wenn Sie das Setup berücksichtigen, und wird kürzer, wenn Sie jemals gleichzeitig .1und .2mehr als einmal zuweisen müssen oder können .

Es geht nicht nur darum, Befehle zu berechnen, bei denen dieser Trick funktioniert. Wenn Sie eine Variable zweimal verstauen müssen, gehen Sie nicht so vor:

DOSTASH.1DOSTASH.1

aber so:

DOSTASH.1+.1

(Die +Notation funktioniert für die meisten Befehle, bei denen dies konzeptionell sinnvoll sein könnte.)


quelle
2

Verwenden Sie einen einzigen RESUME für alle Konstrukte im INTERCAL-72-Stil

Wenn Sie das Äquivalent einer "if" -Anweisung schreiben müssen, besteht die normale Methode mit INTERCAL-72-Code darin, NEXTzweimal zu arbeiten und dann eine Berechnung durchzuführen RESUME. (In modernem Code ist ein berechneter Code oft COME FROMbesser, aber dieser Tipp setzt voraus, dass Ihr Code bevorzugt wird NEXT.) Sie müssen mit ziemlicher Sicherheit die Bytes für das erste bezahlen NEXT, da es von einem Zweig des "Wenn" zum anderen springt. Das Teilen der zweiten NEXTist ebenfalls nicht trivial, es sei denn, Sie haben viele "if" -Anweisungen, die beim Anzeigen von a an dieselbe Stelle gehen #1. Das RESUMEkann sich jedoch an einer beliebigen Stelle im Programm befinden (da die Steuerung es sofort an einer beliebigen Stelle belassen wird).

Es gibt zwei Möglichkeiten, damit umzugehen. Wenn Sie viele "if" -Anweisungen haben, RESUMEgarantiert die wahrscheinlich eine einstellige Zeilennummer, damit Ihre zweite NEXTAnweisung so kurz wie möglich sein kann. Wenn möglich, versuchen Sie, daraus eine Berechnung zu machen RESUME, die natürlich in Ihrem Code vorkommen würde (zugegebenermaßen ist dies schwierig, da diese nur selten im "normalen Codefluss" angezeigt werden, anstatt NEXTbearbeitet zu werden). dann sind die einzigen Kosten die Zeilennummer. Sie müssen für alle diese NEXTs eine einzige boolesche Variable verwenden . Der universelle Konsens besteht darin .5, hauptsächlich die Variable zu verwenden, die die Standardbibliothek für boolesche Rückgabewerte verwendet.

Alternativ ist es möglich, eine undokumentierte Funktion (technisch unterdokumentiert, da ich einen Hinweis in die INTERCAL-Dokumentation eingefügt habe, als ich es bemerkte) der Standardbibliothek zu verwenden. Da ein zentraler Speicherort für a RESUMEso nützlich ist, verwendet die Standardbibliothek intern einen. Die Zeilennummern in INTERCAL sind global (mit Namespace-Konventionen, die jedoch unterbrochen werden können, wenn Sie wissen, was Sie tun), sodass Sie NEXTdirekt in die Interna der Standardbibliothek wechseln können NEXT, wenn Sie möchten, und insbesondere zu ihrem zentralen RESUME-Speicherort . Dies ist in vorhandenem INTERCAL-Code so beliebt, dass Standardbibliotheksersetzungen ihn tendenziell implementieren müssen, um zu vermeiden, dass vorhandene Programme beschädigt werden.

Die fragliche Zeile lautet (entweder wörtlich oder effektiv, abhängig von der Implementierung):

(1001) DO RESUME .5

Der Hauptgrund, dies nicht zu verwenden, ist seine lange Zeilennummer; Wenn Sie viele Konstrukte im INTERCAL-72-Stil ausführen müssen, ist es besser, Ihre eigenen zu verwenden, um eine kürzere Zahl zu erhalten.

Natürlich können Sie die Techniken kombinieren und so etwas schreiben

(9)DO(1001)NEXT

das ist nur unwesentlich länger als

(9)DORESUME.5

und hat den Vorteil, dass die Booleschen Werte werden #2und #3(was schwerer zu lesen, aber normalerweise einfacher zu generieren ist). Tatsächlich könnte es sich sogar lohnen, den zusätzlichen Code einzugeben , der verarbeitet werden soll, #0und #1wenn Sie viel ficken werden (aber die Berechnung COME FROMfunktioniert in diesem Fall wahrscheinlich besser, es sei denn, Ihre Anforderungen sind sehr seltsam).


quelle
2

INTERCAL gibt keine Priorität an, aber es gibt auch keine Fehler bei mehrdeutigen Prioritäten

Ein Ausdruck wie

#1$#2~#3

ist mehrdeutig und könnte bedeuten

'#1$#2'~#3

oder

#1$'#2~#3'

Die INTERCAL-Spezifikation lässt absichtlich unklar, was gemeint ist, und im Allgemeinen gibt es keinen Standard (obwohl C-INTERCAL und CLC-INTERCAL sich bemühen, in den einfacheren Fällen miteinander übereinzustimmen). Das Original ist jedoch nicht falsch . Es ist mehrdeutig und ich würde nicht empfehlen, es im Produktionscode zu verwenden (aber dann würde ich nicht empfehlen, INTERCAL selbst im Produktionscode zu verwenden), aber es wird in den meisten Compilern eine gewisse Bedeutung haben.

Mit anderen Worten, es kann sich lohnen, nur Gruppierungszeichen zu entfernen und zu hoffen, dass Ihr Programm noch funktioniert. Die meisten Interpreten analysieren einen bestimmten mehrdeutigen Ausdruck konsistent, sodass für jedes Paar von Gruppierungszeichen eine 1: 2-Chance besteht, dass dies nicht erforderlich ist. das kann zu erheblichen Einsparungen führen. (Leider sind INTERCAL-Parser in der Regel so verwirrend, dass niemand genau weiß , wie die Regeln tatsächlich lauten . Sie können jedoch normalerweise experimentell ermittelt werden. In den einfachsten Fällen haben Operatoren in der Regel alle den gleichen Vorrang und eine konsistente Assoziativität.)


quelle
2

Ziehen Sie in C-INTERCAL in Betracht, den Code mit abzukürzen CREATE

Mit der CREATEAnweisung können Sie eine neue Syntax erstellen. Dies ist besonders beim Golfen nützlich, da Sie damit Aussagen kürzer benennen können. Sie können es auch verwenden, um eine Funktion effektiv zu "definieren", indem Sie einen neuen Operator erstellen (was den großen Vorteil hat, dass Sie die Funktion mitten in einem Ausdruck aufrufen können).

Die Einrichtungskosten sind hier ziemlich hoch, aber wenn es ein Konstrukt gibt, das Sie häufig verwenden, ist es wahrscheinlich eine gute Idee, eine kürzere Syntax dafür zu erfinden.


quelle