Pyth ist eine von Python inspirierte prozedurale Programmiersprache, die vom PPCG-Benutzer isaacg erstellt wurde .
Welche allgemeinen Tipps haben Sie zum Golfen in Pyth? Ich bin auf der Suche nach Ideen, die sich auf Code-Golf-Probleme im Allgemeinen anwenden lassen, die zumindest etwas spezifisch für Pyth sind.
Ein Tipp pro Antwort, bitte.
Kenne deine Variablen
In Pyth gibt es drei Kategorien von Variablen: generische vorinitialisierte Variablen, auf der Grundlage von Benutzereingaben vorinitialisierte Variablen und Variablen, die bei der ersten Verwendung implizit eine Zuweisung generieren.
Generische Variablen:
Eingabeinitialisierte Variablen:
Beachten Sie, dass diese Initialisierungen nur in einem bestimmten Programm ausgeführt werden, wenn die zugehörige Variable außerhalb einer Zeichenfolge im Code verwendet wird. Außerdem ist die Reihenfolge
Q
dannz
, wenn beide verwendet werden.Zuordnung bei Erstverwendungsvariablen:
J
undK
. Wenn Sie beide auf denselben Wert initialisieren möchten, können Sie einen Ausdruck wie verwendenKJ0
, der dem längeren Wert entsprichtJ0K0
.quelle
Verwenden Sie den noch neueren Online-Dolmetscher , um Ihre Antworten zu testen.
Beachten Sie, dass dies eine neue Software ist und daher möglicherweise fehlerhaft ist. Bitte melden Sie mir Probleme.
quelle
Zeichenfolgen am Zeilenende benötigen keine Anführungszeichen. Zum Beispiel:
ist ein vollständig gültiges Hello World-Programm.
quelle
Verwenden Sie diese Option
C
für die BasiskomprimierungDies ist tatsächlich undokumentiert. C auf einer Zeichenfolge ist tatsächlich nicht direkt chr -> int, sondern Basis 256 -> Basis 10 (was auf einer Zeichenfolge dasselbe ist). Dies ist sehr hilfreich beim Komprimieren eines Int. Wir können dieses Skript verwenden, um Folgendes zu komprimieren:
Nehmen Sie
12345678910
, es ergibt sichßÜ>
(einige Unprintables drin).Mit einem Array von Ints können Sie sie auch verketten und mit großen Zeichenfolgen, indem Sie sie in Codepunkte konvertieren und als Basis-128-Zahl behandeln.
Eine andere Verwendung von
C
, danke @xnor, dass Sie mir dies gezeigt haben, ist das Erstellen einer willkürlich großen Zahl. Der naive Weg ist:Aber wir können ein Byte besser machen mit:
Diese Basis 256 dekonvertiert das gesamte Alphabet. Ergebnisse
156490583352162063278528710879425690470022892627113539022649722
= ~1.56e62
.quelle
Es gibt jetzt ein Online-Tutorial für Pyth.
Die vollständige Dokumentation wird später hinzugefügt.
quelle
Verwenden Sie die Kurzfunktion ... err ...
Wenn die Lambda - Argument
map
oderreduce
gilt nur einem Arbeitsgang auf die Argumente ,, können Sie die Kurzformen verwenden,M
undF
.fMx
ist gleichbedeutend mitmfdx
undfFx
ist dasselbe wie.UfbZx
. Nehmen wir zum Beispiel an, wir nehmen eine Liste von Zahlen als Eingabe und geben jede inkrementierte Zahl aus. Ein erster Ansatz könnte sein:Dies kann jedoch wie folgt umgeschrieben werden:
Ähnliches gilt für
reduce
mitF
. Angenommen, es ist eine Herausforderung, das Produkt einer Liste von ganzen Zahlen zu berechnen. Wieder kann ein erster Versuch sein:Mit
F
kann dies jedoch verkürzt werden auf:Rasiert drei Bytes weg ... nicht schlecht!
quelle
Q
, wie es ergänzt wird, wenn die Funktion eine Eingabe fehlt, machen es*F
Halten Sie Ihre Pyth-Implementierung auf dem neuesten Stand.
Ich verbessere Pyth ziemlich regelmäßig, entferne weniger nützliche Funktionen und füge mehr nützliche Funktionen hinzu. Achten Sie also auf neue Funktionen und aktualisieren Sie Ihre Kopie der Implementierung regelmäßig.
Einige kürzlich hinzugefügte Funktionen: (Stand 19.10.14)
y
: Funktioniert wie*2
bei Zahlen und als Liste aller Teilmengen von Zeichenfolgen und Listen. Zum Beispiel:f
:f
ist normalerweise der Filterbefehl. Wenn es nun mit einer Zahl als zweitem Argument aufgerufen wird, filtert es über die unendliche Folge, beginnend mit dieser Zahl, und zählt sie um eins hoch, und gibt dann das erste Element der resultierenden Folge zurück.Hier ist zum Beispiel der Code, um die kleinste Primzahl über eine Milliarde zu finden:
quelle
yz
?mvdczd
kann nicht der kürzeste Weg sein ...y
weil ich nicht glaube, dass Pyth mehrere superleicht zu analysierende Eingabeformate haben muss, nur eines, zB das Python-Format. Also ja, ich denkemvdczd
muss leider machen.r
's String Processing Suite hinzugefügt .r
sieht ziemlich nützlich aus.@
in Fdr1 + 1 @ Q2Iq% Qd0d verwenden kann, um einen Faktorrechner zu erstellen. Wenn ich versuche, es zu benutzen, wirdindex
stattdessen die Bedeutung verwendet. Gibt es einen Weg, um dieses Verhalten zu umgehen?Benannte Argumente in Funktionen (nicht mehr unterstützt)
Manchmal können Standardwerte in Funktionen zum Golfen nützlich sein. Pyth unterstützt dies tatsächlich (sehr zu meiner Überraschung). Zum Beispiel:
Druckt:
Sie können dabei auch J und K verwenden, um Zeichen zu speichern:
druckt:
Dies ist normalerweise nützlich für rekursive Algorithmen.
Das funktioniert nicht mehr, aber ich habe es hier gelassen, falls jemand mit einer alten Version von Pyth Golf spielen möchte.
quelle
Auspacken von 2 Elementtupeln mit
F
Angenommen, Sie haben ein 2-Element-Tupel
J = (a, b)
und möchtenr(a,b)
für eine 2-Aritätsfunktion r.Der naive Weg, dies zu tun, ist
rhJeJ
.Die ausgefallene Möglichkeit, dies zu tun, besteht darin
r.*J
, den Entpack-Operator zu verwenden.Der wirklich ausgefallene Weg, dies zu tun, ist die
rFJ
Verwendung des Fold-Operators.quelle
.u
?.u
scheint jetzt kumulativ zu reduzieren.Verwenden Sie die kurzen Rechenfunktionen
h
: Gibt nicht das erste Element einer Liste zurück, sondern erhöht eine Zahl, z . B.hT
ergibt11
. Kürzer als+1T
.t
: Dies dekrementiert eine Zahl (außer das Ende einer Liste zurückzugeben), z . B.tT
ergibt9
. Kürzer als-T1
.y
: Dies verdoppelt eine Zahl, zByT
ergibt20
, kürzer als*T2
oder+TT
.quelle
Verwenden Sie
map
diese Option , um Listen zu erstellenEs ist im Grunde ein Äquivalent zu den ausgefallenen Listenverständnissen von Python. Verwenden Sie eine vorhandene Liste oder einen Bereich, um die einzelnen Werte zu durchlaufen und zuzuordnen, auch wenn der Wert keine Rolle spielt.
Zwei Beispiele:
Erstellen Sie eine Liste mit 8 Nullen.
mZ8
Anstatt von*8]Z
Erstellen Sie eine Liste mit 5 Zufallszahlen zwischen 0 und 9:
mOT5
Anstatt vonV5~Y]OT)
Die zweite ordnet die Liste automatisch zu
Y
(nun ja, sie hängt an Y an), ist aber noch=YmOTU5
kürzer.quelle
Implizites Q bei EOF
Dies ist ab heute eine neue Änderung.
Q
ist die Variable, die für den ausgewerteten Eingang automatisch initialisiert wird. Es wird implizit an das Ende des Pyth-Programms angehängt, so oft es erforderlich ist, damit die Arität funktioniert. Angenommen, wir möchten die Collatz-Funktion der Eingabe berechnen, um ein Beispiel für die Verwendung dieser Funktion zum Golfen zu sehen .Ein kürzester Weg, es zu schreiben, ist wie folgt:
Da die
Q
s jedoch am Ende der Datei implizit sind, können wir einfach schreiben:2 Bytes speichern.
Beachten Sie, dass in Funktionen mit nicht erforderlichen Argumenten diese Argumente nicht angegeben werden. Beispielsweise
c"12 12"
wird kein implizites Argument angegebenQ
, dac
nur 1 Argument erforderlich ist.quelle
Verwenden Sie "Reduzieren", um eine Funktion wiederholt anzuwenden.
Angenommen, Sie müssen eine Variable auf eine Funktion von sich selbst festlegen und eine bestimmte Anzahl von Malen wiederholen. Nehmen Sie zum Beispiel das Problem, die Nummer 100 später in der Collatz-Sequenz aus der Eingabe zu finden. Der kürzeste Weg, um die nächste Nummer in der Sequenz zu finden
Q
, ist , wenn die Anfangsnummer istDie naheliegendste Möglichkeit, diese 100-mal anzuwenden und das Ergebnis auszudrucken, wäre
Schleife 100 Mal, wobei der Wert von Q jedes Mal aktualisiert wird. Beenden Sie dann die Schleife und geben Sie Q aus.
Stattdessen können wir eine Reduktionsfunktion verwenden, die die Sequenzvariable (
H
) ignoriert .Dies ist 2 Zeichen kürzer. Es ist 3 Zeichen kürzer, wenn Sie versuchen, so oft eine Schleife auszuführen, wie Elemente in einer Sequenz vorhanden sind.
quelle
Es gibt normalerweise kürzere Alternativen zu Any
Wenn Sie herausfinden möchten, ob eine Sequenz eine Bedingung erfüllt, verwenden Sie normalerweise
.Em
. Wenn Sie beispielsweise herausfinden möchten, ob eine Liste größer oder gleich 5 ist, gehen Sie wie folgt vor:Aber wenn es nur eine Wahrheit / Falschheit sein muss, nicht wahr / falsch,
sm
würde das funktionieren, da sum auf Bools funktioniert.Wir können sogar eine kürzere machen, mit
f
ilter:Der letzte sieht allerdings wirklich hässlich aus.
Für
.A
ll kann ich mir nur vorstellen, die gegenteilige Bedingung zu verwenden und sie für einen Char Save Over zu negieren.Am
:quelle
Sehen Sie sich alle Kontrollflussoptionen an
Schleifen:
F
: For-Schleife. Genau wie bei Python.V
: Für eine Schleife über einen Bereich. Weder Variable noch Bereich müssen angegeben werden, daher 2 Zeichen kürzer.W
: While-Schleife. Genau wie bei Python.#
: Endlose while-Schleife. Escape mit Fehler oder expliziter Unterbrechung.Nurtry ... except
verfügen jetzt in Pyth.Funktionen:
D
: Allgemein definieren. Genau wie Python.L
: 1 Argument, keine Zuweisungsfunktion, wie Pythons Lambda, aber benannt. Funktionsname, Variablenname und return (R
) müssen nicht angegeben werden, daher 3 Zeichen kürzer.Funktionsprogrammierung:
f
: Filter - Wählen Sie Elemente der Eingabesequenz aus, die bei Eingabe von Lambda die Wahrheit zurückgeben.f
: Erste Ganzzahl größer oder gleich der Eingabe, die ein wahrheitsgemäßes Filterergebnis liefert.m
: Map - transformiere Elemente der Eingabesequenz unter Verwendung von Eingabe-Lambda.u
: Eingangssequenz auf Eingangs-Lambda verkleinern, Akkumulator auf drittes Argument initialisieren.o
: Reihenfolge - ältere Elemente der Eingabesequenz mit Eingabe-Lambda als Schlüssel.Normalerweise gibt es mehrere Möglichkeiten für ein bestimmtes Problem, und nur durch das Schreiben von Testlösungen mit jedem von ihnen können Sie herausfinden, welche am kürzesten ist.
quelle
.x
kann in jüngerer Zeit für try-except-Blöcke verwendet werden..x{some_statments}{except_block - can this be empty}
.# ... B
kann auf diese Weise verwendet werden, wenn Sie nicht in einem Ausdruck sindZwei Elemente in einer Liste wechseln
Das Umschalten von zwei Elementen kann eine ziemlich teure Aufgabe sein. Hier sind zwei Ansätze, die Sie verwenden möchten.
Tmp-variabler Ansatz
In Vorbereitung definieren wir eine Liste
Y
und füllen sie mit Zahlen. Das Ziel ist es, das zweite und dritte Element zu wechseln.Wir weisen einfach die Variable tmp zu
J = Q[G]
, führen die erste ListenzuweisungY[G] = Y[H]
und dann die vorletzte Zuweisung durchY[H] = J
. Der Trick dabei ist, die beiden Listenzuweisungen zu verschachteln, damit Sie das Drucken nicht unterdrücken und nicht zweimal auf referieren müssenY
.Anstatt von
Übersetzungsansatz
Wenn die Elemente, die Sie wechseln möchten, in der Liste eindeutig sind, verwenden Sie diesen Ansatz. Es ist sehr kurz. Also wechseln wir dieses Mal das erste und dritte Element (die Werte
1
und5
sind eindeutig).Dies nutzt die Übersetzungsfunktionalität der Liste:
Diese Übersetzung ersetzt jedes Element
Y[0]
mitY[1]
und jedesY[1]
mitY[0]
. Wenn die Werte also nicht eindeutig sind, passieren schlimme Dinge. Zum BeispielK,1 2
ergibt[1, 5, 3, 5, 6, 7]
.Beachten Sie, dass die schließenden Klammern optional sind, wenn die Anweisung die letzte in Ihrem Code ist.
quelle
Debuggen mit
<newline>
Wenn Ihr Code in einem zwingenden Programmierstil geschrieben ist, ist das Debuggen ziemlich einfach, da Sie problemlos Zwischenergebnisse drucken können. ( Permalink )
Eine große Anzahl von Pyth-Programmen verwendet jedoch Elemente der funktionalen Programmierung wie Map, Filter und Reduction, die ein so einfaches Drucken nicht ermöglichen. Aber es ist immer noch möglich, mit dem
\n
Befehl.Der gleiche Code mit
u
(Verkleinern) wäre: ( Permalink )Wenn Sie die Zwischenwerte drucken möchten, fügen Sie einfach Folgendes ein
\n
: ( Permalink )\na
druckta
auf eine neue Zeile und kehrt zurücka
. Sie können es also überall einfügen, ohne die Funktionalität des Programms ändern zu müssen.quelle
Ermitteln des Maximums von zwei ganzen Zahlen
Angenommen, Sie haben
J=5
undK=12
. Danng#JK
= 12 und auchg#KJ
= 12.Dies wurde von @ Pietu1998 entdeckt, der es so formulierte:
Ich bin mir nicht sicher, ob jemand es bereits gefunden hat, aber es gibt eine coole Möglichkeit, max (A, B) in 2 Bytes zu machen, ohne 3 für zu verwenden
eS,AB
.g#AB
macht das gleiche. (Es ist jedoch sehr ineffizient, da es maximal (1, A-B + 1) Mal eine Schleife durchläuft. Eine Optimierung besteht darin, die Zahl wahrscheinlich größer als B zu setzen.)quelle
Pyths
join
MethodeDie
join
Methode in Python kann oft etwas nervig sein, da sie nur Strings zusammenfügt. Pyth'sjoin
ist großzügiger. Standardmäßig werden alle Objekte in Zeichenfolgen transformiert.ZB
jkUT
gibt0123456789
oderjb["abc"4,5\f]7
gibtquelle
j2\a\b
->"a2b"
Feststellen, ob eine Zahl eine ganze Zahl ist
Ein
I
guter Trick besteht darin, mit nvariant festzustellen, ob eine Zahl eine ganze Zahl ist:Hiermit wird überprüft, ob sich die Zahl nicht ändert, wenn Sie sie abschneiden. Wenn es sich um eine ganze Zahl handelt, wird dies nicht der Fall sein.
Zum Beispiel können Sie dies als perfekte quadratische Prüfung verwenden:
quelle
Verwenden Sie Packed Pyth
Packed Pyth ist eine neue "Programmiersprache", die genau wie Pyth ist, außer dass sie 7 Bits pro Zeichen anstelle von 8 Bits pro Zeichen verwendet.
Klonen Sie dazu das Pyth-Repository . Die Datei
packed-pyth.py
ist der Interpreter.Sagen Sie, Ihr Code ist
"Hello, world!
.Legen Sie es zuerst in eine Datei:
echo -n '"Hello, world!' > code.pyth
Als nächstes packen Sie den Pyth-Code in die Packed Pyth-Datei:
python3 packed-pyth.py -p code.pyth code.ppyth
Führen Sie zum Schluss den Packed Pyth-Code aus:
python3 packed-pyth.py code.ppyth
Wenn Sie Code ausführen, können Sie das
-d
Flag angeben, um zu sehen, welcher Pyth-Code tatsächlich ausgeführt wird, und Sie können nach der Datei, die den Code enthält, eine Eingabe als zweites Befehlszeilenargument angeben.Oberseite:
Nachteil:
Nur ASCII.
Keine interaktive Eingabe.
Vollständige Debug-Optionen sind nicht verfügbar.
Schlimmer noch die Fehlermeldung.
quelle
Teilbarkeitstests mit
I
und GCDHaftungsausschluss: Dies funktioniert nur für nicht negative ganze Zahlen.
Um zu überprüfen, ob zwei nicht negative ganze Zahlen teilbar sind, können Sie Folgendes tun:
Ist a durch b teilbar und a ≥ b ≥ 0 , so gilt gcd (a, b) = b .
Es spart nicht notwendigerweise Bytes
!%<dividend><divisor>
, aber es könnte Ihnen eine Ersparnis bringen, weil:Q
) optimieren , wenn Sie mit der Dividende arbeiten.<pfn>
, da es eine Funktion für sich ist.0
.Versuch es!
quelle
iI
Ist eine Funktion für sich, während dies!%
nicht der Fall ist, sodass Sie sie als Präfixfunktion verwenden können.Zuweisen einer Variablen zu einer auf sich selbst angewendeten Funktion
Wenn Sie eine Funktion der Arität 1 haben und diese auf eine Variable und auf sich selbst anwenden möchten, können Sie die folgende Syntax verwenden:
Anstatt von:
Wenn Sie beispielsweise die Variable erhöhen möchten
Z
, können Sie Folgendes tun:Das spart ein Byte mehr
=ZhZ
.quelle