Was, dieser Beitrag existiert noch nicht?
Natürlich GolfScript ist gemacht für Golf, so dass Sie , dass keine konkreten Tipps vielleicht denken wirklich benötigt werden. Um die Funktionen von GolfScript voll ausnutzen zu können, müssen Sie einige nicht offensichtliche Tricks lernen. In diesem Beitrag werden hilfreiche Tipps und Tricks gesammelt.
Zunächst finden Sie hier die offiziellen GolfScript-Referenzseiten. Sie sollten sich zuerst mit den folgenden Themen vertraut machen:
Insbesondere würde ich sehr empfehlen, die Seiten in dieser Reihenfolge zu lesen - die Kurzanleitung ist von geringem Nutzen, bis Sie mit den integrierten Funktionen bereits einigermaßen vertraut sind, und das Lernprogramm enthält einige wichtige Details, die auf den anderen Seiten nicht erläutert werden .
Ps. Aus Gründen der Inspiration und des persönlichen Interesses sind hier einige Fragen, auf die ich gern nette Antworten hätte:
Wie kann ich in GolfScript eine begrenzte Transliteration durchführen?
{FROM?TO=}%
funktioniert, wenn Sie sicher sein können, dass alle Eingaben in gefunden wurdenFROM
(oder nicht, dass sie alle dem letzten Element von zugeordnet wurdenTO
), aber alle Möglichkeiten, die ich gesehen habe, um nicht zugeordnete Werte unverändert zu lassen, mehr oder weniger klug waren.Wie konvertiere ich einen String am besten in ein Array von ASCII-Codes und zurück? Welche Operationen machen das als Nebeneffekt? Wie lassen sich die Zeichen in einer Zeichenfolge am besten auf dem Stapel ablegen (wie
~
bei Arrays)?
quelle
... x
in etwas zu verwandeln... [x]
? Das Beste, was ich sehen kann, ist[.;]
.x
es sich um eine Zahl handelt,[]+
funktioniert sie und ist ein Zeichen kürzer. Und natürlich, wennx
das einzige auf dem Stapel ist, dann reicht es einfach]
.Antworten:
Rational / Float / Komplex
Ich habe so oft gelesen, dass GolfScript nur Ganzzahlen enthält, die ich zu glauben begann. Nun, das stimmt nicht.
Die Ausgabe ist
mit dem Standard GolfScript Interpreter und
auf Web GolfScript .
Ähnliche Hacks ermöglichen das Casting in Rational, Float oder sogar Complex:
quelle
Gint.new(@val**b.val)
. Es scheint, dass demGint
Konstruktor eine int-Besetzung fehlt ...Eine Zahl negieren
Eine Sache, die GolfScript fehlt, ist ein eingebauter Negationsoperator. Die offensichtlichen Möglichkeiten, eine Zahl auf dem Stapel in ihr Negativ umzuwandeln, wie
-1*
oder0\-
, erfordern drei Zeichen. Es gibt jedoch zwei Möglichkeiten:Dies funktioniert, weil GolfScript die Zweierkomplementarithmetik verwendet , sodass ~ x gleich - x −1 ist.
Natürlich
(~
funktioniert die Variante auch; Die Wahl zwischen ihnen ist in der Regel Geschmackssache.quelle
Ein Array mischen
Die einfachste Möglichkeit, ein Array in GolfScript zu mischen, besteht darin, es nach einem zufälligen Sortierschlüssel zu sortieren. Wenn Sie nur ein paar Werte grob mischen müssen, reicht der folgende Code aus:
Beachten Sie, dass dies selbst für kurze Listen kein sehr gutes Mischen ergibt. Aufgrund des Geburtstagsparadoxons muss das Argument für ein einigermaßen einheitliches Mischen
rand
deutlich größer sein als das Quadrat der Länge der Liste, die gemischt wird.Das Ersetzen des
9
obigen durch99
ergibt somit einigermaßen gute Ergebnisse für Listen mit bis zu zehn Elementen, zeigt jedoch eine merkliche Verzerrung für längere Listen.Der folgende Code, der 9 9 = 387.420.489 mögliche Werte verwendet, ist für bis zu etwa 1000 Elemente geeignet (und für bis zu etwa 20.000 akzeptabel):
Fügen Sie für sehr lange Listen eine weitere 9 für 99 99 ≈ 3,7 × 10 197 Werte hinzu:
Testen:
Hier ist die Verteilung des ersten Elements in einer Liste mit 10 Elementen, die unter Verwendung der oben gezeigten verschiedenen Varianten gemischt wurde. Es wurden über 10.000 Versuche durchgeführt:
Die Ausgabe von
10,{;9rand}$0=
zeigt eine sehr deutliche Tendenz, da0
es mehr als dreimal so wahrscheinlich ist, dass sie auf der ersten Position landet wie1
:Mit
10,{;99rand}$0=
ist der größte Teil der Verzerrung verschwunden, aber es bleibt noch ein merklicher Betrag übrig:Bei
10,{;9.?rand}$0=
ist die Ausgabe grundsätzlich nicht von einer wirklich zufälligen Stichprobe zu unterscheiden:Ps. Für ein wirklich schlechtes Mischen von numerischen Arrays oder Zeichenfolgen kann der folgende Code manchmal akzeptabel sein:
Es wird im Allgemeinen lächerlich voreingenommen sein, aber solange alle Elemente des Eingabearrays (oder alle Zeichencodes in der Zeichenkette) größer als eins sind, hat es eine Wahrscheinlichkeit ungleich Null, eine Permutation des Arrays zu erzeugen, die manchmal erfüllt schlecht geschriebene Herausforderungsanforderungen.
quelle
So adressieren Sie eine bestimmte Unterfrage:
Für diejenigen, die das Problem nicht verstehen, gibt das Typensystem von GolfScript den Typen in der Reihenfolge Integer, Array, String, Block den Vorrang. Dies bedeutet, dass gewöhnliche Array-Operationen, die auf eine Zeichenfolge angewendet werden, fast immer eine Zeichenfolge ergeben. Z.B
wird
'BCD234'
auf dem Stapel verlassen.Daher besteht die beste Möglichkeit, eine Zeichenfolge in ein Array von ASCII-Codes zu konvertieren, mit ziemlicher Sicherheit darin, die Zeichen auf dem Stapel zu sichern und sie dann in einem Array zusammenzufassen.
Was ist der beste Weg, um die Zeichen in einer Zeichenkette auf dem Stapel abzulegen?
{}/
Wie kann man einen String am besten in ein Array von ASCII-Codes konvertieren?
[{}/]
(mit dem üblichen Vorbehalt, dass man das überspringen kann, wenn nichts anderes auf dem Stapel ist[
)Wie kann ein Array von ASCII-Codes am besten in eine Zeichenfolge konvertiert werden?
''+
(Beachten Sie, dass dies auch das Array abflacht, also zB[65 [66 67] [[[49] 50] 51]]''+
gibt'ABC123'
)quelle
[]+''+
? (scheint ziemlich lang zu sein)Wenn Ihr Programm auf mysteriöse Weise kaputt geht, überprüfen Sie Ihre Variablen
Ich habe gerade eine Weile damit verbracht, ein anscheinend korrektes Programm zu debuggen, das
!
als Variable verwendet wurde (mit der Begründung, dass ich es nicht wieder verwenden würde). Leider ich tat Gebrauchif
, und es stellt sich heraus , dass die Durchführung vonif
Anrufen ,!
die Verzweigung zu folgen , um zu entscheiden.quelle
Wickeln Sie das oberste Element des Stapels in ein Array
Für die vollständige Allgemeinheit scheint die beste Option 4 Zeichen zu sein. In bestimmten Sonderfällen ist es jedoch möglich, dies zu reduzieren.
1 Zeichen
]
funktioniert in dem speziellen Fall, dassx
das einzige ist, was auf dem Stapel.3 Zeichen
[]+
Funktioniert in dem speziellen Fall, dassx
es sich um eine Ganzzahl handelt..,/
Funktioniert in dem speziellen Fall, dassx
es sich um ein wahrheitsgemäßes Array oder eine Zeichenfolge handelt. ZB"AB".,/
gibt["AB"]
;3,.,/
gibt[[0 1 2]]
. Doch"".,/
und[].,/
beide geben nach[]
.4 Zeichen
[.;]
funktioniert bedingungslos.quelle
Das ist eine gute Frage. Es gibt keine direkte Möglichkeit, einem Array-Element in GolfScript einen Wert zuzuweisen. Auf die eine oder andere Weise müssen Sie also das gesamte Array neu erstellen.
Die kürzeste allgemeine Möglichkeit, einen neuen Wert
x
am Indexi
in ein Array einzufügen, besteht darin, das Array am angegebenen Index zu teilen undx
an die erste Hälfte anzuhängen , bevor Sie sie wieder zusammenfügen:.i<[x]+\i>+
(11 Zeichen) - Fügt den Wertx
am (0-basierten) Index in das Array eini
Um den Wert bei Index durch zu ersetzen , müssen wir nur die zweite Hälfte des Arrays um ein Element kürzen:
i
x
.i<[x]+\i)>+
(12 Zeichen) - Ersetzen Sie das Element am (0-basierten) Indexi
durch den Wertx
Alternativ kann auch die erste Hälfte gekürzt werden, jedoch mit einer 1-basierten Indizierung, was manchmal vorzuziehen ist:
.i(<[x]+\i>+
(12 Zeichen) - Ersetzen Sie das Element am (1-basierten) Indexi
durch den Wertx
Wenn
x
es sich bei allen obigen Beispielen um eine Zahl handelt, können die eckigen Klammern weggelassen werden, um zwei Zeichen zu speichern, da sie+
sowieso automatisch in ein Array umgewandelt werden:.i<x+\i>+
(9 Zeichen) - Fügen Sie die Zahlx
am (0-basierten) Index in das Array eini
.i<x+\i)>+
(10 Zeichen) - Ersetzen Sie das Element am (0-basierten) Indexi
durch die Zahlx
.i(<x+\i>+
(10 Zeichen) - Ersetzen Sie das Element bei (1-basiertem) Indexi
durch die Zahlx
Die Klammern können auch weggelassen werden, wenn es sich bei einem
x
oder beiden "Array" -Eingaben (oder beiden) tatsächlich um Zeichenfolgen handelt. In diesem Fall wird das Ergebnis auch in eine Zeichenfolge umgewandelt (unter Verwendung der üblichen Regeln für die Konvertierung von Feldern → Zeichenfolgen).Ps. Wenn wir als Sonderfall wissen, dass das Array zwischen
i
und 2 ×i
Elemente enthält, können wirx
am (0-basierten) Index ein neues Elementi
miti/[x]*
(6 Zeichen) einfügen . Tatsächlich wird das Array in Blöcke von bis zui
Elementen aufgeteilt undx
zwischen den einzelnen Blöcken eingefügt. Beachten Sie, dass in diesem Fall die Klammern erforderlich sind, auch wennx
es sich um eine Zahl handelt.Pps. Ein alternativer Ansatz besteht darin, dynamisch benannte Variablen zu verwenden. Beispielsweise,
ordnet den Wert
'foo'
der Variablen zux42
, währendwerde es abrufen.
Sie können dies weiter optimieren, indem Sie das
x
Präfix weglassen und nur die numerischen Literale direkt zuweisen. Dies ist in GolfScript völlig legal und ermöglicht Ihnen, ein Zeichen aus dem Zuweisungscode zu speichern und den Abrufcode auf "nur"`~
(oder gar nichts, wenn dies der Fall ist) zu verkürzen der Index ist konstant!). Der Nachteil ist natürlich, dass die Zuweisung zu einem numerischen Literal den Wert dieses Literal an einer anderen Stelle in Ihrem Code überschreibt. Häufig kann jedoch die Verwendung von Zahlenliteralen vermieden werden (oder zumindest auf den Beginn des Programms beschränkt werden, bevor eines von ihnen neu zugewiesen wird). In diesem Fall ist dieser Trick völlig in Ordnung.quelle
i
für 9 Bytes ersetzen :.[i=]/[x]*
Endgültige Ausgabe-Manipulation
Wenn Ihr Programm endet, gibt der GolfScript-Interpreter standardmäßig alles auf dem Stapel sowie eine letzte neue Zeile so aus, als würde Ihr Programm mit folgendem Ergebnis beendet:
Was die Dokumentation nicht direkt erwähnen ist , dass der Dolmetscher wörtlich nennt die eingebaute in
puts
dieser Ausgabe zu erzeugen, und dass dieses eingebaut ist wörtlich wie folgt definiert:So können Sie die endgültige Ausgabe durch eine Neudefinition unterdrücken oder manipulieren
wenn Sie das Gefühl wirklich verdreht). Hier sind einige Beispiele:
puts
,print
und / odern
(oderLetzte Zeile unterdrücken:
(Natürlich können Sie das weglassen,
;
wenn Sie nichts gegen eine zusätzliche leere Zeichenfolge auf dem Stapel haben.)Endausgabe vollständig unterdrücken:
Dies überschreibt
puts
alles, was sich auf dem Stapel befindet. Wenn das etwas ist, das Sie nicht ausführen möchten, können Sie0:puts;
stattdessen zB verwenden. Beachten Sie, dass dies auch unterdrücktp
(was als definiert ist{`puts}:p;
), Sie können es aber trotzdemprint
für die Ausgabe verwenden, wenn Sie möchten.quelle
nothing
du meinst\n
?];
die endgültige Ausgabe unterdrücken.Minimal Maximal
Um den kleinsten / größten Wert in einem Array zu finden, sortieren Sie ihn einfach und nehmen Sie das erste / letzte Element:
$0=
(3 Zeichen) - Minimum Element in einer Arry$-1=
(4 Zeichen) - Maximales Element in einem ArrayWenn Sie die Länge des Arrays kennen und es 10 Elemente oder weniger sind, können Sie das Maximum in drei Zeichen finden, indem Sie es
-1
durch den Index des letzten Elements ersetzen .Wenn Sie die Werte auf dem Stapel haben, können Sie sie einfach zuerst in einem Array sammeln. Ein gelegentlich nützlicher Trick besteht darin,
[\]
die beiden obersten Elemente des Stapels in einem Array zu[@]
sammeln , während die drei obersten Elemente gesammelt werden. So erhalten wir:[\]$0=
(6 Zeichen) - Mindestens zwei Werte im Stapel[@]$0=
(6 Zeichen) - mindestens drei Werte im Stapel[\]$1=
(6 Zeichen) - Maximal zwei Werte im Stapel[@]$2=
(6 Zeichen) - Maximal drei Werte im StapelMit demselben Trick kann auch der Median von drei Werten ermittelt werden, was gelegentlich nützlich sein kann:
[@]$1=
(6 Zeichen) - Median von drei Werten im StapelHier ist ein weiterer potenziell nützlicher Trick, um das Minimum / Maximum zweier Werte zu ermitteln, während die ursprünglichen Werte auf dem Stapel belassen werden :
.2$>$
(5 Zeichen) - Finden Sie mindestens zwei Werte im Stapel, ohne die ursprünglichen Werte zu verändern.2$<$
(5 Zeichen) - Finden Sie maximal zwei Werte im Stapel, ohne die ursprünglichen Werte zu verändernEs funktioniert so, dass
.2$
die beiden obersten Elemente des Stapels in umgekehrter Reihenfolge geklont werden (dha b
→a b b a
),<
/>
die Kopien verglichen werden und 0 oder 1 zurückgegeben$
werden. Je nach Ergebnis des Vergleichs kopiert scalar dann einen der beiden Eingabewerte.Wenn Sie zwei nichtnegative Ganzzahlen auf dem Stapel haben, können Sie mit
,\,&,
(5 Zeichen) das Minimum und mit,\,|,
(5 Zeichen) das Maximum ermitteln. Bei diesem Trick werden Schnittmenge und Vereinigung über die Bereiche festgelegt. Sie können ein anderes Zeichen speichern, wenn Sie,
jedes Argument einzeln anwenden können , ohne es austauschen zu müssen. Da diese Methode einen Bereich für jedes Argument berechnet, ist sie für größere Zahlen nicht sehr effizient, kann jedoch für kleinere Eingaben sehr nützlich sein.Ein noch kürzerer Weg, um das Minimum von zwei nicht negativen ganzen Zahlen auf dem Stapel zu finden, ist
,<,
(3 Zeichen). Leider funktioniert dieser Trick nicht, um das Maximum zu finden.Absolutwert
Der in GolfScript integrierte Absolutwertoperator ist
abs
(3 Zeichen). Das sind zwar zwei Zeichen mehr, als ich vorziehen würde, aber im Allgemeinen ist es schwer zu schlagen.In einigen Fällen (z. B. zum Sortieren nach dem absoluten Wert) ist das Quadrat einer Zahl möglicherweise ein geeigneter Ersatz für den absoluten Wert. Dies kann entweder
2?
oder in zwei Zeichen berechnet werden.*
. So erhalten wir:{.*}$0=
(7 Zeichen) - Minimum Element durch absoluten Wert im Array{.*}$-1=
(8 Zeichen) - Maximales Element nach Absolutwert im ArrayAnstatt beispielsweise zu testen, ob der absolute Wert einer Zahl mit
abs 3<
(6 Zeichen, einschließlich Leerzeichen) kleiner als 3 ist , können Sie mit.*9<
(4 Zeichen, kein Leerzeichen erforderlich) auch testen, ob das Quadrat kleiner als 9 ist .quelle
,\,&,
(5 Zeichen) das Minimum und mit,\,|,
(5 Zeichen) das Maximum ermitteln. Bei diesem Trick werden Schnittmenge und Vereinigung über die Bereiche festgelegt. Sie können ein anderes Zeichen speichern, wenn Sie,
jedes Argument einzeln anwenden können , ohne es austauschen zu müssen. Da diese Methode einen Bereich für jedes Argument berechnet, ist sie für größere Zahlen nicht sehr effizient, kann jedoch für kleinere Eingaben sehr nützlich sein.Duplikate aus einem Array entfernen
Die Mengenoperatoren
|
(Vereinigung),&
(Schnittmenge) und^
(symmetrischer Unterschied) reduzieren mehrere Array-Elemente zu einem. Der einfachste Weg, um doppelte Elemente aus einem Array zu entfernen, besteht darin, seine Vereinigung oder Schnittmenge mit sich selbst zu nehmen:oder:
Diese Operatoren behandeln Zeichenfolgen als Arrays von Zeichen, sodass sie auch zum Entfernen doppelter Zeichen aus Zeichenfolgen verwendet werden können.
quelle
Eingeschränkte Transliteration
So adressieren Sie eine bestimmte Unterfrage: Welche Methode eignet sich bei einer bestimmten Zeichenfolge am besten zum Ausführen von
tr
? Z.Btr/ABC/abc/
Wenn alle Zeichen in der Zeichenfolge betroffen sind, ist dies recht einfach:
{'ABC'?'abc'=}%
(Overhead: 9 Zeichen).Jedoch, dass die Pausen, wenn einige der Charaktere nicht transkribiert und
'ABC'?
gibt-1
.Wenn die Transliteration nicht zyklisch ist, kann sie einzeln durch Zeichenfolgensplits und -verknüpfungen ersetzt werden:
'AaBbCc'1/2/{~@@/\*}/
(Overhead: 15 Zeichen). Das ist zwar verbesserungsfähig, aber es gibt einen alternativen Ansatz, der derzeit besser ist und für zyklische Transliterationen funktioniert.Derzeit haben die kürzesten allgemeinen Lösungen einen Overhead von 14 Zeichen:
Ein Ansatz beinhaltet ein Escape-Zeichen:, wobei das ein literales Null-Byte bezeichnet. (Natürlich ist diese Methode nicht vollständig
{.'ABC'?'abc0'=\or}%
0
allgemein: Sie kann kein anderes Zeichen in ein Null-Byte abbilden.)Alternativ
{.'ABC'?'abc'@),+=}%
wird derselbe Overhead benötigt, es werden jedoch nur druckbare ASCII-Zeichen verwendet. Dies@),+
ist ein umständlicher (aber anscheinend der kürzeste) Weg, um sicherzustellen, dass die Ersetzungszeichenfolge immer mit dem Eingabezeichen endet.quelle
'ABCDEF'
erhalte ich für die Eingabezeichenfolge das Ergebnis'abc000'
, aber das richtige Ergebnis wäre'abcDEF'
. Vermisse ich etwas?Verwandle einen String in ein Array von Zeichen
Sie können dies tun, indem Sie Folgendes eingeben:
1/
danach.Beispiel:
"String"1/
Drückt, um das Array zu stapeln['S''t''r''i''n''g']
.Dies ist praktisch, wenn Sie Zeichen in der Zeichenfolge verschieben möchten.
quelle
"abc"1/(+
->"bca"
, aber"abc"(+
->bc97
.Zuordnung zu Zahlenliteralen
Anstatt
1:x
die Variable zu schreiben und dann zu verwenden / aktualisierenx
, können Sie sie häufig einfach direkt verwenden und aktualisieren1
:Dies funktioniert natürlich auch für andere Startwerte, bricht jedoch ab, wenn dieser Wert an einer anderen Stelle in Ihrem Code auftritt.
Zeichensetzung als Variablennamen
Wenn Sie haben Variablen zu verwenden, ist es auch oft weise Interpunktion zu verwenden , die nicht bereits in Ihrem Code ist - viele Programme tun können , ohne
&
,|
,^
, oder?
. Auf diese Weise können Sie beispielsweise schreiben,&n
anstattx n
Ihre Variable und dann eine neue Zeile zu schreiben.quelle
!
ist oft eine schlechte Idee, da sie brechenif
unddo
(sowiewhile
,until
,and
,or
undxor
). Ebensoor
wird vom Interpreter als Alias für definiert1$\if
, also neu definiert1
,$
oder es\
wird auch gebrochen. Die Neudefinition`
Pausenp
.Ein Array filtern
Die allgemeinste Methode zum Filtern eines Arrays ist die Verwendung von
{ },
, die den Codeblock für jedes Element des Arrays auswertet und die Elemente auswählt, für die der resultierende Wert wahr ist (dh, sie verhalten sich wiegrep
in Perl).Die Verwendung des Array-Subtraktionsoperators
-
ist jedoch häufig kürzer. Dieser Operator nimmt zwei Arrays und entfernt jedes Element, das im zweiten Array vorkommt, aus dem ersten. Die Reihenfolge der Elemente im ersten Array wird nicht geändert oder Duplikate werden ausgeblendet. Ein nützlicher Trick besteht darin, die Subtraktionsoperation zweimal anzuwenden, um einen nicht kollabierenden Array-Schnittoperator zu erhalten:a b -
: Entferne alle im Array gefundenen Elementeb
aus dem Arraya
a. b --
: Entferne alle Elemente, die nicht im Array gefunden wurden,b
aus dem Arraya
Dies kann insbesondere verwendet werden, um zu zählen, wie oft ein Element in einem Array vorkommt:
a.[c]--,
: Zähle, wie oft das Elementc
im Array vorkommta
Im Allgemeinen ist diese Methode nicht optimal, da:
a[c]/,(
: Zähle, wie oft das Elementc
im Array vorkommta
a{c=},,
: Zähle, wie oft das Elementc
im Array vorkommta
ist ein Zeichen kürzer (und wenn es in Ordnung ist, die Anzahl um eins zu
a[c]/,
verringern, wird ein Zeichen mehr gespeichert). In dem speziellen Fall, in dem es sichc
um eine Zahl unda
ein normales Array (keine Zeichenfolge) handelt, können die eckigen Klammernc
weggelassen werden, da der-
Operator seine Argumente auf den gleichen Typ zwingt:a.c--,
: Zähle, wie oft die Zahlc
im Array vorkommt (keine Zeichenkette!)a
(Wenn
a
es sich um eine Zeichenfolge handelt undc
eine Zahl zwischen 0 und 9 ist,a.c--
wird die Häufigkeit gezählt, mit der die Zifferc
vorkommta
.)Ein ähnlicher Trick kann verwendet werden, um das häufigste Element in einem Array zu finden :
Wenn die Eingabe wiederum ein Array von Zahlen ist, kann die gesamte
[.]
Sequenz weggelassen werden. Leider funktioniert dies nicht für Saiten ohne die[.]
.quelle
a[c]/,(
unda{c=},,
sind ein Byte kürzer.Lesen Sie aus STDIN
GolfScript kann von stdin lesen:
Dies liest weiter von STDIN, bis die EOF erreicht ist. Alternative:
oder
Andere Dinge zur Verfügung:
Sie können jeweils nur einmal verwendet werden (und auch einmal für jede Änderung des Parameters, auch noch einmal mit leeren Klammern). Danach erhalten Sie den ursprünglichen Wert anstelle eines neuen Werts.
quelle
{"#{STDIN.readline}"p}2*
die nicht 2 Zeilen liest, sondern die Zeichenfolge nur einmal ausgewertet wird.i
eine Ganzzahl initialisieren ,'"#{'i):i';STDIN.gets}"'++~
wird bei jeder Auswertung ein anderes Ergebnis ausgegeben. Auch Backticks sind erwähnenswert. Wenn wir von Linux ausgehen, können wir zB`head -1`
stattSTDIN.gets
."#{var'g','gpush Gstring.new(STDIN.gets)'.cc}";
Sie auch einen neuen GolfScript-Operator definiereng
, der eine Zeile von stdin liest und auf den Stapel schiebt.Hexadezimale Eingabe decodieren
GolfScript hat keine hexadezimalen Integer-Literale. Sie können also leider nicht einfach hexadezimale Eingaben mit analysieren
~
. Wenn Ihr Code hexadezimal eingegeben werden muss, müssen Sie ihn stattdessen manuell analysieren.Diese 8-Zeichen-Schleife, die auf eine Zeichenfolge angewendet wird, konvertiert hexadezimale Kleinbuchstaben in ihre numerischen Entsprechungen:
Wenn Sie (auch) hexadezimale Großbuchstaben akzeptieren müssen, besteht die einfachste (und wahrscheinlich kürzeste) Lösung darin, diese zuerst mit Kleinbuchstaben zu versehen
32|
, für insgesamt 11 Zeichen:Beachten Sie, dass die Ausgabe technisch gesehen immer noch eine Zeichenfolge (bestehend aus den ASCII-Zeichen 0 bis 15) ist, die meisten GolfScript-Array-Funktionen jedoch auch Zeichenfolgen akzeptieren. Wenn Sie unbedingt ein Array benötigen, können Sie es immer verwenden
[{39%9-}/]
(wobei das erste[
optional ist, wenn der Stapel ansonsten leer ist).Um die Ausgabe des obigen Codes in eine Ganzzahl umzuwandeln, können Sie einfach
16base
(6 Zeichen) verwenden. Wenn Sie stattdessen ein Array von Bytes wünschen, ist die kürzeste Lösung, die ich gefunden habe, einfach jedes Paar von Hexadezimalziffern mit2/{16base}%
(11 Zeichen) zu decodieren . Alles in allem ist der kürzeste Code, den ich gefunden habe, um einen Hex-String in ein Byte-Array umzuwandeln, 8 + 11 = 19 Zeichen:Beachten Sie, dass die Ausgabe dieses Codes ist in der Tat ein Array, kein String. Bei Bedarf können Sie die Zeichenfolge verketten, indem Sie sie z. B. mit
""+
oder verknüpfenn+
.quelle
Neue eingebaute Operatoren definieren
Der standardmäßige GolfScript-Interpreter verfügt über eine selten verwendete Funktion , die interpolierten Ruby-Code in Strings in doppelten Anführungszeichen ermöglicht.
Ein Grund, warum diese Funktion nicht häufiger verwendet wird, ist, dass der interpolierte Code umständlich zur Kompilierungszeit ausgeführt wird und die Ausgabe vom GolfScript-Interpreter zwischengespeichert wird, so dass dasselbe Zeichenfolgenliteral auch innerhalb immer den gleichen Wert ergibt string eval.
Eine Sache, für die sich diese Funktion als gut herausstellt, ist die Definition neuer GolfScript-Operatoren, die in Ruby-Code implementiert sind. So definieren Sie beispielsweise einen neuen binären Additionsoperator, der genau wie der integrierte Standardoperator funktioniert
+
:Es spielt keine Rolle, wo Sie die Definition in Ihren Code einfügen. Der neue Operator wird definiert, sobald die doppelte Zeichenfolge mit dem Ruby-Code analysiert wird. Der
add
oben definierte Operator funktioniert genauso wie der eingebaute+
Operator und kann genauso verwendet werden:Das Definieren eines neuen Additionsoperators ist natürlich ziemlich nutzlos, es sei denn, Sie haben etwas Dummes getan, wie den eingebauten
+
Operator zu löschen . Mit demselben Trick können Sie jedoch neue Operatoren definieren, die Dinge tun, die Golfscript nicht (ohne weiteres) von Haus aus tun kann, z. B. das einheitliche Mischen eines Arrays:oder den Inhalt des gesamten Stapels drucken:
oder interaktive Eingabe:
oder sogar Webzugriff:
Eine etwas golferischere (und riskantere!) Implementierung der letzteren wäre natürlich zB:
Dies ist an sich nicht besonders golfen, ermöglicht Ihnen jedoch, die Fähigkeiten von GolfScript über das hinaus zu erweitern, was die eingebauten Befehle bieten.
Wie funktioniert es?
Die maßgebliche Referenz zur Definition neuer GolfScript-Operatoren auf diese Weise ist natürlich der Quellcode für den Interpreter . Das heißt, hier sind ein paar kurze Tipps:
Um einen neuen Operator zu definieren
name
, der den Ruby-Code ausführtcode
, verwenden Sie:Verwenden Sie im Code, um
gpop
einen Wert aus dem Stapel zu lesen undgpush
wieder einzuschieben. Sie können auch direkt über das Array auf den Stapel zugreifen$stack
. Zum Beispiel, um beidea
undb
auf den Stapel zu schieben , ist es golfer,$stack<<a<<b
als zu tungpush a;gpush b
.[
Array-Startmarkierungen werden im$lb
Array gespeichert . Diegpop
Funktion sorgt dafür, dass diese Markierungen nach unten korrigiert werden, wenn der Stapel unter ihre Position schrumpft, nicht jedoch, wenn das$stack
Array direkt manipuliert wird.Die
.cc
Zeichenfolgenmethode, mit der Ruby-Code in einer Zeichenfolge in einen GolfScript-Operator kompiliert wird, ist nur ein praktischer WrapperGblock.new()
. Es hat auch die Varianten.cc1
,.cc2
und.cc3
das macht den Bediener automatisch 1 Pop, 2 oder 3 Argumente vom Stapel und weisen Sie auf die Variablena
,b
undc
. Es gibt auch ein.order
Verfahren , das funktioniert wie.cc2
, mit der Ausnahme , dass es automatisch die Argumente sortiert Typ Priorität .Alle Werte auf dem GolfScript Stapel (und sollen!) Objekte vom Typ
Gint
,Garray
,Gstring
oderGblock
. Auf die zugrunde liegende native Ganzzahl oder das zugrunde liegende Array kann bei Bedarf über die.val
Methode zugegriffen werden .Gstring.val
ein Array vonGint
s! Um eineGstring
in eine native Ruby-Zeichenfolge zu verwandeln , rufen Sie.to_s
sie stattdessen auf (oder verwenden Sie sie in einem Kontext, der dies automatisch ausführt, z. B. bei der Zeichenfolgeninterpolation). Der Aufruf.to_gs
auf jedem GS Wert verwandelt es in einGstring
, so kann jeder GS - Wert mit Zeichenfolge werden.to_gs.to_s
.Die
gpush
Funktion bricht native Ruby-Zahlen, -Strings oder -Arrays nicht automatisch in die entsprechenden GS-Typen ein, sodass Sie dies häufig selbst tun müssen, indem Sie zGstring.new()
. B. explizit aufrufen . Wenn Sie etwas anderes als einen der GS-Werttypen auf den Stapel schieben, stürzt wahrscheinlich jeder Code ab, der später versucht, ihn zu manipulieren.Die GS-
.factory
Werttypen verfügen auch über eine Methode, die den Konstruktor des Typs aufruft. Dies kann nützlich sein, um z. B. Arrays / Strings nach der Bearbeitung ihres Inhalts neu zu verpacken. Alle Typen haben auch eine.coerce
Methode, mit der Typenzwang ausgeführt wird :a.coerce(b)
Gibt ein Paar zurück, das denselben Typ enthälta
und zu diesemb
gezwungen wird.quelle