Blueprint a sestina


19

Une sestina est un format de poème qui suit un modèle intéressant que nous pouvons générer. Il comporte six strophes de six lignes chacune, où les derniers mots de chaque ligne de la première strophe constituent les terminaisons de ligne de chaque strophe successive, tournés selon un modèle défini. (Il y a aussi une strophe de trois lignes à la fin, mais nous ne nous en inquiéterons pas.) Jetez un coup d'œil aux trois premières strophes d'Elizabeth Bishop, créatives, nommées Sestina :

La pluie de septembre tombe sur la maison.
Dans la lumière défaillante, la vieille grand-mère est
assise dans la cuisine avec l'enfant à
côté du Little Marvel Stove,
lisant les blagues de l'almanach,
riant et parlant pour cacher ses larmes.

Elle pense que ses larmes équinoxiales
et la pluie qui bat sur le toit de la maison
ont été annoncées par l'almanach,
mais seulement connues d'une grand-mère.
La bouilloire en fer chante sur la cuisinière.
Elle coupe du pain et dit à l'enfant:

Il est temps pour le thé maintenant; mais l'enfant
regarde les petites larmes dures de la bouilloire
danser comme un fou sur le poêle noir et chaud,
comme la pluie doit danser sur la maison.
Rangement, la vieille grand-mère
raccroche l'almanach intelligent

...

Notez comment chaque ligne se termine par l'un des six mots «maison», «grand-mère», «enfant», «poêle», «almanach» ou «larmes». Non seulement cela, mais les mots sont ordonnés dans le motif 6–1—5–2—4–3, par rapport à la strophe précédente. Cela finit par ressembler à une spirale:

entrez la description de l'image ici

Il nous reste encore quelques années avant de générer par programme une sestina complète, mais nous pouvons créer un modèle contenant les derniers mots de chaque strophe dans le bon ordre. Écrivez un programme ou une fonction qui, compte tenu des six mots de fin de ligne, génère le plan pour une sestina, en suivant ces règles. Voici le résultat attendu pour l'entrée 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

La première strophe est constituée des mots dans l'ordre d'origine, la deuxième strophe est dans l'ordre 6-1-5-2-4-3 du premier. La troisième strophe est cet ordre par rapport à la seconde, et ainsi de suite, jusqu'à la strophe 6.

Supposons que les mots saisis seront toujours uniquement des lettres, majuscules ou minuscules. Vous pouvez les prendre comme un tableau de chaînes ou une chaîne unique délimitée par un caractère non-lettre (espace, nouvelle ligne, etc.). Dans la sortie, les lignes sont séparées par des sauts de ligne ( 0x0A) et les strophes sont séparées par deux sauts de ligne. Une nouvelle ligne de fin est acceptable.

C'est le , donc le code le plus court en octets gagne. Cela étant dit, il peut être plus court de compresser toute la structure du poème, mais j'aimerais voir des solutions qui basent chaque strophe sur la précédente.


Les nouvelles lignes de fin sont-elles acceptées?
Luis Mendo

De plus, la ligne de séparation peut-elle contenir un espace?
Luis Mendo

@LuisMendo Bien sûr, les deux vont bien.
NinjaBearMonkey

La sortie peut-elle être une liste ordonnée de listes ordonnées de chaînes?
Greg Martin

6
+1 pour les sestinas, mais je ne suis pas sûr que cela mérite le natural-languagetag. L'algorithme est le même même si l'entrée est de six chaînes de charabia.
DLosc

Réponses:


1

Gelée , 15 14 octets

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

TryItOnline!

Comment?

Oui, une utilisation de l'un de mes ajouts à 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)

7

Python, 72 64 octets

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

Prend l'entrée via STDIN en tant que tableau séparé par des virgules de 6 chaînes et les sorties vers STDOUT dans le format décrit dans la publication avec un retour à la ligne supplémentaire.

Essayez-le en ligne! (Ideone)

De plus, je ne suis pas sûr que ce soit correct, mais voici une réponse plus courte sous la forme d'une fonction lambda anonyme à 59 octets qui accepte les entrées dans le même format que la réponse ci-dessus et génère le programme nécessaire pour générer la sortie correcte:

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

Par conséquent, il doit être appelé dans le format exec(<Function Name>(<Array>)). Encore une fois, je ne suis pas sûr que ce soit correct, alors j'ajoute cela comme une réponse supplémentaire, distincte et non concurrente jusqu'à ce que quelqu'un (peut-être même OP) puisse, je l'espère, clarifier si cela va ou non, ce que j'apprécierais vraiment .


2
J'aime le poptruc!
xnor

3

MATL , 18 17 octets

0ch5:"t[6l5H4I7])

L'entrée est un tableau de cellules de chaînes, au format

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

Essayez-le en ligne!

Explication

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

3

Mathematica, 59 octets

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

Le noyau de cette fonction sans nom est NestList[RotateRight,#,5], qui prend une liste d'entrée de longueur 6 et crée une liste de 6 listes, chacune tournée dans le sens sestina. En effet, si une liste de listes de chaînes est une sortie acceptable, alors NestList[RotateRight,#,5]&le travail se fait en 26 octets .

Ensuite, r[...,""]insère une chaîne vide entre chacune des 6 listes; Flattentransforme le tout en une seule liste de chaînes; ~r~"\n"insère ensuite une nouvelle ligne entre chacune de ces chaînes; et ""<>concatène le tout en une seule chaîne. Ainsi, les 33 autres octets ne servent qu'à convertir la sortie structurée en une seule chaîne.


2

Lot, 99 octets

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

Explication: prend l'entrée en tant que paramètres de ligne de commande. Le %0fait tourner en boucle, accumulant .s dans le 7e paramètre initialement vide. L'extra .est parce ifque ne fonctionne pas sur les chaînes vides.


2

Rubis, 51 octets

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

Au lieu d'itérer sur les nombres 0..5comme ci-dessous, nous répétons 6 fois en itérant sur les éléments de z. Dans une utilisation normale telle que (0..5).map{|i|puts i}le code {}lit les éléments itérés. Dans ce cas, les permutations effectuées par le code à l'intérieur du {}ne lisent pas les éléments itérés, nous pouvons donc parcourir les éléments de zsans que cela interfère avec les permutations.

Rubis, 56 octets

Prend un tableau de 6 éléments comme paramètre

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

version alternative prenant 6 paramètres

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

A chaque itération de mapnous permutons z. La version originale plus un ""pour représenter une rupture entre les strophes devient la sortie du map(ce septième élément de tableau n'est pas nécessaire par l'affectation, il est donc ignoré). *$/convertit les tableaux en chaîne, joignant le tout avec des retours à la ligne.


2

Raquette 115 octets

(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)))

Non golfé:

(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))))

Essai:

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

Production:

'(("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"))
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.