Die erste Programmiersprache, der ich ausgesetzt war, war Sinclair BASIC . Wie bei vielen BASIC-Dialekten müssen alle Quellcodezeilen nummeriert werden .
Infolgedessen war die Verwendung des GO TO
Befehls idiomatisch und springt zur angegebenen Zeilennummer (keine Bezeichnungen).
Es gibt auch einen zugehörigen GO SUB
Befehl, der als rudimentärer Funktionsaufruf verwendet werden kann. Die Ausführung springt wieder zur angegebenen Zeilennummer, aber wenn ein RETURN
Befehl erreicht ist, springt die Ausführung zurück zum nächsten Befehl nach dem GO SUB
.
In ähnlicher Weise RUN
startet der Befehl die Programmausführung in der angegebenen Zeile neu.
Jeder, der Zeit in einem zeilennummerierten BASIC-Interpreter verbracht hat, hat gelernt, ein lückenhaftes Nummerierungsschema zu verwenden. Dies erleichtert das Einfügen neuer Codezeilen. Trotzdem müssen Sie möglicherweise immer noch neue Zeilen zwischen fortlaufend nummerierten Zeilen einfügen.
Bei einer Linie nummerierten BASIC Protokoll als Eingang, Ausgang das gleiche Programm , aber neu nummeriert , so dass die Zeilennummern bei 10 und Erhöhung in Schritten von 10 starten Die Eingangs Listing kann GO TO
oder GO SUB
Befehle, so verbunden sind die Zahlen mit diesen auch angepasst werden müssen.
GO TO
undGO SUB
Befehle stehen entweder in eigenen Zeilen oder am ZeilenendeIF
THEN
. Es ist sicher zu sagen, dass^(\d+) .*GO (TO|SUB) (\d+)$
es ausreicht, um solche Linien zu treffen. Diese Befehle in Anführungszeichen sollten ignoriert werden.RUN
Befehle werden immer in eigenen Zeilen stehen. In diesem Fall ist eine Zeilennummer optional. Fehlt es, startet der Interpreter einfach oben im Programm.Wenn ein
GO TO
,GO SUB
oderRUN
Befehl verweist auf eine nicht vorhandene Linie, dann wird es stattdessen auf die nächste definierte Linie springen. Ihr Eintrag muss sich damit befassen und sicherstellen, dass solche Zeilenreferenzen festgelegt sind, damit sie auf die richtige Zeile verweisen. Das Verhalten kann undefiniert sein, wenn in einem dieser Befehle eine Zeilennummer nach dem Programmende angegeben wird.Zeilennummern sind immer positive ganze Zahlen von 1 bis 9999 (gemäß Handbuch). Dies bedeutet, dass Eingabeprogramme niemals mehr als 999 Zeilen haben.
Eingabezeilen werden immer in numerisch aufsteigender Reihenfolge nummeriert.
Für die Zwecke dieser Herausforderung enthalten Eingabeauflistungen nur druckbare ASCII-Daten. Sie müssen sich nicht um den ZX-Zeichensatz kümmern. Having said that, wenn Ihr Eintrag in ZX BASIC tatsächlich geschrieben oder geeignete z80 Montage / Maschinencode (und es gibt Emulatoren heraus dort ), dann können Sie wählen für Ihre Eingabe in der codiert werden ZX - Zeichensatz statt.
Sie dürfen keine neu nummerierten Bibliotheken oder Dienstprogramme verwenden, die speziell auf diesen Zweck zugeschnitten sind.
Beispiel Eingabe:
1 REM "A rearranged guessing game"
2 INPUT A: CLS
3 INPUT "Guess the number ", B
10 IF A=B THEN PRINT "Correct": STOP
100 IF A<B THEN GO SUB 125
120 IF A>B THEN GO SUB 122
121 GO TO 3
125 PRINT "Try again"
126 RETURN
127 REM "An example of GO TO 7 and GO SUB 13 in quotes"
Beispielausgabe:
10 REM "A rearranged guessing game"
20 INPUT A: CLS
30 INPUT "Guess the number ", B
40 IF A=B THEN PRINT "Correct": STOP
50 IF A<B THEN GO SUB 80
60 IF A>B THEN GO SUB 80
70 GO TO 30
80 PRINT "Try again"
90 RETURN
100 REM "An example of GO TO 7 and GO SUB 13 in quotes"
Ich wollte auf ein ZX BASIC-Handbuch verlinken. Das Beste, was ich finden konnte, scheint http://www.worldofspectrum.org/ZXBasicManual/index.html zu sein, aber dies scheint ein toter Link zu sein. Die Wayback-Maschine hat jedoch eine Kopie .
GOTO 100 + A*10
und Anhang C der ZX Spectrum Handbuch ListenGO TO
als numerischen Ausdruck akzeptiert (keine Beschränkung auf Konstanten). Im Folgenden werden die Vorteile von ComputingGOTO
für ZX80 und ZX81 erörtert . Übrigens habe ich keine Ahnung, warum der Speicherplatz in der Spectrum-Version hinzugefügt wurde.Antworten:
JavaScript (ES6) 177
Bearbeiten Der (kostspielige) Scan für die nächste gültige Zeilennummer wurde hinzugefügt
PRÜFUNG
quelle
Perl 6,
147145144142 BytesDies kann wahrscheinlich ein bisschen mehr Golf gespielt werden.
Erweitert
quelle
.min
. Verwenden Sie{min %line-map.keys».Num.grep:*>=$1
stattdessenVisual Basic für Applikationen, 288 Byte
Ich konnte nicht widerstehen, eine Lösung in einem BASIC-Dialekt zu geben. Funktioniert wahrscheinlich mit Visual Basic 6 / .NET oder anderen modernen Varianten mit geringfügigen Änderungen.
Ich habe viele Ein-Buchstaben-Variablen aus Gründen der Übersichtlichkeit verwendet. Außerdem habe ich alle unnötigen Leerzeichen unterdrückt (VBE erweitert sie beim Import automatisch). Die Byteanzahl gilt für die endgültige .BAS-Datei mit CHR (10) als Zeilenumbruch.
Die Subroutine, die über das VBE-Direktfenster aufgerufen werden kann, öffnet ein Sinclair BASIC-Programm (der erste Parameter ist der Pfad zu einer ASCII-Datei - mit CHR (10) als Zeilenvorschub - die das Programm enthält), nummeriert die Zeilen neu und schreibt die Ergebnisse in eine Variant-Variable (zweiter Parameter).
Die Idee ist, Iterierte auf allen möglichen Quellzeilennummern, aufsteigende Reihenfolge, und für jeden, ersetzen Sie sofort alle passenden Zeilennummern sowie
GO TO
,GO SUB
undRUN
Referenzen mit der nächsten verfügbaren Nummer Ziellinie. Mit diesem Ansatz benötigen wir keine Übersetzungstabelle. Die Zielzeilennummer wird jedes Mal erhöht, wenn eine Übereinstimmung in der Quellzeilennummer gefunden wird, sodass "falsche" Zeilenreferenzen automatisch an die nächste gültige Nummer angepasst werden. Zeilenumbruchzeichen werden als Markierungen für Zeilenanfang und -ende verwendet, und eine CHR (0) - die im Programm nie verwendet wird, da sie nicht gedruckt werden kann - wird als temporäre Markierung verwendet, um zu vermeiden, dass dieselbe Zeile mehrmals neu nummeriert wird.Einige Bemerkungen:
Aus Gründen der Übersichtlichkeit verwenden wir die kleinere mögliche Zeichenfolge für eine Übereinstimmung mit den Sprunganweisungen. Wenn wir das Zeilenende in unseren Suchzeichenfolgen verwenden, laufen wir nicht Gefahr, Anführungszeichen oder Benutzerfunktionen (die in Sinclair immer Klammern verwenden) aufzunehmen.
GO TO
erfordert aufgrund desFOR ... TO
Konstrukts einen größeren String (zB compare50 FOR X=AGO TO 100
and50 GO TO 100
)Der Code unterstützt keine Anweisungen in der Form
GO TO200
(ohne Leerzeichen), obwohl das ZX-Handbuch impliziert, dass es sich bei mehreren Beispielen um gültigen Code handelt (die Bearbeitung würde ein Dutzend Bytes mehr kosten).Der Code fügt eine neue Zeile am Anfang und eine weitere am Ende des Programms hinzu. Ich könnte dies am Ende bereinigen (ein Dutzend weitere Bytes), aber ich denke, dass der ZX wahrscheinlich leere Zeilen ignorieren würde.
Unten eine besser lesbare Version:
quelle
Pip
-rn
, 63 BytesProbieren Sie es online!
Erläuterung
Installieren
Das
-r
Flag liest das gesamte stdin und speichert es als eine Liste von Zeilen in der lokalen Variableng
. Die globale Variablet
ist auf 10 vorinitialisiert, und die globale Variables
ist auf vorinitialisiert" "
.Zieht die Liste der Zeilen
g
in die globale Variable einy
, damit sie in der Funktion verfügbar ist, die wir definieren werden.Zeilennummern-Übersetzungsfunktion
Wir konstruieren eine Funktion, die aus einer beliebigen Zeilennummer im ursprünglichen Nummerierungsschema (einschließlich einer nicht vorhandenen) die entsprechende Zeilennummer im neuen Nummerierungsschema abbildet.
Angenommen, wir haben diese Zeilen:
Wir möchten 1 bis 10, 2-4 bis 20 und 5-9 bis 30 zuordnen. Wenn wir eine Liste der ursprünglichen Zeilennummern (
[1; 4; 9]
) haben, können wir mit einer Filteroperation herausfinden, wie viele dieser Zahlen kleiner sind als die Zeilennummer, die wir konvertieren wollen. Multiplizieren Sie dieses Ergebnis mit 10 und addieren Sie 10, und wir haben die gewünschte Antwort.Wenn Sie beispielsweise 9 konvertieren, sind zwei Zeilennummern (1 und 4) kleiner als 9. 2 * 10 + 10 ergibt 30. Wenn Sie 3 konvertieren, ist eine Zeilennummer (1) kleiner als 3. 1 * 10 + 10 gibt 20.
Hier ist der Code (leicht modifiziert, um leichter zu lesen):
Erster Ersatz:
GO TO
,GO SUB
, undRUN
Der Rest des Programms ist ein einzelner Ausdruck, der
g
einige reguläre Ausdrücke ersetzt (die vektorisieren und auf jede Zeile in angewendet werdeng
).Hier ist der erste Ersatz:
Die Regex paßt jeder
RUN
,GO SUB
undGO TO
, gefolgt von einer Zahl, gefolgt von Zeilenende. Dies stellt sicher, dass es weder innerhalb von Zeichenfolgen nochRUN
ohne Zeilennummer übereinstimmt .Die Reihenfolge der Erfassungsgruppen ist wichtig. Die erste Gruppe fängt den Befehl (eine
RUN
,GO SUB
oderGO TO
). Die zweite Gruppe erfasst, falls verwendet, entwederSUB
oderTO
. Wir müssen diesen Teil nicht erfassen, aber eine nicht erfassende Gruppe würde zusätzliche Bytes benötigen. Dann erfasst die dritte Gruppe die Zeilennummer.Wir verwenden eine Rückruffunktion für den Ersatz. Mit Callback - Funktionen in Pip ist das ganze Spiel das erste Argument
a
, und die Fängergruppen sind , um die nachfolgenden Argumenteb
,c
,d
, unde
. Wir haben also den Befehl in der ersten Gruppe, die rein gehtb
, und die Zeilennummer in der dritten Gruppe, die rein gehtd
. Die einzige Änderung , die wir machen müssen ist die Zeilennummer durch unsere Umwandlungsfunktion zu übergeben, die Lisp-Stil genannt wird:(nd)
. Dann verknüpfen wir das mitb
und einem Leerzeichen und geben es zurück.Zweiter Ersatz: Zeilennummern
Alles, was konvertiert werden muss, sind die Zeilennummern am Anfang der Zeilen.
Der reguläre Ausdruck entspricht einer Ziffernfolge am Anfang einer Zeile. Wieder verwenden wir eine Rückruffunktion; Dieses Mal ist die Konvertierungsfunktion
n
selbst ausreichend, da die gesamte Übereinstimmung (erstes Argumenta
) die Zahl ist, die konvertiert werden soll.Da dies der letzte Ausdruck im Programm ist, druckt Pip das Ergebnis automatisch aus. Das
-n
Flag trennt die Ergebnisliste mit Zeilenumbrüchen.quelle