Hier ist Übung 5.F.2 aus 'Ein Buch der abstrakten Algebra' von Charles C. Pinter:
Lassen Sie
G
die Gruppe{e, a, b, b^2, b^3, ab, ab^2, ab^3}
who sein Generatoren erfüllena^2 = e
,b^4 = e
,ba = ab^3
. Schreibe die Tabelle vonG
. (G
wird die Diedergruppe D4 genannt.)
Hier ist ein kleines Perl 6-Programm, das eine Lösung bietet:
%Vor%So sieht die resultierende Tabelle aus:
Konzentrieren wir uns auf diese speziellen Zeilen von generate
:
Für jedes Element in generate
wird ein rekursiver Aufruf von @results
ausgeführt. Dann führen wir effektiv eine manuelle "Zip" auf die resultierenden Sequenzen. Perl 6 hat jedoch zip
und den Operator Z
.
Anstelle der obigen Zeilen würde ich gerne so etwas tun:
%Vor% Also hier ist die vollständige generate
mit Z
:
Das Problem mit der Z
Version von generate ist, dass es hängt ...
Also, meine Frage ist, gibt es eine Möglichkeit, generate
in Z
zu schreiben?
Neben dieser Kernfrage können Sie alternative Lösungen für die Übung, die Perl 6 erforschen und präsentieren, teilen.
Als ein anderes Beispiel, hier ist Übung 5.F.3 aus dem gleichen Buch:
Sei G die Gruppe
{e, a, b, b^2, b^3, ab, ab^2, ab^3}
who Generatoren erfüllena^4 = e
,a^2 = b^2
,ba = ab^3
. Schreiben Sie die Tabelle vonG
. (G heißt die Quaternion-Gruppe.)
Und das obige Programm zeigt die Tabelle an:
Nebenbei wurde dieses Programm von einer Version in C # konvertiert. So sieht generate
dort mit LINQ und einer Version von ZipMany mit freundlicher Genehmigung von
Das gesamte C # -Programm: Link .
zip
nicht funktioniert Ihr Code geht davon aus, dass [Z]
("mit dem Zip-Operator verkleinern") verwendet werden kann, um die Umsetzung zu erhalten einer Liste von Listen.
Leider funktioniert im allgemeinen Fall nicht. Es 'normalerweise' funktioniert, aber bricht an einem Rand Fall: Nämlich, wenn die Liste der Listen ist eine Liste von genau eine Liste. Beobachte:
%Vor% In den ersten beiden Beispielen (3 und 2 Unterlisten) können Sie sehen, dass die Transponierung von @a
einwandfrei zurückgegeben wurde. Das vierte Beispiel (0 Unterlisten) macht auch das Richtige.
Aber das dritte Beispiel (1 Unterliste) hat a b c
nicht wie erwartet gedruckt, dh es wurde in diesem Fall nicht die Transponierung von @a
zurückgegeben, sondern (scheinbar) die Transponierung von @a[0]
.
Leider ist dies kein Rakudo-Bug (in diesem Fall könnte es einfach behoben werden), sondern eine unvorhergesehene Interaktion zweier Perl 6-Design-Entscheidungen, nämlich:
[ ]
behandelt eine Eingabeliste mit einem einzelnen Element, indem er den Operator aufruft, auf den er angewendet wird, mit einem Argument (besagtem Element). &infix:<Z>( <a b c>, )
. Z
und die Funktion zip
folgen (wie andere eingebaute Listen, die verschachtelte Listen akzeptieren) der sogenannten "Einargument-Regel" - dh ihre Signatur verwendet a Slurpy-Parameter mit einem Argument . Dies bedeutet, dass, wenn es mit einem einzelnen Argument aufgerufen wird, es in es absteigt und seine -Elemente die tatsächlich zu verwendenden Argumente berücksichtigt. (Siehe auch Slurpy-Konventionen .) zip(<a b c>,)
als zip("a", "b", "c")
behandelt. Beide Funktionen bieten in vielen anderen Fällen einige nützliche Funktionen, aber in diesem Fall stellt ihre Interaktion leider eine Falle dar.
zip
Sie können die Anzahl der Elemente von @arrs
und Sonderfall "genau 1 Unterliste" überprüfen:
Das []
ist ein " zen slice " - es gibt die Liste unverändert zurück, aber ohne Der Elementcontainer, in den das übergeordnete Array ihn eingepackt hat. Dies ist erforderlich, da die for
-Schleife alles, was in einen Elementcontainer eingeschlossen ist, als einzelnes Element betrachtet und nur eine Iteration ausführt.
Natürlich ist diese if-else-Lösung nicht sehr elegant, was wahrscheinlich den Grund für den Versuch, zip
zu verwenden, negiert.
zip
Siehe Christophs Antwort .
Das könnte mit Z
möglich sein, aber für mein armes kleines Gehirn ist das Zappen rekursiv generierter fauler Listen zu viel.
Stattdessen habe ich einige andere Vereinfachungen gemacht:
%Vor% Hier ist eine kompakte Neuschreibung von generate
, die bidirektionale Substitution durchführt, immer noch ohne eine explizite zip:
Hier ist eine Version von generate
, die den von smls gezeigten Ansatz verwendet:
Ich habe es getestet und es funktioniert auf die Übungen 2 und 3.
Wie smls in seiner Antwort erwähnt, macht zip
nicht das, was wir erwartet haben, als das angegebene Array von Arrays enthalten nur ein einzelnes Array. Also, machen wir eine Version von zip
, die funktioniert mit einem oder mehreren Arrays:
Und jetzt generate
in zip-many
:
Das sieht ziemlich gut aus.
Danke smls !
smls schlägt in einem Kommentar unten Folgendes vor: zip-many
nicht aufrufen take
, wobei generate
beibehalten wird. Lassen Sie uns auch flat
von zip-many
nach generate
verschieben.
Das abgespeckte zip-many
:
Und die generate
dazu:
Das separate Testen der Schlüssel und Werte scheint etwas albern zu sein; Deine Strings sind keine echten Regexes, also brauchst du //
nirgendwo in deinem Code.
Offensichtlich müssen Sie mit dieser Version von generate
table
neu schreiben, um @eqs
anstelle von %eqs
zu verwenden.
Tags und Links perl6