Golftipps in Japt

18

Jetzt, da ich von Code Golf süchtig bin, ist es wahrscheinlich an der Zeit, ein paar Golfsprachen zu lernen.

Da ich fast ausschließlich in JavaScript spiele, scheint Japt die logische Sprache zu sein. Ich werde bei der nächsten Gelegenheit in die Dokumentation eintauchen, aber in der Zwischenzeit posten Sie bitte alle Tipps, die Sie für Japt haben, in den Antworten unten.

Als Anfänger in Japt- und Golfsprachen im Allgemeinen wäre es eine große Hilfe, wenn Sie Ihre Tipps nach Möglichkeit in JavaScript "übersetzen" könnten, um mich mit den Dingen vertraut zu machen.

Zottelig
quelle
Danke, dass du das gepostet hast. Ich hatte mich zurückgehalten, weil ich Japt irgendwann umgestalten wollte, aber das wird nicht so bald passieren, und es wird wahrscheinlich sowieso nicht viele Tipps durcheinander bringen. Tipp für mich: Tutorial schreiben: P
ETHproductions
Vergiss nicht, den Japt-Chatroom zu besuchen :)
Oliver

Antworten:

11

Verschieben von JavaScript nach Japt

Wie Sie vielleicht wissen, ist Japt einfach eine verkürzte, erweiterte Version von JavaScript. Ich habe Japt erstellt, weil ich es satt hatte, lange Eigenschaftsnamen wie String.fromCharCode(x)und zu verwenden Math.floor(x)und umständlich Dinge wie das Erstellen einer Reihe zu tun. Hier ist das absolute Minimum, das Sie wissen müssen, wenn Sie von JavaScript zu Japt wechseln:

  • Japt ist eine transpilierte Sprache; Japt Code transpiled auf JavaScript und dann als JS laufen. (Ich denke man könnte sagen kompiliert , aber transpiliert klingt mehr hipster. Disclaimer: Ich weiß absolut nichts darüber, hipster zu sein)
  • Alle Einträge sind standardmäßig vollständige Programme. Die Eingabe wird implizit geparst, und die ersten sechs Eingänge werden in die Variablen gesetzt U, V, W, X, Y, und Z; Das vollständige Array wird in gespeichert N. Das Ergebnis des letzten Ausdrucks wird automatisch gedruckt.
  • Alle Großbuchstaben sind Variablen und bleiben beim Transpilieren gleich. Die meisten haben voreingestellte Werte, die Sie im Abschnitt "Variablen" der Japt-Dokumentation (beim Interpreter ) finden.
  • Alle Kleinbuchstaben sind Prototypfunktionen oder -methoden . Japt fügt die Methoden a- z(und à- ÿ) für Zahlen, Zeichenfolgen und Arrays hinzu. Wenn Sie einen dieser Buchstaben verwenden, füllt Japt das .und aus (. Ucin Japt ist äquivalent zu U.c(in JavaScript, was je nach Art von ceil, charCodeAt oder concat bedeuten kann U. Hier kommt der größte Teil von Japts Kraft her. Eine vollständige Liste dieser Methoden finden Sie in den Abschnitten "_____ Funktionen" der Japt-Dokumentation (beim Interpreter ).
  • Ein Raum repräsentiert )und )repräsentiert )). Dies liegt daran, dass ich beim ersten Entwerfen von Japt so viele Bytes wie möglich speichern wollte, und so dachte ich zuerst, dies zu tun. (Obwohl Us w nes besser aussieht als Us)w)n), IMHO.)
  • Eine Funktion wird als bezeichnet ABC{...}, wobei es ABCsich um eine beliebige Folge von Variablen handeln kann. Funktionen funktionieren größtenteils wie in JS. Der Hauptunterschied besteht darin, dass der letzte Ausdruck automatisch zurückgegeben wird (anstatt returnKlammern in ES6 zu verwenden oder zu verwenden ).
  • 'bezeichnet eine einzelne Zeichenkette (dh 'aist dasselbe wie "a"), #nimmt den nächsten Zeichencode und wird zu dieser Zahl ( #eist dasselbe wie 101).
  • Alles zwischen Dollarzeichen $bleibt während des Transpilationsprozesses gleich. Sie können dies zum forBeispiel verwenden, um Schleifen zu implementieren , da Japt diese nicht hat, aber ich würde vorschlagen, andere Methoden zu verwenden (zum Beispiel mfür Zeichenfolgen und Arrays oder ofür Zahlen).
  • Die meisten anderen Zeichen in JS allgemein verwendet - "", 0-9, (, +, =, usw. - gleich bleiben , wenn transpiled (zum größten Teil jedenfalls).

Und das ist alles, was Sie wissen müssen, um einfachen Japt-Code zu schreiben. Das Erreichen einer maximalen Golfkraft in Japt erfordert mehr Kenntnisse, die jedoch in anderen Antworten zu finden sind.


Hier ist ein einfaches Beispiel. Angenommen, Sie möchten eine Zeichenfolge aus ASCII-Zeichen verwenden und diese durch den hexadezimalen Zeichencode ersetzen. So könnten Sie das in JavaScript tun:

U.split("").map(x=>x.charCodeAt(0).toString(16)).join("")

Nun zu Japt konvertieren. .split("")in JS ist gleichbedeutend mit q""in Japt oder sogar kürzer q. .join("")ist auch gerecht q, der Unterschied ist, dass das Objekt ein Array anstelle einer Zeichenfolge ist. .map(ist m, .charCodeAt(ist cund .toString(ist s. So könnte unser Japt-Code aussehen:

Uq mX{Xc0 s16} q 

In Japt mfunktioniert dies jedoch sowohl für Zeichenfolgen als auch für Arrays, sodass wir beide qs entfernen können :

UmX{Xc0 s16}

Online testen! Wie Sie im Feld "JS-Code" sehen können, gilt dies direkt für:

U.m(function(X){return X.c(0).s(16)})

Wenn Sie lernen, mit Japt zu arbeiten, werden Sie sich immer weniger darauf konzentrieren, JavaScript hin und her zu konvertieren und in Japt als eigene Sprache zu programmieren. Hier ist eine Erklärung, bei der der JavaScript-Teil vollständig weggelassen wird:

UmX{Xc0 s16}
               // Implicit: U = input string
UmX{       }   // Take U, and replace each character X with the result of this function:
    Xc0        //   Take the char-code at index 0 in X (the first and only one).
        s16    //   Convert this to a hexadecimal string.
               // Implicit: output result of last expression
ETHproductions
quelle
Es ist möglicherweise besser, einen weiteren Schritt anzuzeigen: die Unicode-Verknüpfungen. In diesem Fall könnten wir 2B mit ihnen sparen. Vielleicht möchten Sie auch hinzufügen, dass Sie bestimmte Dinge am Ende weglassen können. Das würde ein weiteres Byte sparen.
Luke
Ein exzellenter Primer, danke ETH. Ich denke, es gibt genug, um mich auf ein paar einfache Herausforderungen einzulassen.
Zottelig
Wäre es richtig, wenn ich dies mit dem kombiniere, was ich bisher aus der README-Datei entnommen habe, dass das obige Beispiel weiter verkürzt werden könnte Um_c s16?
Shaggy
Oder noch kürzer ¡Xc s16:?
Shaggy
1
@ Shaggy Du hast recht! Mann, du hast das schnell herausgefunden ;-) Ich werde einige grundlegende Japt-Golftipps (wie Unicode-Shortcuts und dergleichen) hinzufügen, wahrscheinlich als andere Antworten.
ETHproduktionen
8

String-Arrays komprimieren

UPDATE: Die Tools in diesem Tipp wurden neu geschrieben, verbessert und in meinen Japt-Interpreter integriert . Um die besten Ergebnisse zu erzielen, wird empfohlen, diesen Kompressor über einem der unten aufgeführten zu verwenden. Ich werde diesen Tipp wiederholen, wenn ich etwas mehr Zeit habe, und ihn unter Berücksichtigung des neuen Kompressors neu schreiben.

Einführung

Wenn Ihr Code ein Array von Zeichenfolgen enthält, ist es am offensichtlichsten, wenn Sie jede ZeichenfolgeOc einzeln durchlaufen . In diesem Tipp wird mit dem Array gearbeitet ["lollipop","marshmallow","nougat","oreo"], das anfänglich 42 Byte wiegt. Durchlaufen jeder Zeichenfolge Ocgibt uns:

[`lo¥ipop`,`Ú\hÚaow`,`Í`,`eo`]

Das sind jetzt 33 Bytes, eine ordentliche Ersparnis.


Schritt 1

Aber wir können es besser machen. Wenn wir das Array zu einer durch Zeilenumbrüche getrennten Zeichenfolge zusammenfügen, können wir die Klammern, Kommas und überflüssigen Backticks entfernen und nach Zeilenumbrüchen aufteilen, um unser Array zu erhalten. Wenn wir das auf unser Beispielarray anwenden, erhalten wir Folgendes:

`lo¥ipop
Ú\hÚaow
Í
eo`·

Bis zu 26 Bytes jetzt.


Schritt 2

Aber wir können es noch besser machen! Wir könnten einen Kleinbuchstaben verwenden, um die Zeichenfolgen anstelle einer neuen Zeile abzugrenzen, die möglicherweise in die Komprimierung einbezogen wird. zwird in keiner unserer Saiten verwendet, also lasst uns das mal sehen, wie wir uns verstehen.

`lo¥ipopzÚ\hÚaowzÍzeo`qz

Ah, Nüsse - keine Besserung da; unsere Byteanzahl ist um eins gestiegen! Es könnte ein weiterer Brief, den Sie verwenden können , aber je nach Zeichenketten, könnte es durchaus ein paar zu versuchen - in unserem Beispiel gibt es 11: b,c,d,f,j,k,q,v,x,y,z. Jeder Versuch wäre ziemlich mühsam, wo dieses handliche Werkzeug ist Spiel. Geben Sie Ihre durch Zeilenumbrüche getrennten Zeichenfolgen ein, und es wird versucht, die Zeichenfolgen mit jedem Buchstaben abzugrenzen, der in keiner der Zeichenfolgen enthalten ist, und Folgendes ausgegeben:

  • die kürzeste komprimierte Zeichenfolge,
  • das verwendete Trennzeichen und
  • seine Länge.

Das Durchlaufen unserer Beispielzeichenfolgen zeigt, dass bdie besten Ergebnisse erzielt werden:

`lo¥ipáæqrÚaowbÍÞo`qb

Und da haben Sie es, wir haben nur 24 Bytes.


Schritt 3

Aber wir können es noch besser machen! Wenn die Reihenfolge der Zeichenfolgen in Ihrem Array keine Rolle spielt, gibt es möglicherweise eine andere Permutation in Kombination mit einem anderen Begrenzer, die sogar noch kürzer ausfallen könnte. Es wird jedoch viel mühsamer sein, jede Möglichkeit auszuprobieren. Mit unseren 4 Saiten können Sie 24 verschiedene Permutationen ausprobieren. Mit jedem der 11 möglichen Buchstaben wird das zu 264! Hier kommt dieses Tool ins Spiel. Geben Sie erneut Ihre durch Zeilenumbrüche getrennten Zeichenfolgen ein, und es wird jede Kombination aus jeder Permutation und jedem Begrenzungsbuchstaben ausprobiert, wobei Folgendes ausgegeben wird:

  • die Reihenfolge der Zeichenfolgen in der kürzesten komprimierten Zeichenfolge,
  • die komprimierte Zeichenfolge,
  • das verwendete Trennzeichen und
  • seine Länge.

Das Durchlaufen unserer Beispielzeichenfolgen zeigt, dass "nougat","oreo","lollipop","marshmallow"mit bals Trennzeichen die besten Ergebnisse erzielt werden, mit einer letzten Bytezahl von nur 23:

`ÍÞo½o¥ipáæqrÚaow`qb


Bonus-Tipp: Integer-Array-Komprimierung

Sie können dasselbe Prinzip auf Arrays von ganzen Zahlen anwenden, indem Sie zuerst jedes in eine höhere Basis konvertieren. Unter Verwendung dieses Beispiels 36-Byte-Array:

[588181,156859,595676,475330,680474]

Wir können das auf 29 Bytes reduzieren, indem wir es zuerst in ein Array von Basis-32-Strings konvertieren und dann durch das erste Komprimierungsprogramm ausführen:

`huclt4p5r5ÛÊg62tkogq`qt mnH

Oder nur 27 Bytes mit dem zweiten Programm:

`4p5Ïcl5ÛÊg62tkogq`qt mnH

Sie können möglicherweise ein weiteres Byte oder 2 zusätzlich dazu speichern, indem Sie die Ganzzahlkonvertierung in eine Methode verschieben, die Sie bereits auf dem Array ausführen.


Anmerkungen

  1. Vergessen Sie nicht, die q<letter>(<space>)Kosten von 1 oder 2 zusätzlichen Bytes zu berücksichtigen ·. Sie können möglicherweise eine der Unicode - Verknüpfungen verwenden , um ein Byte zurückzugewinnen. Dies hängt von Ihrem Trennzeichen ab ( ist dasselbe wieql<space> , zum Beispiel).
  2. Ein Wort der Vorsicht bei der Verwendung des letzten Werkzeugs: Je mehr Zeichenfolgen Sie haben, desto mehr Permutationen sind vorhanden und desto langsamer wird das Programm ausgeführt, bis es schließlich zusammenbricht. Wie oben beschrieben, gibt es mit unseren 4 Beispielzeichenfolgen und 11 möglichen Buchstaben 264 mögliche Kombinationen. Erhöhen Sie die Anzahl der Zeichenfolgen um nur 1 mit den gleichen 11 Buchstaben, und wir haben bereits 1320 Kombinationen zum Ausprobieren. (Sie können dieses Tool verwenden, um die Anzahl der Kombinationen zu zählen, wenn Sie möchten).

Credits

  • Oliver für die Inspiration, die Werkzeuge in diesem Tipp zu erstellen.
  • ETH-Produktionen zum Korrekturlesen.
Zottelig
quelle
6

Saiten komprimieren

Japt verwendet (derzeit) die Shoco- Bibliothek zur Komprimierung von Strings. Sie können eine beliebige Zeichenfolge mit komprimieren Oc, sofern sie Kleinbuchstaben enthält:

Oc"Hello, World!"

Diese Ausgabe HÁM, WŽld!( Žnaja , das ist technisch ein nicht druckbares Zeichen). Sie können dies dekomprimieren, indem Sie es in Backticks einwickeln:

`HÁM, WŽld!`

Online testen!

Alternativ können Sie die OdFunktion verwenden, um eine beliebige Zeichenfolge zu dekomprimieren. Dies ist normalerweise nicht nützlich, hat aber seine Absichten ...

ETHproductions
quelle
Also, wenn ich das "Hallo, Welt!" Herausforderung, würde ich nur verwenden HÁM, WŽld!oder müsste es in Backticks eingeschlossen werden? Ich vermute letzteres.
Shaggy
2
@Shaggy Bei der Beantwortung einer Frage müssten Sie den gesamten Code angeben, damit dies wie folgt aussieht: `HÁM, WŽld! in diesem Fall
Martijn Vissers
6

Zahlen mit Char-Codes kürzen

In Japt können Sie #, gefolgt von einem Zeichen, einen Zeichencode erstellen. Dies ist nützlich, wenn Sie längere Nummern kürzen möchten.

Wie bei @ETHproductions erwähnt, funktioniert dies nur bei dreistelligen Durchläufen im Bereich von 100 bis 255, sofern Sie nicht bereit sind, auf UTF-8 zu wechseln.

Beispiele:

123 kann auf gekürzt werden #{

101 kann auf gekürzt werden #e

Sie können diese sogar miteinander verketten:

123101 kann auf gekürzt werden #{#e

Sie können String.fromCharCode(123)JavaScript oder 123dJapt verwenden, um den entsprechenden Charakter zu finden.

String.fromCharCode(123) kehrt zurück {

Oliver
quelle
Danke, @obarakon, toller Tipp, um den Ball ins Rollen zu bringen; String.fromCharCode()ist eine dieser (vielen!) unangenehmen langen JS-Methoden, die Ihre Byteanzahl auffüllen können. Vermutlich wären dies ganze Zahlen? dh, wenn ich die ganze Zahl 123in einer Lösung brauche , könnte ich verwenden #{, um ein Byte zu speichern.
Shaggy
1
Ja, das sind ganze Zahlen. Wenn Sie das -QFlag in Ihr Eingabefenster einfügen, können Sie den Ausgabetyp besser anzeigen: Anführungszeichen für Zeichenfolgen , Arrays usw.
Oliver
1
Sie sollten erwähnen , dass String.fromCharCode(123)Werke in JavaScript, aber Sie tun können , 123din Japt das gleiche Ergebnis zu erhalten ;-) Auch das funktioniert nur auf dreistellige Läufe im Bereich 100- 255(es sei denn , Sie sind bereit , auf UTF-8 wechseln)
ETHproductions
@ETHproductions Guter Anruf, aktualisiert!
Oliver
5

Kurztipp: Array leeren []

Japt hat eine Konstante für ein leeres Array: A. Um jedoch darauf zugreifen zu können, müssen Sie ;Ihrem Programm ein Semikolon voranstellen , um die alternativen Konstanten von Japt Azu verwenden 10. Andernfalls wird dies der Fall sein . Die Verwendung von ;Abietet also tatsächlich eine Einsparung von 0 Byte [], wird dies aber tun Sie sparen Bytes , wenn Sie Ihre Array müssen eine Variable zuweisen ( zum Beispiel A=[]).

Wenn Ihr Programm jedoch (und nur dann) keine Eingaben vornimmt, können Sie mit der NVariablen, die das Array der Eingaben darstellt, mit nur 1 Byte auf das leere Array zugreifen. Ohne Eingaben wäre es leer. Probieren Sie es hier aus .

Dies hat auch den zusätzlichen Vorteil, dass Sie die Standardkonstantenwerte in Ihrem Programm verwenden können. In einigen Fällen können Sie ;Adank der Verknüpfungen für s1und auch dann noch Byte sparen , wenn Ihr Programm Eingaben vornimmt s2.

Zottelig
quelle
2
Wow, ich hatte nicht darüber nachgedacht N, nette Idee.
ETHproductions
2
Schön, @Shaggy!
Oliver
4

JavaScript auswerten

Mit Japt können Sie rohes JavaScript ausführen, indem Sie es umschließen $...$ .

Beispielsweise, $alert("hello world")$

Dies kann durch Ausnutzen von Japts Auto-Closing $und verkürzt werden ).

$alert("hello world")$ kann auf gekürzt werden $alert("hello world"

JavaScript komprimieren

Sie können JavaScript auch mit komprimieren Ox.

Wenn es eine JavaScript-Funktion gibt, die Sie beispielsweise verwenden möchten, screen.widthkönnen Sie den String "screen.width"mitOc komprimieren und dann das Ergebnis zwischen Ox` ... `einfügen

Beachten Sie, dass Sie in Japt keine schließenden Anführungszeichen benötigen, wenn nichts anderes folgt.

Oliver
quelle
@Shaggy Sie müssen Oxden String auswerten. Andernfalls würden Sie nur den Text ausgeben "screen.width". Beispiel
Oliver
4

Kenne die Flaggen

Nach dem neuesten Metakonsens (Dezember 2017) werden Befehlszeilenflags nicht mehr zu Bytes gezählt. Es ist wirklich eine gute Nachricht für Japt, da es viele Flags für eine zusätzliche Behandlung der Eingabe / Ausgabe gibt.

Alle verfügbaren Flags in Japt werden nachfolgend in der Reihenfolge der Auswertung beschrieben . Die Flags in derselben Gruppe sind einander exklusiv. Beachten Sie, dass die Flags in verschiedenen Gruppen in Kombination verwendet werden können, was ungefähr so aussieht :)

mdefæ

Das gesamte Programm wird auf das erste Argument abgebildet ( U).

Wenn mehrere Argumente vorhanden sind, werden sie unverändert übergeben (dh nicht paarweise zugeordnet). Ansonsten ist das zweite Argument der Index und das dritte ist genau wie das gesamte Array U.m. Wenn Ues sich um eine Zahl handelt, wird sie in einen Bereich konvertiert. Wenn string, wird es in ein Array von Zeichen konvertiert und die Ergebnisse werden zusammengefügt.

  • -m: Gilt das oben und sonst nichts.
  • -d: Gibt zurück, truewenn ein Ergebnis wahr ist, falseansonsten.
  • -e: Gibt zurück, truewenn alle Ergebnisse wahr sind, falseandernfalls.
  • -f: Gibt das Array von Elementen zurück, Uderen Ergebnisse wahr sind.
  • : Wendet -fdas erste Element an und gibt es zurück.

gh

Übernimmt ein Element am angegebenen Index.

  • -g: Nimmt das erste Element (Index 0).
  • -gX: Nimmt das Element am Index X(kann eine beliebige positive Ganzzahl sein).
  • -h: Nimmt das letzte Element.

Konvertieren Sie das Ergebnis in einen Booleschen Wert.

  • -!: Booleschen Wert nicht anwenden.
  • : Wende den Booleschen Wert nicht zweimal an (gibt die Wahrheit zurück).

N

Wandle das Ergebnis in eine Zahl um. Das unäre Plus wird verwendet.

PRSQ

In irgendeinen String konvertieren.

  • -P: Verbinden Sie das Array mit "".
  • -R: Verbinden Sie das Array mit "\n".
  • -S: Verbinden Sie das Array mit " ".
  • -Q: Apply JSON.stringify(kann ein beliebiges Objekt sein, nicht nur ein Array). Beispiel .

x

Wendet die Funktion xauf den Ausgang an. (Es ist buchstäblich xnicht "eine einzelne Kleinbuchstabenfunktion".)

  • Array: Summe.
  • String: Von beiden Enden abschneiden.
  • Zahl: Rund um eine ganze Zahl.
Bubbler
quelle
2
Beachten Sie, dass die Verwendung von Flags nicht als Japt-Übermittlung, sondern als Japt-with-those-specific-flags-language-Übermittlung zählt.
Nit
3

Unicode-Verknüpfungen

Es gibt viele gemeinsamen Strukturen in Japt , die einfach nicht in einem einzigen ASCII - Zeichen gespeichert werden, wie zum Beispiel qS , p2 , mX{, , etc. Also , dies zu umgehen, Japt hat „Unicode - Verknüpfungen“, die Zeichen im Bereich sind \xA1- \xDE( ¡- Þ), die sich auf diese gemeinsamen Strukturen ausweiten. Eine vollständige Liste finden Sie in den Interpreter-Dokumenten .

Darüber hinaus @steht für XYZ{und _steht für Z{Z, für den Aufbau von Funktionen. Lassen Sie uns unser Beispielprogramm anhand einer anderen Antwort betrachten :

UmX{Xc0 s16}

Erstens können wir ersetzen X{Xdurch _, was uns gibt:

Um_c0 s16}

Dann können wir ersetzen m_mit ®Speichern ein weiteres Byte:

U®c0 s16}

Oder wir könnten ersetzen X{durch @, was uns gibt:

Um@Xc0 s16}

Dies ermöglicht es uns dann, die ¡Verknüpfung zu verwenden, um zwei Bytes zu speichern:

¡Xc0 s16}

Einer dieser beiden Pfade kann 1 Byte mehr als der andere verkürzt werden. Können Sie herausfinden, welche?

ETHproductions
quelle
1
®c s16für 6 Bytes - gewinne ich ein Cookie ?!
Shaggy
@ Shaggy Du kannst 1 Byte mehr sparen, wenn du genau hinschaust ...;)
ETHproductions
Wäre es ®c sG?
Shaggy
1
Ja! Ich denke das ist so niedrig wie du gehen kannst. Gut gemacht! :-)
ETHproductions
2
Ein erstaunlicher Rückblick auf diese Ereignisse und die Entwicklung von Japt in wenigen Monaten. Dies kann nun mit erreicht werden csG.
Shaggy
3

Nutzen Sie die voreingestellten Variablen

Variablen A- Ssind auf gemeinsame Werte voreingestellt, die mehr als ein Byte benötigen, um in Japt dargestellt zu werden:

  • A- Gsind 10- 16.
  • Hist 32, Iist 64, Jist -1, List 100.
  • Kist definiert als new Date(), was Sie auf verschiedene Arten manipulieren können.
  • Mund Osind Objekte mit verschiedenen nützlichen Funktionen. Weitere Informationen finden Sie in den Dokumenten.
  • Pist die leere Zeichenfolge, Qein Anführungszeichen, Rein Zeilenumbruch und Sein Leerzeichen.
  • Tist auf eingestellt 0, damit Sie es bei Bedarf als Akku verwenden können.

Wenn das erste Zeichen im Programm ein Semikolon ist ;, A-Lwerden Sie wie folgt zurückgesetzt:

  • Aist das leere Array [].
  • Bist "ABCDEFGHIJKLMNOPQRSTUVWXYZ".
  • Cist "abcdefghijklmnopqrstuvwxyz".
  • Dist "QWERTYUIOP\nASDFGHJKL\nZXCVBNM".
  • Eist "[a-z]", und Fist "[A-Za-z]"(nützlich, bevor ich diese als reguläre Ausdrücke hinzufügte)
  • Gist 36, Hist 65und Iist 91(nützlich für Alphabetbereiche).
  • Jist ein einzelnes Komma; L, eine einzelne Periode.

Heute nur A, B, C, und Daus dieser Liste sind wirklich nützlich. Ich plane, ein besseres System hinzuzufügen, das bis zu 256 Zwei-Byte-Variablen zulässt, die auf diese Werte voreingestellt werden, und vieles mehr.

ETHproductions
quelle
3

Verwenden Sie Auto-Funktionen

Sie wahrscheinlich bereits wissen , dass @und _sind Abkürzungen für XYZ{und Z{Zjeweils (in den abgedeckten Unicode - Shortcuts Antwort). Aber manchmal kann man Funktionen noch kürzer machen.

Angenommen, Sie hatten ein Array von Zeichen und wollten jedes Zeichen seinem Zeichencode zuordnen. Sie können dies mit einer der folgenden Methoden tun:

mX{Xc} 
m_c} 

Aber es gibt einen besseren Weg. Wenn eine Methode oder ein Operator das erste Element nach einer anderen Methode oder einem anderen Operator ist (, wird es in eine Zeichenfolge umgewandelt. Diese beiden Zeilen sind also äquivalent:

r'a'b  // Replace all "a"s with "b"s; transpiles to .r("a","b")
ra'b   // Does the same thing, 1 byte less; transpiles to the same thing

Aber wie hilft das bei unseren Funktionen? Nun, die meisten Methoden, die Funktionen akzeptieren, interpretieren eine Zeichenfolge, die eine Methode oder einen Operator darstellt, als Funktion. Was bedeutet, dass Sie dies auch tun können:

m_c}  // Map each item to its char code
m'c   // Does the same thing, 1 byte less
mc    // Also does the same thing, 2 bytes less

Ich nenne diese "Auto-Funktionen". Es gibt verschiedene Sorten:

  • m@Xc}mc
  • m@Xc1}mc1
  • m@X+1}m+1
  • m@1+X}m!+1
  • m@2pX}m!p2

Hoffentlich kommst du auf die Idee. Um die Argumente auszutauschen, müssen Sie der Methode oder dem Operator lediglich das Präfix voranstellen !.

ETHproductions
quelle
Wäre es hier erwähnenswert, dass die Verwendung von Auto-Funktionen auch durch die Verwendung von Verknüpfungen weitere Einsparungen ermöglichen kann? zB m@2pXÃm!p2<space>m!².
Shaggy
Woah! Ich habe nicht daran gedacht, eine Zeichenfolge in der Karte zu verwenden, wusste nicht einmal, dass es möglich ist. Vielleicht spare ich dadurch in Zukunft ein paar Bytes.
RedClover
Hey @Soaku, ich habe irgendwie vermisst, dass du mit Japt geantwortet hast, also erlaube mir, dich spät zu begrüßen! Hoffe, Sie haben es bisher genossen. Wenn Sie Fragen oder Anregungen haben oder einfach nur reden möchten, besuchen Sie uns im Japt-Chatroom (Github funktioniert normalerweise auch für die ersten beiden;))
ETHproductions
3

Implizite Variablenzuweisung

Wenn Sie in Japt eine neue Zeile beginnen, wird das Ergebnis der vorherigen Zeile automatisch einer der Eingangsvariablen ( U- Z) zugewiesen , wobei die erste Zeile Udie zweite Vist und so weiter.

Nehmen wir ein Beispiel: Angenommen, Sie möchten zwei Arrays erstellen, von denen eines die Zahlen 1 bis 10 und das andere die Quadrate enthält. Der lange Weg dazu würde so aussehen:

U=Aõ V=Um² [do something with the arrays]

Mit der automatischen Variablenzuweisung kann dies jedoch verkürzt werden auf:

Aõ
Um²
[do something with the arrays]

Wir haben dort 4 Bytes gespeichert. In diesem Fall können wir jedoch ein weiteres Byte speichern, da das Array von 1-10 bestimmten Szenarien zugewiesen ist Uund Uweggelassen werden kann :

Aõ
m²
[do something with the arrays]

Vorsicht

Beachten Sie bei diesem Tipp, dass Sie keine Eingabevariablen überschreiben, die Sie später in Ihrem Programm benötigen. Dies kann vermieden werden, indem am Anfang eine oder mehrere Leerzeilen stehen. Im folgenden Beispiel werden die 2 Arrays den Variablen V& Wanstelle von U& zugewiesen V:


Aõ
Vm²
[do something with the arrays]
Zottelig
quelle
3

Kennen Sie das Javascript

Da jeder Japt-Code als transpilierter JS ausgeführt wird, hilft ein gutes Verständnis der JS-Operatoren und der eingebauten Methoden beim Golfen von Japt-Code-Teilen.

Relevante JS-Tipps

[]Vm@...
...
  • Kurzschluss
  • Teilen mit Zahlen
    • Dies kann auf jede Methode verallgemeinert werden, die Zeichenfolgen aber keine Zahlen akzeptiert. Eine dort übergebene Zahl wird implizit in eine Zeichenfolge umgewandelt und speichert oft ein Byte (z . B. 0über '0).

Relevante integrierte JS-Funktionen

Sehen Sie sich genau an, welche Parameter an Funktionsargumente übergeben werden.

Bei String-Methoden ist es gut zu wissen, wie sich das Verhalten beim Übergeben eines Strings oder einer Regex mit oder ohne gFlag unterscheidet.

Bubbler
quelle
3

Verwenden Sie bei Bedarf mehrere Zeilen

Für die meisten nicht allzu harten Herausforderungen können Sie die Lösung in nur einer Zeile von Japt als Folge der Anwendung integrierter Funktionen ausdrücken. Für komplexere Anwendungen müssen jedoch Schleifenkonstrukte, Rekursionen oder die Wiederverwendung großer Codestücke verwendet werden. Hier kommt die mehrzeilige Programmierung ins Spiel.

Verschlussklammern entfernen

Aufgabe : Paaren Sie bei einem gegebenen Array von Zahlen jedes Element mit dem quadratischen Index und sortieren Sie es nach der Summe.

[5,1,17,9,3] => [[5,0],[1,1],[17,4],[9,9],[3,16]] => [[1,1],[5,0],[9,9],[3,16],[17,4]]

Einzeilige Lösung ist íUm@Yp2})ñx, })kostet aber zwei Bytes (und es gibt keine Ein-Byte-Verknüpfung). Sie können das entfernen, })indem Sie das Ende einfach ñxin die nächste Zeile verschieben. Der Code sieht also so aus:

íUm@Yp2
ñx

und das transpilierte JS wird:

U = U.í(U.m(function(X, Y, Z) { return Y.p(2) })); U.ñ("x")

Sie sehen deutlich, dass dies dasselbe bewirkt wie die einzeilige Lösung, indem Sie lediglich das Zwischenergebnis zurückgeben U.

Verwenden Sie implizite Argumente

Die Rekursionsfunktion verwendet ßall of UVWXYZals impliziten Parameter, falls nicht angegeben. Uist natürlich die Haupteingabe, aber Sie können jede verwenden VWXYZ, um andere Werte zu verfolgen, die Sie benötigen. Sie können beispielsweise Folgendes tun:

(modify input and implicit assign to U)
(modify V and implicit assign to V)
(test something and call ß without arguments; U and V are passed automatically)

Wenn Sie alternativ nur eine temporäre Variable benötigen, können Sie die Inline-Zuweisung (T=...)als Variable verwendenT (0) nur selten unverändert verwendet wird.

Eine lange Funktion wiederverwenden

Aus diesem Grund glaube ich nicht, dass ich eine gute Beispielaufgabe finden kann. Ich werde daher auf die einzige Lösung verweisen, für die dieser Tipp verwendet wurde , und nur einige allgemeine Ideen skizzieren.

  • Um eine Funktion wiederzuverwenden, müssen Sie sie in einer Variablen speichern. Starten einer Linie mit der Funktion-Öffner {, @oder _macht die Arbeit. Alternativ können Sie (T=@...})die Funktionszuweisung auch in eine komplexere Zeile einbetten.
  • Es ist eigentlich nicht trivial, die gespeicherte Funktion aufzurufen. Angenommen, es Vist eine Funktion, und wir möchten V(U)JS aufrufen . VUfunktioniert nicht, da es einfach bedeutet V,U. V(Utut es auch nicht; es ist V,(U). Auch die Funktionsmethoden sind wenig hilfreich. Der beste Weg, den wir gefunden haben, ist:
    • [U]xV (Karte und Summe), wenn das Ergebnis eine Zahl ist
    • UmVif Uist ein einzelnes Zeichen und Vgibt eine Zeichenfolge zurück, oder
    • $V($Uoder [U]mV gallgemein.
  • Das Mappen oder Schleifen ist jedoch ziemlich einfach. Um ein Array zuzuordnen, verwenden Sie UmV. VVerwenden Sie, um die erste befriedigende Ganzzahl zu finden Va.
Bubbler
quelle
2

Spaß mit Auto-Funktionen

Als Follow-up zu den allgemeinen Tipp der ETH zu Auto-Funktionen finden Sie in diesem Tipp einige spezifische Beispiele für Tricks zum Speichern von Bytes, die Sie mit diesen Tricks erzielen können. Ich werde sie ergänzen, wenn ich über mehr nachdenke.


Ruft die größte Ganzzahl in einem Array ab.

Angenommen, wir haben das Array [3,1,4,2]der Variablen zugewiesen Uund wollen die größte Zahl daraus abrufen. Wir könnten es in 4 Bytes tun, indem wir das Array sortieren und dann das letzte Element einfügen:

Un o

Der Nachteil dabei ist, dass wir das ursprüngliche Array geändert haben. Uist jetzt [1,2,3]was nicht immer wünschenswert sein mag. Glücklicherweise gibt es eine Möglichkeit, das Array zu ändern, die ebenfalls ein Byte kürzer ist:

Urw

Was wir dort gemacht haben, ist das Array mit der wMethode zu verkleinern , die, wenn sie für eine Ganzzahl verwendet wird, das Größere der Ganzzahl und des Argumentes der Methode 2w5zurückgibt (z 5. B. return ). Das obige ist also das Äquivalent von UrÈwYoder UrXY{XwY}. Beachten Sie jedoch, dass dieser Tipp nicht funktioniert, wenn alle Ganzzahlen im Array negativ sind.

Zottelig
quelle
1
Randnotiz: Ich plane, Funktionen hinzuzufügen, um die minimalen und maximalen Werte eines Arrays zu ermitteln, allerdings wahrscheinlich nur in Version 2.
ETHproductions
2

Wann nicht verwendení

íist eine nützliche Funktion, die zipzwei Arrays oder Strings paarweise zusammenfügt (oder paarweise ) und optional jedes Paar durch eine Funktion abbildet. Bei ungeraden Arrays oder Strings treten jedoch derzeit einige kleinere Probleme auf:

  • Wenn das erste Array mehr Elemente als das zweite enthält, werden die nicht vorhandenen Elemente im zweiten Array als angegeben undefined .
  • Wenn das zweite Array mehr Elemente als das erste enthält, wird die Verarbeitung am Ende des ersten Arrays beendet.

Dies kann es beispielsweise schwierig machen, zwei ungerade Zeichenfolgen zu vergleichen und das Zeichen mit dem höheren Codepunkt von jedem Paar zu nehmen. Selbst wenn Sie wissen, dass Udies die längere sein wird, dauert es immer noch zu viele Bytes, um diese einfache Aufgabe zu lösen:

UíUç hV @[XY]n o

Sie könnten stattdessen eine Eingabe als Array mit zwei Zeichenfolgen annehmen, das Array mit transponiereny und dann jede Zeile dem richtigen Ergebnis zuordnen:

Uy m_q n o

Dies hat den Vorteil, dass die kürzere Saite immer mit Leerzeichen aufgefüllt wird, was es zu einem Kinderspiel macht, die gesamte Saite zu durchlaufen.

Beispiele aus der Praxis: 1 , 2

ETHproductions
quelle
2

Generieren Sie den ASCII-Bereich

Update: Japt hat jetzt eine Konstante für den ASCII-Bereich; der alternative Wert für E, zugänglich mit ;. In diesem Tipp finden Sie weitere Informationen zu Japt-Konstanten.

Während Japt (noch) kein eingebautes Format für den ASCII-Bereich hat, können Sie ein Array von Zeichen in nur 5 Bytes erzeugen:

95odH

Versuch es


Wie es funktioniert

95oErstellt den Bereich [0,95)mit jedem Element, das die Auto-Funktion durchläuft d, die bei Verwendung für eine Zahl das Zeichen an diesem Codepunkt zurückgibt. Übergeben Sie din diesem Fall eine Zahl als Argument an die MethodeHÜbergeben Sie die Japt-Konstante für 32, und diese wird vor der Konvertierung zur ursprünglichen Zahl hinzugefügt.

Eine äquivalente Lösung in JavaScript wäre:

[...Array(95)].map((_,x)=>String.fromCharCode(x+32))

Zufällige Charaktere

Verwenden Sie östattdessen, um ein zufälliges Zeichen im ASCII-Bereich zu erhalten. Dabei wird eine Zufallszahl aus dem Bereich zurückgegeben [0,X). Dabei Xhandelt es sich um die Zahl, auf der es ausgeführt wird.

95ö dH

Um ein Array mit mehreren zufälligen Zeichen zu erhalten, übergeben Sie die Anzahl der Zeichen, die Sie als Argument für benötigen ö. Folgendes gibt 10 Zeichen zurück:

95öA mdH
Zottelig
quelle
1

Unnötige Strukturspäne entfernen

Durch strukturelle Zeichen, ich meine {}, (), $, auch "und `. Sie können diese Zeichen normalerweise immer dann entfernen, wenn sie direkt am Ende eines Programms auftreten (z UmX{Xc +"; "} -> UmX{Xc +"; . B. ).

Darüber hinaus können Sie Parens oder Leerzeichen entfernen, wenn sie an den folgenden Stellen erscheinen:

  • Gegen ein Semikolon ;(oder das Ende des Programms);
  • Rechts von {(und durch Erweiterung @) oder [oder links von ]oder }.

Kommas werden auch sehr selten benötigt, um Argumente zu trennen. Wenn du ABzum Beispiel schreibst, weiß Japt, dass du es ernst meinst Aund Bgetrennt. Sie brauchen wirklich nur ein Komma, um zwei numerische Literale zu trennen, wie zUs2,5 .

Schließlich, wenn es eine ist Uzu Beginn eines Programms oder nach einem {oder ;, gefolgt von einem Methodenaufruf (Kleinbuchstabe oder verwandte Unicode Verknüpfung) oder in einem binären Operator ohne +und -( *, &, ==, etc.), können Sie entfernen die Uein sparen Byte und Japt wird es für Sie einfügen.

ETHproductions
quelle
Ich habe einige andere Fälle gefunden, in denen Ueine Unterbrechung möglich ist, auch wenn das Programm noch nicht gestartet ist.
Shaggy
@Shaggy Oh richtig, es funktioniert auch nach einem {oder ;. Gibt es noch andere, die dir bekannt sind? (Es ist schon eine Weile her, seit ich dieses Feature codiert habe: P)
ETHproductions
Ich kann nicht von oben an sie denken; Ich werde es mir noch einmal ansehen, wenn ich morgen wieder an meinem Computer bin.
Shaggy
1

Ändern Sie das letzte Element in einem Array

In manchen Fällen müssen Sie möglicherweise das letzte Element in einem Array ändern. Hier finden Sie eine kurze Erläuterung dazu. Wir werden mit dem Array arbeiten[2,4,8,32] der Eingabevariablen zugewiesen ist, Uund die letzte Ganzzahl ( 32) durch 2 teilen .

Der naheliegende Weg, dies zu erreichen, wäre mit dieser 9-Byte-Lösung ( Demo ):

UhJUgJ /2
  • hnxSetzt das Element am Index naufx .
  • gn Gibt das Element am Index zurück n .
  • J ist die Japt-Konstante für -1 , die es uns dank Japts Unterstützung für den negativen Index ermöglicht, mit dem letzten Element in einem Array zu arbeiten. Praktisch, wenn Sie die Größe des Arrays nicht kennen.
  • Und /2 ist einfach Division durch 2.

So die oben setzt das Element mit dem Index -1in dem Array auf das Element mit dem Index -1in dem Array durch 2 geteilt oder in JavaScript: U[3]=U[3]/2. Wenn Sie es so ausschreiben, scheint es eine viel zu umständliche Methode zu sein. Zum Glück gibt es einen kürzeren Weg; Wir könnten das letzte Element aus dem Array entfernen, es ändern und es zurück in das Array verschieben. Jede dieser Operationen einzeln auszuführen würde mehr als 9 Bytes in Anspruch nehmen, aber wir können sie alle auf einmal für nur 7 Bytes ausführen, was eine Einsparung von 2 Bytes bedeutet ( Demo )

UpUo /2

Übersetzt in JS entspricht dies:

U.push(U.pop()/2)&&U
Zottelig
quelle