Mejoras para el hogar para el Minotauro

42

Mejoras para el hogar para el Minotauro

El laberinto cretense es bastante fácil de dibujar. Simplemente comience con una forma simétrica (aquí en rojo). Llamemos a todos los puntos finales de esas líneas 'nodos'. Luego comienza a dibujar los arcos (negro): el primero siempre comienza en el nodo central superior y se conecta al nodo al lado del lado derecho, luego los dos nodos más cercanos al arco anterior están conectados. Esto se repite hasta que todos los nodos estén cubiertos.

gif

Ahora podemos generalizar este concepto: podemos generar fácilmente nuevos patrones iniciales agregando más Lformas. Enumeré las formas iniciales de la siguiente manera:

la licenciatura

El patrón más a la izquierda producirá un laberinto cretense de grado 0 . El siguiente creará un laberinto cretense de grado 1 (el original), etc.

Tarea

Dado un número entero no negativo n, su programa debería generar la representación ascii de un laberinto de grados cretense n, que se muestra en los siguientes ejemplos. Los espacios finales / líneas nuevas no importan. Debe incluir una breve explicación de cómo funciona su código.

Ejemplos

El resultado para el laberinto cretense original (grado 1) es el siguiente:

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

Patrón inicial:

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

El laberinto cretiano de grado 0 debería verse así:

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

Patrón inicial:

+ | +
--+--
+ | +
falla
fuente

Respuestas:

10

Perl 5, 349 bytes

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+"

(Pase n como argumento de línea de comando).

Calcula el laberinto línea por línea en seis secciones:

  • primeras 4n + 4 líneas,
  • siguiente línea (la única línea sin -),
  • siguientes n líneas,
  • siguiente línea (la línea en el medio del patrón inicial),
  • siguientes 2n + 1 líneas,
  • línea final (la línea con espacios iniciales).
Anders Kaseorg
fuente
6

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

Gracias a @flawr por sus consejos sobre cómo guardar 55 bytes (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]))

No soy un gran contendiente por el título, pero aún así lo intenté, y funciona perfectamente. Intentaré acortarlo más con el tiempo donde pueda, pero por ahora, me encanta y no podría estar más feliz.

Pruébalo en línea! (Ideone) (Puede verse un poco diferente aquí debido a las aparentes limitaciones del compilador en línea. Sin embargo, sigue siendo muy parecido) .

Explicación:

Para los fines de esta explicación, supongamos que la función anterior se ejecutó con la entrada r, que es igual a 1. Dicho esto, básicamente lo que está sucediendo, paso a paso, es ...

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

    Un objeto zip q, se crea con 2 objetos de rango, uno que consiste en cada segundo entero en el rango 0=>r+r+1y otro que consiste en cada segundo entero en el rango r+r+1=>0. Esto se debe a que cada patrón inicial de un laberinto cretense de un grado específico siempre tendrá un número par -en cada línea. Por ejemplo, para un laberinto cretense de grado 1, r+r+1igual 3, y por lo tanto, su patrón siempre comenzará con 0guiones, seguido de otra línea con 4guiones (2 + 2). Este objeto zip se usará para las primeras r+1líneas del patrón del laberinto.

    Nota: La única razón qes que una lista y separada del resto es porque qse hace referencia varias veces y se suscribe, y para ahorrar mucha repetición y permitir la suscripción, simplemente creé un objeto zip qen forma de lista.

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

    Este es el último paso, en el que se construye y se arma el laberinto. Aquí, tres listas, la primera que consiste en las 4*r+1líneas superiores del laberinto, la segunda que consiste en las 3*r+3líneas medias del laberinto y la última lista que consiste en la última línea del laberinto se unen, con saltos de línea ( \n) en Una larga cuerda. Finalmente, se imprime esta enorme cadena que consiste en todo el laberinto. Vamos a profundizar en lo que realmente contienen estas 2 listas y 1 cadena:

    • La primera lista, en la que se utiliza otro objeto comprimido en la comprensión de la lista para crear cada línea una por una, con símbolos iniciales |o +símbolos, un número impar de guiones en el rango 0=>4*(r+1), símbolos finales |y +símbolos, y luego una nueva línea ( \n). En el caso de un 1laberinto de grado , esta lista devuelve:

      +-----------------------------+
      | +-------------------------+ |
      | | +---------------------+ | |
      | | | +-----------------+ | | |
      | | | | +-------------+ | | | |
      | | | | | +---------+ | | | | |
      | | | | | | +-----+ | | | | | |
      | | | | | | | +-+ | | | | | | |
      
    • La segunda lista, que consiste en un objeto zip que contiene 4 listas, y cada lista corresponde a la cantidad de |símbolos iniciales / finales , la cantidad de +símbolos, la cantidad de guiones y, finalmente, la última lista, que contiene las primeras r+1líneas de el patrón creado de acuerdo con el objeto zip q, la línea en el medio del patrón (la que no tiene |) y las últimas r+2líneas del patrón simétrico. En este caso específico, la última lista utilizada en el objeto zip de esta lista devolvería:

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

      Y por lo tanto, en el caso de un laberinto de 1 grado, toda esta lista devolvería:

      | | | | | + | | | + | | | | | |
      | | | | +---+ | +---+ | | | | |
      | | | +-------+-------+ | | | |
      | | +-------+ | +-------+ | | |
      | +-------+ | | | +-------+ | |
      +-----------+ | +-----------+ | <- Here is where the extra line of the pattern is used.
      
    • Esta lista final, en la que se crea la última línea. Aquí, Pse crea la longitud del primer segmento (el anterior al primer espacio) de la última línea del número de espacios de la lista . Luego, se agrega la longitud del último segmento (el segmento final) de la misma línea + 4 números de guiones, todos los cuales están precedidos y seguidos por un solo +símbolo. En el caso de un laberinto de grado 1, esta última lista devuelve:

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

    Después de unir todo esto, este paso finalmente devuelve el laberinto completado. En el caso de un laberinto de 1 grado, finalmente devolvería esto:

    +-----------------------------+
    | +-------------------------+ |
    | | +---------------------+ | |
    | | | +-----------------+ | | |
    | | | | +-------------+ | | | |
    | | | | | +---------+ | | | | |
    | | | | | | +-----+ | | | | | |
    | | | | | | | +-+ | | | | | | |
    | | | | | + | | | + | | | | | |
    | | | | +---+ | +---+ | | | | |
    | | | +-------+-------+ | | | |
    | | +-------+ | +-------+ | | |
    | +-------+ | | | +-------+ | |
    +-----------+ | +-----------+ |
                  +---------------+
    
R. Kap
fuente
1
¿Puedes quizás primero definir R=rangeo algo así? Lo mismo para P='+'?
flawr
1
Creo que deberías aprovechar la oportunidad de oro para decirfor g,o,k,u in Z
Sherlock9
@ Sherlock9 Jaja! ¡Buena idea! Adicional. :)
R. Kap