Miglioramento domestico per il Minotauro


42

Miglioramento domestico per il Minotauro

Il labirinto cretese è abbastanza facile da disegnare. Inizia con una forma simmetrica (qui in rosso). Chiamiamo tutti i nodi di quelle linee "nodi". Quindi inizi a disegnare gli archi (neri): il primo inizia sempre nel nodo centrale superiore e si connette al nodo accanto ad esso sul lato destro, quindi i due nodi più vicini all'arco precedente sono collegati. Questo si ripete fino a quando tutti i nodi sono coperti.

gif

Ora possiamo generalizzare questo concetto: possiamo facilmente generare nuovi schemi iniziali aggiungendo più Lforme. Ho elencato le forme iniziali come segue:

grado

Il modello più a sinistra produrrà un labirinto cretese di grado 0 . Il prossimo creerà un labirinto cretese di grado 1 (quello originale) ecc.

Compito

Dato un numero intero non negativo n, il tuo programma dovrebbe produrre la rappresentazione ASCII di un labirinto di gradi cretese n, che viene mostrato nei seguenti esempi. Gli spazi finali / le nuove righe non contano. Devi includere una breve spiegazione di come funziona il tuo codice.

Esempi

L'output per il labirinto cretese originale (grado 1) è il seguente:

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

Modello iniziale:

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

Il labirinto cretino di grado 0 dovrebbe apparire così:

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

Modello iniziale:

+ | +
--+--
+ | +

Risposte:


10

Perl 5, 349 byte

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

(Passa n come argomento della riga di comando.)

Calcola il labirinto riga per riga in sei sezioni:

  • prime 4n + 4 righe,
  • riga successiva (l'unica riga con no -),
  • linee successive n,
  • riga successiva (la linea al centro del modello iniziale),
  • prossime 2n + 1 righe,
  • linea finale (la linea con spazi iniziali).

6

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, è ...

  1. 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+1e 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+1uguale 3, e quindi, il suo modello inizierà sempre con 0trattini, seguiti da un'altra linea con 4(2 + 2) trattini. Questo oggetto zip verrà utilizzato per le prime r+1linee del motivo del labirinto.

    Nota: l' unico motivo qè un elenco e separato dal resto è perché qviene referenziato alcune volte e sottoscritto, e per salvare molte ripetizioni e consentire la sottoscrizione, ho semplicemente creato un oggetto zip qsotto forma di un elenco.

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

    Questo è l'ultimo passo, in cui il labirinto è costruito e messo insieme. Qui, tre elenchi, il primo costituito dalle 4*r+1linee superiori del labirinto, il secondo costituito dalle 3*r+3linee 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 1labirinto 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+1righe di il motivo creato secondo l'oggetto zip q, la linea al centro del motivo (quella senza no |) e le ultime r+2linee 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 Pviene 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:

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

1
Puoi forse prima definire R=rangequalcosa del genere? Lo stesso per P='+'?
Flawr,

1
Penso che dovresti cogliere l'occasione d'oro per direfor g,o,k,u in Z
Sherlock9

@ Sherlock9 Haha! Buona idea! Aggiunto. :)
R. Kap
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.