Amélioration de l'habitat pour le Minotaure

42

Amélioration de l'habitat pour le Minotaure

Le labyrinthe crétois est assez facile à dessiner. Commencez simplement par une forme symétrique (ici en rouge). Appelons toutes les extrémités des nœuds de ces lignes. Ensuite, vous commencez à dessiner les arches (noires): La première commence toujours dans le nœud supérieur central et se connecte au nœud à côté, à droite, puis les deux nœuds les plus proches de la voûte précédente sont connectés. Ceci est répété jusqu'à ce que tous les nœuds soient couverts.

gif

Nous pouvons maintenant généraliser ce concept: nous pouvons facilement générer de nouveaux modèles initiaux en ajoutant plus de Lformes. J'ai énuméré les formes initiales comme suit:

diplôme

Le motif le plus à gauche produira un labyrinthe crétois de degré 0 . La prochaine créera un labyrinthe crétois de degré 1 (l'original), etc.

Tâche

Étant donné un nombre entier non négatif n, votre programme devrait afficher la représentation ascii d’un labyrinthe de degré crétois n, illustrée dans les exemples suivants. Les espaces de fin / nouvelles lignes n'ont pas d'importance. Vous devez inclure une brève explication du fonctionnement de votre code.

Exemples

La sortie du labyrith crétois d’origine (degré 1) est la suivante:

+-----------------------------+
| +-------------------------+ |
| | +---------------------+ | |
| | | +-----------------+ | | |
| | | | +-------------+ | | | |
| | | | | +---------+ | | | | |
| | | | | | +-----+ | | | | | |
| | | | | | | +-+ | | | | | | |
| | | | | + | | | + | | | | | |
| | | | +---+ | +---+ | | | | |
| | | +-------+-------+ | | | |
| | +-------+ | +-------+ | | |
| +-------+ | | | +-------+ | |
+-----------+ | +-----------+ |
              +---------------+

Motif initial:

+ | | | +
--+ | +--
----+----
--+ | +--
+ | | | +

Le labyrinthe crétien de degré 0 devrait ressembler à ceci:

+-------------+ 
| +---------+ | 
| | +-----+ | | 
| | | +-+ | | | 
| | + | + | | | 
| +---+---+ | | 
+---+ | +---+ | 
      +-------+ 

Motif initial:

+ | +
--+--
+ | +
flawr
la source

Réponses:

10

Perl 5, 349 octets

say$p="| "x$_,"+","-"x(16*$n-4*$_+13),"+ $p"for 0..4*($n=pop)+3;say$p="| "x(3*$n+2),"+ | ","| "x2x$n,"+ $p|";$p=~s/..//,$q="-"x(4*$_-1),say"$p+$q+ ","| "x(2*$n-2*$_+1),"+$q+ $p|"for 1..$n;$p=~s/..//;say$p,("+---"."-"x4x$n)x2,"+ $p|";$p=~s/..//,$q="-"x(4*$n+3)."-"x4x$_,say"$p+$q+ | ","| "x2x($n-abs$_),"+$q+ $p|"for-$n..$n;say" "x(8*$n+6),"+----$q+"

(Passez n comme argument de ligne de commande.)

Calcule le labyrinthe ligne par ligne en six sections:

  • 4n + 4 premières lignes,
  • ligne suivante (la seule ligne non -),
  • n lignes suivantes,
  • ligne suivante (la ligne au milieu du motif initial),
  • 2n + 1 lignes suivantes,
  • ligne finale (la ligne avec les espaces de début).
Anders Kaseorg
la source
6

Python 3.5, 703 695 676 648 587 581 542 535 500 486 462 431 423 411 octets:

( Merci à @flawr pour ses conseils sur la sauvegarde de 55 octets (486 -> 431)! )

def j(r):R=range;Z=zip;B=r+r+2;P,M='+-';X='| ';q=[*Z(R(0,B-1,2),R(B-1,0,-2))];L=r+1;A=2+r;print('\n'.join([X*w+P+M*v+P+' |'*w for v,w in Z(R(4*L*4-3,0,-4),R(4*L))]+[X*g+P*o+M*k+u+M*k+P*o+' |'*-~g for g,o,k,u in Z([*R(4*L-A,0,-1),*R(4*L-A)],[0]+[1]*(3*r+2),[0,*R(1,4*L,2),*R(4*L+1,11*r,2)],[M*y+'+ '+X*b+P+M*y for y,b in q]+[M*B+P+M*B]+[M*y+'+ '+X*b+P+M*y for y,b in q[::-1]+q[1:]])]+[' '*(8*r+6)+P+M*(8*r+7)+P]))

Pas vraiment un prétendant au titre, mais je l’ai quand même tenté le coup et cela fonctionne parfaitement. Je vais essayer de le raccourcir davantage avec le temps, mais pour l'instant, je l'aime et je ne pourrais pas être plus heureux.

Essayez-le en ligne! (Idéone) (Cela peut paraître un peu différent ici à cause des limitations apparentes du compilateur en ligne. Cependant, c'est toujours très similaire.)

Explication:

Aux fins de cette explication, supposons que la fonction ci-dessus a été exécutée avec l'entrée r, étant égale à 1. Cela étant dit, fondamentalement, ce qui se passe, étape par étape, est ...

  1. q=[*Z(R(0,B-1,2),R(B-1,0,-2))]

    Un objet zip,, qest créé avec 2 objets de plage, un composé de chaque deuxième entier de la plage 0=>r+r+1et un autre composé de chaque deuxième entier de la plage r+r+1=>0. En effet, chaque motif de départ d'un labyrinthe crétois d'un degré spécifique aura toujours un nombre pair de -dans chaque ligne. Par exemple, pour un labyrinthe de degrés crétois 1, r+r+1égaux 3, son motif commence toujours par des 0tirets, suivis par une autre ligne comportant des 4tirets (2 + 2). Cet objet zip sera utilisé pour les premières r+1lignes du motif du labyrinthe.

    Remarque: La seule raison qest une liste séparée du reste, car elle qest référencée plusieurs fois et en indice, et pour économiser beaucoup de répétition et permettre l'indexation, j'ai simplement créé un objet zip qsous la forme d'une liste.

  2. print('\n'.join([X*w+P+M*v+P+' |'*w for v,w in Z(R(4*L*4-3,0,-4),R(4*L))]+[X*g+P*o+M*k+u+M*k+P*o+' |'*-~g for g,o,k,u in Z([*R(4*L-A,0,-1),*R(4*L-A)],[0]+[1]*(3*r+2),[0,*R(1,4*L,2),*R(4*L+1,11*r,2)],[M*y+'+ '+X*b+P+M*y for y,b in q]+[M*B+P+M*B]+[M*y+'+ '+X*b+P+M*y for y,b in q[::-1]+q[1:]])]+[' '*(8*r+6)+P+M*(8*r+7)+P]))

    C'est la dernière étape dans laquelle le labyrinthe est construit et assemblé. Ici, trois listes, la première comprenant les 4*r+1lignes supérieures du labyrinthe, la seconde les 3*r+3lignes centrales du labyrinthe et la dernière liste constituée de la dernière ligne du labyrinthe, sont reliées entre elles, avec des sauts de ligne ( \n) dans une longue ficelle. Enfin, cette énorme chaîne composée de tout le labyrinthe est imprimée. Approfondissons ce que ces 2 listes et cette chaîne contiennent:

    • La 1ère liste, dans laquelle un autre objet compressé est utilisé dans la compréhension de liste pour créer chaque ligne une par une, avec des majuscules |ou des +symboles, un nombre impair de tirets dans la plage 0=>4*(r+1), de fin |ou des +symboles, puis une nouvelle ligne ( \n). Dans le cas d'un 1labyrinthe de degrés , cette liste renvoie:

      +-----------------------------+
      | +-------------------------+ |
      | | +---------------------+ | |
      | | | +-----------------+ | | |
      | | | | +-------------+ | | | |
      | | | | | +---------+ | | | | |
      | | | | | | +-----+ | | | | | |
      | | | | | | | +-+ | | | | | | |
      
    • La 2ème liste, qui consiste en un objet zip contenant 4 listes, chaque liste correspondant au nombre de |symboles de début / fin , au nombre de +symboles, au nombre de tirets, et enfin à la dernière liste, qui contient les premières r+1lignes de le motif créé en fonction de l’objet zip q, la ligne au milieu du motif (celui qui n’a pas |) et les dernières r+2lignes du motif symétrique. Dans ce cas spécifique, la dernière liste utilisée dans l'objet zip de cette liste renverrait:

      + | | | +
      --+ | +--
      ----+----
      --+ | +-- 
      + | | | + 
      --+ | +--  <- Last line created especially for use in the middle of the labyrinth itself.
      

      Et donc, dans le cas d'un labyrinthe de 1 degré, toute cette liste renverrait:

      | | | | | + | | | + | | | | | |
      | | | | +---+ | +---+ | | | | |
      | | | +-------+-------+ | | | |
      | | +-------+ | +-------+ | | |
      | +-------+ | | | +-------+ | |
      +-----------+ | +-----------+ | <- Here is where the extra line of the pattern is used.
      
    • Cette liste finale, dans laquelle la dernière ligne est créée. Ici, le premier segment (celui qui précède le premier espace) Pest créé avec la longueur de la dernière ligne de la liste . Ensuite, la longueur du dernier segment (le segment de fin) de la même ligne + 4 tirets sont ajoutés, lesquels sont tous précédés et suivis d'un +symbole unique . Dans le cas d'un labyrinthe de degré 1, cette dernière liste renvoie:

                    +---------------+
      

    Après avoir réuni tout cela, cette étape renvoie enfin le labyrinthe terminé. Dans le cas d'un labyrinthe de 1 degré, cela renverrait finalement ceci:

    +-----------------------------+
    | +-------------------------+ |
    | | +---------------------+ | |
    | | | +-----------------+ | | |
    | | | | +-------------+ | | | |
    | | | | | +---------+ | | | | |
    | | | | | | +-----+ | | | | | |
    | | | | | | | +-+ | | | | | | |
    | | | | | + | | | + | | | | | |
    | | | | +---+ | +---+ | | | | |
    | | | +-------+-------+ | | | |
    | | +-------+ | +-------+ | | |
    | +-------+ | | | +-------+ | |
    +-----------+ | +-----------+ |
                  +---------------+
    
R. Kap
la source
1
Pouvez-vous peut-être d'abord définir R=rangeou quelque chose comme ça? La même chose pour P='+'?
mardi
1
Je pense que vous devriez saisir cette occasion en or de direfor g,o,k,u in Z
Sherlock9
@ Sherlock9 Haha! Bonne idée! Ajoutée. :)
R. Kap