Blaupause einer Sestina

19

Eine Sestina ist ein Gedichtformat, das einem interessanten Muster folgt, das wir erzeugen können. Es verfügt über sechs Zeilengruppen mit jeweils sechs Zeilen, wobei die letzten Wörter jeder Zeile in der ersten Zeilengruppe die Zeilenenden in jeder aufeinander folgenden Zeilengruppe bilden, die in einem festgelegten Muster gedreht werden. (Es gibt auch eine dreizeilige Strophe am Ende, aber wir werden uns nicht darum kümmern.) Schauen Sie sich die ersten drei Strophen von Elizabeth Bishops kreativem Namen Sestina an :

September Regen fällt auf das Haus.
Im schwachen Licht
sitzt die alte Großmutter mit dem Kind
neben dem Little Marvel Stove in der Küche ,
liest die Witze aus dem Almanach,
lacht und redet, um ihre Tränen zu verbergen.

Sie glaubt, dass ihre äquinoktialen Tränen
und der Regen, der auf dem Dach des Hauses schlägt,
beide vom Almanach vorhergesagt wurden,
aber nur einer Großmutter bekannt waren.
Der eiserne Wasserkocher singt auf dem Herd.
Sie schneidet etwas Brot und sagt zu dem Kind:

Es ist jetzt Zeit für Tee; Aber das Kind
beobachtet, wie die kleinen harten Tränen des Teekessels
wie verrückt auf dem heißen schwarzen Herd tanzen, so wie
der Regen auf das Haus tanzen muss.
Die alte Großmutter räumt auf und
legt den cleveren Almanach auf

...

Beachten Sie, wie jede Zeile mit einem der sechs Wörter "Haus", "Großmutter", "Kind", "Herd", "Almanach" oder "Tränen" endet. Darüber hinaus sind die Wörter in der Reihenfolge 6–1–5–2–4–3 in Bezug auf die vorherige Strophe angeordnet. Es sieht aus wie eine Spirale:

Bildbeschreibung hier eingeben

Wir sind noch ein paar Jahre davon entfernt, programmgesteuert eine vollständige Sestina zu generieren, aber wir können eine Vorlage mit den Endwörtern jeder Strophe in der richtigen Reihenfolge erstellen. Schreiben Sie ein Programm oder eine Funktion, die anhand der sechs Zeilenenden nach diesen Regeln den Entwurf für eine Sestina ausgibt. Hier ist das erwartete Ergebnis für die Eingabe house grandmother child stove almanac tears:

house
grandmother
child
stove
almanac
tears

tears
house
almanac
grandmother
stove
child

child
tears
stove
house
grandmother
almanac

almanac
child
grandmother
tears
house
stove

stove
almanac
house
child
tears
grandmother

grandmother
stove
tears
almanac
child
house

Die erste Strophe enthält die Wörter in der ursprünglichen Reihenfolge, die zweite Strophe in der Reihenfolge 6-1-5-2-4-3 von der ersten. Die dritte Strophe ist diese Reihenfolge relativ zur zweiten und so weiter bis zur Strophe 6.

Angenommen, die eingegebenen Wörter bestehen immer nur aus Buchstaben, Groß- oder Kleinbuchstaben. Sie können sie als ein Array von Zeichenfolgen oder als eine einzelne Zeichenfolge, die durch ein Nicht-Buchstaben-Zeichen (Leerzeichen, Zeilenumbruch usw.) getrennt ist, annehmen. In der Ausgabe werden Zeilen durch Zeilenumbrüche ( 0x0A) und Zeilengruppen durch zwei Zeilenumbrüche getrennt. Ein abschließender Zeilenumbruch ist zulässig.

Das ist , also gewinnt der kürzeste Code in Bytes. Abgesehen davon mag es kürzer sein, die Struktur des gesamten Gedichts zu komprimieren, aber ich würde gerne einige Lösungen sehen, die jede Strophe auf der vorherigen aufbauen.

