Python 3.5, 703 695 676 648 587 581 542 535 500 486 462 431 423 411 bytes:
( Obrigado a @flawr pelo conselho sobre como salvar 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]))
Não é um grande candidato ao título, mas ainda tentei, e funciona perfeitamente. Vou tentar reduzi-lo mais com o tempo, sempre que puder, mas por enquanto, adoro e não poderia ser mais feliz.
Experimente online! (Ideone) (Pode parecer um pouco diferente aqui por causa das limitações aparentes do compilador on-line. No entanto, ainda é praticamente o mesmo.)
Explicação:
Para os fins desta explicação, vamos supor que a função acima foi executada com a entrada r
, sendo igual a 1
. Dito isto, basicamente o que está acontecendo, passo a passo, é ...
q=[*Z(R(0,B-1,2),R(B-1,0,-2))]
Um objeto zip,, q
é criado com 2 objetos de intervalo, um consistindo em cada segundo número inteiro no intervalo 0=>r+r+1
e outro consistindo em cada segundo número inteiro no intervalo r+r+1=>0
. Isso ocorre porque todo padrão inicial de um labirinto de Creta de um grau específico sempre terá um número par -
em cada linha. Por exemplo, para um labirinto cretense de grau 1
, r+r+1
é igual 3
e, portanto, seu padrão sempre começa com 0
traços, seguido por outra linha com 4
(2 + 2) traços. Este objeto zip será usado para as primeiras r+1
linhas do padrão do labirinto.
Nota: O único motivo q
é uma lista e separada do restante é porque q
é referenciada algumas vezes e inscrita e, para economizar muitas repetições e permitir a inscrição, eu simplesmente criei um objeto zip q
na forma de uma 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 é o último passo, no qual o labirinto é construído e montado. Aqui, três listas, a primeira consistindo nas 4*r+1
linhas superiores do labirinto, a segunda consistindo nas 3*r+3
linhas médias do labirinto e a última lista consistindo na última linha do labirinto são unidas, com quebras de linha ( \n
) em uma corda longa. Finalmente, é impressa esta enorme corda composta por todo o labirinto. Vamos aprofundar o que essas 2 listas e 1 string realmente contêm:
A primeira lista, na qual outro objeto compactado é usado na compreensão da lista para criar cada linha uma por uma, com iniciais |
ou +
símbolos, um número ímpar de traços no intervalo 0=>4*(r+1)
, final |
ou +
símbolos e, em seguida, uma nova linha ( \n
). No caso de um 1
labirinto de graus , esta lista retorna:
+-----------------------------+
| +-------------------------+ |
| | +---------------------+ | |
| | | +-----------------+ | | |
| | | | +-------------+ | | | |
| | | | | +---------+ | | | | |
| | | | | | +-----+ | | | | | |
| | | | | | | +-+ | | | | | | |
A segunda lista, que consiste em um objeto zip contendo 4 listas, e cada lista corresponde ao número de |
símbolos iniciais / finais , o número de +
símbolos, o número de traços e, finalmente, a última lista, que contém as primeiras r+1
linhas de o padrão criado de acordo com o objeto zip q
, a linha no meio do padrão (aquela sem |
) e as últimas r+2
linhas do padrão simétrico. Nesse caso específico, a última lista usada no objeto zip dessa lista retornaria:
+ | | | +
--+ | +--
----+----
--+ | +--
+ | | | +
--+ | +-- <- Last line created especially for use in the middle of the labyrinth itself.
E, portanto, no caso de um labirinto de 1 grau, toda a lista retornaria:
| | | | | + | | | + | | | | | |
| | | | +---+ | +---+ | | | | |
| | | +-------+-------+ | | | |
| | +-------+ | +-------+ | | |
| +-------+ | | | +-------+ | |
+-----------+ | +-----------+ | <- Here is where the extra line of the pattern is used.
Esta lista final, na qual a última linha é criada. Aqui, o primeiro segmento (aquele antes do primeiro espaço) da última linha do P
número de espaços da lista é criado. Em seguida, é adicionado o comprimento do último segmento (o segmento final) da mesma linha + 4 número de traços, todos precedidos e seguidos por um único +
símbolo. No caso de um labirinto de grau 1, esta última lista retorna:
+---------------+
Depois de juntar tudo isso, essa etapa finalmente retorna o labirinto concluído. No caso de um labirinto de 1 grau, ele finalmente retornaria isso:
+-----------------------------+
| +-------------------------+ |
| | +---------------------+ | |
| | | +-----------------+ | | |
| | | | +-------------+ | | | |
| | | | | +---------+ | | | | |
| | | | | | +-----+ | | | | | |
| | | | | | | +-+ | | | | | | |
| | | | | + | | | + | | | | | |
| | | | +---+ | +---+ | | | | |
| | | +-------+-------+ | | | |
| | +-------+ | +-------+ | | |
| +-------+ | | | +-------+ | |
+-----------+ | +-----------+ |
+---------------+
R=range
ou algo assim? O mesmo paraP='+'
?