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 ...
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+1
y 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+1
igual 3
, y por lo tanto, su patrón siempre comenzará con 0
guiones, seguido de otra línea con 4
guiones (2 + 2). Este objeto zip se usará para las primeras r+1
líneas del patrón del laberinto.
Nota: La única razón q
es que una lista y separada del resto es porque q
se hace referencia varias veces y se suscribe, y para ahorrar mucha repetición y permitir la suscripción, simplemente creé un objeto zip q
en forma de lista.
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+1
líneas superiores del laberinto, la segunda que consiste en las 3*r+3
lí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 1
laberinto 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+1
lí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+2
lí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í, P
se 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=range
o algo así? Lo mismo paraP='+'
?