NinjaBearMonkey
quelle
Abschließende Zeilenumbrüche akzeptiert?
Luis Mendo
Kann die Trennlinie auch ein Leerzeichen enthalten?
Luis Mendo
@ LuisMendo Sicher, beide sind okay.
NinjaBearMonkey
Kann die Ausgabe eine geordnete Liste geordneter Listen von Zeichenfolgen sein?
Greg Martin
6
+1 für sestinas, aber ich bin nicht sicher, ob dies den natural-languageTag verdient . Der Algorithmus ist der gleiche, auch wenn die Eingabe aus sechs Kauderwelschsätzen besteht.
DLosc

Antworten:

1

Jelly , 15 bis 14 Bytes

620œ?$ÐĿY€j⁷Ḥ¤

TryItOnline!

Wie?

Yey, eine Verwendung von einer meiner Ergänzungen zu Jelly! ( œ?)

620œ?$ÐĿY€j⁷Ḥ¤ - Main link: list of words L
      ÐĿ       - loop until no longer unique, collecting intermediate results
     $         -     last two links as a monad
   œ?          -         permutation of right argument (initially L) at index
620            -         620
        Y€     - join with line feeds for €each (the words of each stanza)
          j    - join (the stanzas) with
             ¤ - nilad followed by link(s) as a nilad
           ⁷   -     a line feed
            Ḥ  -     double (two line feeds)
Jonathan Allan
quelle
7

Python, 72 64 Bytes

i,n=input(),'\n';exec"print n.join(i)+n;i=map(i.pop,[-1,0]*3);"*6

Übernimmt die Eingabe über STDIN als kommagetrenntes Array von 6 Zeichenfolgen und gibt sie in dem im Beitrag beschriebenen Format mit einer zusätzlichen nachgestellten Zeile an STDOUT aus.

Probieren Sie es online! (Ideone)

Ich bin mir auch nicht sicher, ob dies in Ordnung ist, aber hier ist eine kürzere Antwort in Form einer anonymen Lambda-Funktion mit 59 Bytes , die Eingaben im gleichen Format wie die obige Antwort aufnimmt und das zum Generieren erforderliche Programm ausgibt die richtige Ausgabe:

lambda i,n='\n':"print n.join(i)+n;i=map(i.pop,[-1,0]*3);"*6

Daher muss es im Format aufgerufen werden exec(<Function Name>(<Array>)). Auch hier bin ich mir nicht sicher, ob dies in Ordnung ist. Deshalb füge ich dies als zusätzliche, separate, nicht konkurrierende Antwort hinzu, bis jemand (vielleicht sogar OP) hoffentlich klären kann, ob dies in Ordnung ist oder nicht, was ich wirklich begrüße .

R. Kap
quelle
2
Ich mag den popTrick!
xnor
3

MATL , 18 17 Bytes

0ch5:"t[6l5H4I7])

Die Eingabe ist ein Zellenarray von Zeichenfolgen im Format

{'house' 'grandmother' 'child' 'stove' 'almanac' 'tears'}

Probieren Sie es online!

Erläuterung

0c          % Push string with a single space, to be used as separator
h           % Input array of 6 strings implicitly and append the above string
5:"         % Repeat 5 times
  t         %   Duplicate the array of strings (previous stanza plus separator)
  [6l5H4I7] %   Push array [6 1 5 2 4 3 7]. The 7th string is the separator, and stays
            %   at the end. The other strings are shuffled as required
  )         %   Index into the array of strings
            % End implicitly
            % Display implicitly
Luis Mendo
quelle
3

Mathematica, 59 Bytes

