Python 3.5, 703 695 676 648 587 581 542 535 500 486 462 431 423 411 byte:
( Grazie a @flawr per consigli su come salvare 55 byte (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]))
Non è un contendente per il titolo, ma ho comunque provato, e funziona perfettamente. Cercherò di accorciarlo più nel tempo dove posso, ma per ora lo adoro e non potrei essere più felice.
Provalo online! (Ideone) (Potrebbe apparire un po 'diverso qui a causa delle evidenti limitazioni del compilatore online. Tuttavia, è ancora molto simile.)
Spiegazione:
Ai fini di questa spiegazione, supponiamo che la funzione sopra sia stata eseguita con l'ingresso r
, essendo uguale a 1
. Detto questo, fondamentalmente quello che sta succedendo, passo dopo passo, è ...
q=[*Z(R(0,B-1,2),R(B-1,0,-2))]
Un oggetto zip q
, viene creato con 2 oggetti intervallo, uno costituito da ogni secondo intero nell'intervallo 0=>r+r+1
e un altro costituito da ogni secondo intero nell'intervallo r+r+1=>0
. Questo perché ogni modello iniziale di un labirinto cretese di un grado specifico avrà sempre un numero pari di -
in ogni riga. Ad esempio, per un labirinto cretese di gradi 1
, r+r+1
uguale 3
, e quindi, il suo modello inizierà sempre con 0
trattini, seguiti da un'altra linea con 4
(2 + 2) trattini. Questo oggetto zip verrà utilizzato per le prime r+1
linee del motivo del labirinto.
Nota: l' unico motivo q
è un elenco e separato dal resto è perché q
viene referenziato alcune volte e sottoscritto, e per salvare molte ripetizioni e consentire la sottoscrizione, ho semplicemente creato un oggetto zip q
sotto forma di un elenco.
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]))
Questo è l'ultimo passo, in cui il labirinto è costruito e messo insieme. Qui, tre elenchi, il primo costituito dalle 4*r+1
linee superiori del labirinto, il secondo costituito dalle 3*r+3
linee mediane del labirinto, e l'ultimo elenco costituito dall'ultima riga del labirinto sono uniti, con le interruzioni di riga ( \n
) in una lunga corda. Infine, viene stampata questa enorme stringa composta dall'intero labirinto. Andiamo più in profondità nel contenuto di questi 2 elenchi e 1 stringa:
Il 1 ° elenco, in cui un altro oggetto zippato viene utilizzato nella comprensione dell'elenco per creare ciascuna riga una per una, con inizio |
o +
simboli, un numero dispari di trattini nell'intervallo 0=>4*(r+1)
, trailing |
o +
simboli e quindi una nuova riga ( \n
). Nel caso di un 1
labirinto di laurea , questo elenco restituisce:
+-----------------------------+
| +-------------------------+ |
| | +---------------------+ | |
| | | +-----------------+ | | |
| | | | +-------------+ | | | |
| | | | | +---------+ | | | | |
| | | | | | +-----+ | | | | | |
| | | | | | | +-+ | | | | | | |
Il secondo elenco, che consiste in un oggetto zip contenente 4 elenchi, e ciascun elenco corrisponde al numero di |
simboli iniziali / finali , al numero di +
simboli, al numero di trattini e, infine, all'ultimo elenco, che contiene le prime r+1
righe di il motivo creato secondo l'oggetto zip q
, la linea al centro del motivo (quella senza no |
) e le ultime r+2
linee del motivo simmetrico. In questo caso specifico, l'ultimo elenco utilizzato nell'oggetto zip di questo elenco restituirà:
+ | | | +
--+ | +--
----+----
--+ | +--
+ | | | +
--+ | +-- <- Last line created especially for use in the middle of the labyrinth itself.
E quindi, nel caso di un labirinto di 1 grado, l'intero elenco ritornerebbe:
| | | | | + | | | + | | | | | |
| | | | +---+ | +---+ | | | | |
| | | +-------+-------+ | | | |
| | +-------+ | +-------+ | | |
| +-------+ | | | +-------+ | |
+-----------+ | +-----------+ | <- Here is where the extra line of the pattern is used.
Questo elenco finale, in cui viene creata l'ultima riga. Qui P
viene creato il primo segmento (quello prima del primo spazio) dell'ultima riga del numero di spazi dell'elenco . Quindi, viene aggiunta la lunghezza dell'ultimo segmento (il segmento finale) della stessa linea + 4 numero di trattini, tutti preceduti e seguiti da un singolo +
simbolo. Nel caso di un labirinto di grado 1, quest'ultima lista restituisce:
+---------------+
Dopo aver unito tutto questo, questo passaggio restituisce finalmente il labirinto completato. Nel caso di un labirinto di 1 grado, alla fine restituirebbe questo:
+-----------------------------+
| +-------------------------+ |
| | +---------------------+ | |
| | | +-----------------+ | | |
| | | | +-------------+ | | | |
| | | | | +---------+ | | | | |
| | | | | | +-----+ | | | | | |
| | | | | | | +-+ | | | | | | |
| | | | | + | | | + | | | | | |
| | | | +---+ | +---+ | | | | |
| | | +-------+-------+ | | | |
| | +-------+ | +-------+ | | |
| +-------+ | | | +-------+ | |
+-----------+ | +-----------+ |
+---------------+
R=range
qualcosa del genere? Lo stesso perP='+'
?