Husk ist eine völlig neue Golfsprache, die von den PPCG-Nutzern Leo und Zgarb entwickelt wurde . Es hat begonnen, immer wettbewerbsfähiger zu werden, oft in der Nähe zu bleiben oder sogar Sprachen zu schlagen, die bekanntermaßen sehr knapp sind, wie Jelly und 05AB1E.
Lassen Sie uns einige Golftechniken auflisten, die etwas spezifisch für Husk sind. Bitte poste wie immer einen Tipp pro Antwort.
Antworten:
Verwenden Sie den Rückgabewert von Prädikaten
In Husk liefern Funktionen, die ihre Eingaben auf eine Eigenschaft prüfen, in der Regel ein aussagekräftiges Ergebnis, da jede positive ganze Zahl wahr ist.
Beispiele:
¹ Geeigneter Unterschied bedeutet Unterschied der Codepunkte für Zeichen. Es bezieht sich auch auf die Argumentreihenfolge. dh für
<x y
, wärex-y
quelle
Verwenden Sie überlaufende Linienbeschriftungen
Wie Sie vielleicht bereits wissen,
[₀-₉]+|[₀-₉]
ist es regulär, dass die Syntax eine andere Zeile aufruft als die, in der Sie sich gerade befinden.Dieser Tipp ist besonders nützlich, wenn Sie möchten, dass eine in einer bestimmten Zeile definierte Funktion als Argument für mehr als eine der Funktionen in der folgenden Tabelle oder als Argument für eine oder mehrere der folgenden Funktionen und für sich selbst aufgerufen wird.
Funktionstabelle:
Zeilen in Ihrem Code sind von oben nach unten mit ihren jeweiligen 0-basierten Indizes gekennzeichnet. Wenn M <N ist , wobei M die Bezeichnung und N die Anzahl der Zeilen in Ihrem Code ist, stellt die Bezeichnung nur die in Zeile M definierte Funktion dar . Wenn N ≤ M <N * 6 ist , repräsentiert es die Funktion aus der obigen Tabelle bei Index ⌊M ÷ N÷, wobei die Funktion in Zeile M mod N als erstes Argument definiert ist. Wenn N * 6 ≤ M ist , wird ein Indexfehler ausgelöst.
quelle
Lambdas können kürzer sein als neue Funktionen
Wie Sie wahrscheinlich wissen, wenn Sie ein mehrzeiliges Programm haben, können Sie sich auf die Zeilen mit den Indizes beziehen
₀…₉
, zum Beispiel im Fall von₁
wird sich auf die Funktion bezieheng
. Wenn Sie nun immer die Eingaben auf die Funktion anwendeng
(und sie mehrmals verwenden); etwas wie das:Sie sollten ein Lambda einführen, da Sie dadurch 1 Byte für jede weitere Verwendung sparen:
Das Gegenteil könnte auch der Fall sein
Im Fall von selbstreferenzierenden Lambdas (
φχψ
) gibt es den Sonderfall, dass Sie die Eingaben direkt auf die rekursive Funktion anwenden. In diesen Fällen ist es besser, den Index zu verwenden,₀
anstatt ein neues Lambda zu definieren und zu verwenden⁰
.quelle
Verwendungen von
Γ
Die Hauptanwendung der integrierten Funktion
Γ
, die als Mustererkennung in Listen oder Listendekonstruktion bezeichnet wird , besteht darin, eine Liste in einen Kopf und einen Schwanz aufzuteilen und auf diese eine Binärfunktion anzuwenden. Dies entspricht der Haskell-Pattern-Matching-Sprachewo
<something>
ein Ausdruck enthältx
,xs
und gegebenenfallsf
. Es gibt 4 Überladungen vonΓ
, von denen jede ein wenig anders funktioniert.list
Die erste Überladung
list
nimmt einen Werta
und eine Binärfunktion anf
. Es gibt eine neue Funktion zurück, die eine Liste aufnimmt, zurückgibt,a
wenn sie leer ist, undf
Kopf und Schwanz aufruft, wenn sie nicht leer ist. Nimmt zum BeispielΓ_1€
eine Liste, gibt-1
sie zurück, wenn sie leer ist, und den Index des ersten Vorkommens des ersten Elements im Ende, wenn nicht.listN
Die zweite Überladung
listN
ähneltlist
, außer dass siea
weggelassen wird und stattdessen der Standardwert des Rückgabetyps verwendet wird. Zum BeispielΓ€
ist äquivalent zuΓ0€
, da der numerische Standardwert ist0
.In der Praxis
listN
wird häufiger als verwendetlist
, da der Standardwert entweder irrelevant oder genau das ist, was Sie benötigen. Ein übliches Muster istΓ~αβγ
, woαβγ
drei Funktionen sind; Dies giltβ
für das erste Element undγ
den Schwanz und kombiniert die Ergebnisse mitα
. Es wurde zB in dieser Antwort verwendet . Andere Muster umfassen dasΓo:α
Anwendenα
nur auf das erste Element und dasΓ·:mα
Anwendenα
auf alle Elemente mit Ausnahme des ersten. Letzteres wurde in dieser Antwort verwendet .listF
Die dritte Überladung ist etwas aufwändiger. Wie
list
es nimmt einen Werta
und eine Funktionf
und gibt eine neue Funktion ,g
die eine Liste nimmt. Dieses Malf
wird jedoch ein zusätzliches Funktionsargument benötigt, dasg
selbst angegeben ist und für jeden Wert aufgerufen werden kann (einschließlich, aber nicht beschränkt auf den Endpunkt der Eingabeliste). Dies bedeutet, dasslistF
ein allgemeines Rekursionsschema für Listen implementiert wird .listF
wird nicht sehr oft verwendet, da die explizite Rekursion mitlist
/listN
normalerweise genauso lang oder kürzer ist wie in dieser Antwort .listNF
listNF
is tolistF
whatlistN
is tolist
: Die Eingabea
wird weggelassen, und stattdessen wird der Standardwert des Rückgabetyps verwendet. In seltenen Fällen kann es kürzer als eine rechte Falte sein, zum Beispiel in dieser Antwort .Als Beispiel für die rekursiven Versionen von mischt
Γ
die FunktionΓλ·:o⁰↔
eine Liste in der Reihenfolge erster, letzter, zweiter, vorletzter, dritter, vorletzter und so weiter. Probieren Sie es online! Die Funktionf
ist das explizite Lambdaλ·:o⁰↔
, dessen Argument⁰
die gesamte Funktion ist. Wasf
bedeutet, ist, den Schwanz umzukehren↔
, dann die Hauptfunktion rekursiv mit aufzurufeno⁰
und schließlich den Kopf zurückzunageln·:
.Γ·:o₀↔
Ist natürlich ein Byte kürzer, funktioniert aber nicht, wenn die Zeile etwas anderes als diese Funktion enthält.quelle
Kombinatoren können auf Funktionen höherer Ordnung angewendet werden
Angenommen, Sie haben eine Liste von Ganzzahlen X und möchten die Gesamtzahl der Elemente von X zählen , die größer als die Länge (X) sind . Das Zählen von Elementen, die ein Prädikat erfüllen, erfolgt mit der Funktion höherer Ordnung
#
, aber hier hängt das Prädikat (das größer als die Länge (X) ist ) von X ab . Die Lösung besteht darin, den KombinatorṠ
auf#
und die Funktion anzuwenden, dieo>L
überprüft, ob eine Liste kürzer als eine Zahl ist. In der FunktionṠ#o>L
wird die Liste X übergebeno>L
, die teilweise angewendete Funktion wird übergeben#
und X wird#
als zweites Argument übergeben.Wenn
α
es sich um eine Funktion höherer Ordnung,β
eine Binärfunktion undγ
eine UnärfunktionṠαβ
handelt, entspricht dies im Allgemeinen dem Haskell-Pseudocode§αβγ
ist äquivalent zuund
~αβγ
ist äquivalent zusolange die Typen übereinstimmen.
§►δṁ≠P
Findet als weiteres konkretes Beispiel eine Permutation einer Liste X , die die Summe der absoluten Differenzen zu entsprechenden Werten von X maximiert (δṁ≠
komprimiert zwei Listen unter Verwendung der absoluten Differenz und nimmt die Summe).quelle
Standardwerte von Husk
Husk ist nicht so streng wie Haskell, wo Sie Probleme bekommen, wenn Sie beispielsweise versuchen, das
last
Element einer leeren Liste zu erhalten. Um dies zu erreichen, werden vordefinierte Werte verwendet. Hier ist eine Liste der Standardwerte, Maxima und Minima:* Hier sollte ∞ eine unendliche Liste des entsprechenden Maximums darstellen (siehe unten für ein Beispiel)
Hinweis: Für Tupel (X, Y) werden die Werte für jede Komponente separat verwendet.
Wenn sie benutzt werden
Während die Maxima und Minima nur für
▲▼
leere Listen verwendet werden (zum Beispielhusk -u "▼" "[]:LLN"
wird eine unendliche Liste von zurückgegebenInf
), werden die Standardwerte an einigen Stellen verwendet:F
undḞ
)Θ
)r
) fehlschlägt←→
) erhalten oder in eins (!
) indizierenΓ
) für leere Listen►
oder◄
auf leeren Listenquelle