r=Riffle;""<>Flatten@r[NestList[RotateRight,#,5],""]~r~"\n"&

Der Kern dieser unbenannten Funktion ist NestList[RotateRight,#,5], dass eine Eingabeliste mit der Länge 6 erstellt wird und eine Liste mit 6 Listen erstellt wird, die jeweils in Sestina-Richtung gedreht werden. In der Tat, wenn eine Liste von Listen von Zeichenfolgen akzeptable Ausgabe ist, dann NestList[RotateRight,#,5]&erledigt die Arbeit in 26 Bytes .

Dann r[...,""]fügt eine leere Zeichenfolge zwischen jedem der 6 - Listen; Flattenverwandelt das Ganze in eine einzige Liste von Zeichenketten; ~r~"\n"fügt dann eine neue Zeile zwischen jede dieser Zeichenketten ein; und ""<>verkettet das Ganze zu einer einzigen Zeichenfolge. Die anderen 33 Bytes dienen also nur dazu, die strukturierte Ausgabe in eine einzige Zeichenfolge umzuwandeln.

Greg Martin
quelle
2

Batch, 99 Bytes

@for %%w in (%*)do @if not .%%w==.%7 echo %%w
@echo(
@if not .%7==...... %0 %6 %1 %5 %2 %4 %3 .%7

Erläuterung: Übernimmt die Eingabe als Befehlszeilenparameter. Das %0bewirkt , dass es sich um eine Schleife, Akkumulieren .s in der ursprünglich leeren 7. Parameter. Das Extra .ist, weil ifes nicht mit leeren Zeichenketten funktioniert.

Neil
quelle
2

Ruby, 51 Bytes

->z{z.map{z[1],z[3],z[5],z[4],z[2],z[0]=z+[""]}*$/}

Anstatt die Zahlen 0..5wie folgt zu durchlaufen , wiederholen wir sie sechsmal, indem wir die Elemente von durchlaufen z. Im normalen Gebrauch liest der (0..5).map{|i|puts i}Code beispielsweise {}die Elemente, über die iteriert wurde. In diesem Fall werden die {}Elemente, über die iteriert wurde, nicht von den Permutationen gelesen, sodass wir die Elemente von iterieren können, zohne dass dies die Permutationen beeinträchtigt.

Ruby, 56 Bytes

Nimmt ein 6-Element-Array als Parameter

->z{(0..5).map{z[1],z[3],z[5],z[4],z[2],z[0]=z+[""]}*$/}

Alternative Version mit 6 Parametern

->a,b,c,d,e,f{(0..5).map{b,d,f,e,c,a=a,b,c,d,e,f,""}*$/}

Mit jeder Iteration von mappermutieren wir z. Die Originalversion plus ein "", um eine Unterbrechung zwischen Zeilengruppen darzustellen, wird zur Ausgabe des map(dieses siebte Array-Element wird von der Zuweisung nicht benötigt, wird also ignoriert). *$/wandelt die Arrays in einen String um und fügt alles mit Zeilenumbrüchen zusammen.

Level River St
quelle
2

Schläger 115 Bytes

(let p((o(list l))(m 0))(if(> n m)(p(cons(map(λ(x)(list-ref(list-ref o 0)x))'(5 0 4 1 3 2))o)(+ 1 m))(reverse o)))

Ungolfed:

(define(f l n)
 (let loop ((ol (list l))
             (m 0))
    (if (> n m) 
        (loop
         (cons (map
                (λ (x) (list-ref (list-ref ol 0) x))
                '(5 0 4 1 3 2))
               ol)
         (add1 m))
        (reverse ol))))

Testen:

(f (list "house" "grandmother" "child" "stove" "almanac" "tears") 6)

Ausgabe:

'(("house" "grandmother" "child" "stove" "almanac" "tears")
  ("tears" "house" "almanac" "grandmother" "stove" "child")
  ("child" "tears" "stove" "house" "grandmother" "almanac")
  ("almanac" "child" "grandmother" "tears" "house" "stove")
  ("stove" "almanac" "house" "child" "tears" "grandmother")
  ("grandmother" "stove" "tears" "almanac" "child" "house")
  ("house" "grandmother" "child" "stove" "almanac" "tears"))
rnso
quelle