Rendering di un labirinto ASCII


18

Guarda! È un labirinto ASCII! Soo coolzors, stupefacenti e cose del genere.

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

Ma, ma, ma ... è una seccatura capire in che direzione stanno andando tutte le parti del labirinto. Voglio solo disegnare il layout e il labirinto si fa sooper kul senza un sacco di tempo.

E se potessi semplicemente disegnarlo in ...

#############
# #     #   #
# #  ##   # #
# #  ## ### #
#       #   #
######### # #
#         # #
#############

Sarebbe così dolce!


Le regole (Perché le regole sono fredde):

  • Scrivi il codice per convertire una stringa in un labirinto ascii e produrre il risultato.
  • Qualsiasi personaggio non bianco verrà letto come un muro.
  • Ogni personaggio del muro deciderà quale personaggio basarsi sui suoi vicini (solo nelle direzioni Nord, Sud, Est e Ovest).
    • Se un carattere non ha vicini non bianchi, sarà un segno più (+).
    • Se un personaggio ha vicini nelle direzioni verticale (Nord-Sud) e orizzontale (Est-Ovest), sarà un segno più (+).
    • Se un personaggio ha vicini solo in una direzione verticale (nord-sud), sarà un simbolo di pipa (|).
    • Se un personaggio ha vicini solo in una direzione orizzontale (est-ovest), sarà un segno meno (-).
  • L'input può essere una singola stringa (con linee separate da caratteri di nuova riga o una matrice di stringhe).
  • Tutti i caratteri di input saranno caratteri ASCII stampabili, non è necessario gestire set di caratteri estesi.
  • Usa qualsiasi vecchia lingua per favore.
  • Se c'è uno spazio bianco prima di una riga, dovrebbe essere la stessa quantità su ogni riga. Qualsiasi spazio bianco dopo ogni riga di output va bene.
  • Tentare di risolverlo con il minor numero di byte.

Casi test:

1: cornice

Ingresso:

##########
#        #
#        #
#        #
##########

Produzione:

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

2: labirinto classico

Ingresso:

#################
        #       #
# ##### # ##### #
#   # # #     # #
# # # # ##### # #
#   # #       # # 
### # ####### # #
#   # #    #  # # 
# ### # ## # ##
#     # ##    #  
#################

Produzione:

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

3: uova verdi, amico.

Ingresso:

I do not like green eggs and ham.
I do not like them, sam I am.
Would you like them here or there?
I would not like them anywhere!

Produzione:

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

4: ghiaccioli

Ingresso:

Word Icicle!
Word Icicle 
Word  cicle 
 ord  cicle 
 ord   icle 
 ord   i le 
 or    i le 
 or    i l  
 or      l  
 or         
  r         

Produzione:

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

1
La terza linea di uova verdi e prosciutto non dovrebbe finire con ---?
Liefde:

1
I risultati per i vicini misti non sono ancora chiari; non so perché i ghiaccioli abbiano qualche -s o perché il classico labirinto non abbia quattro +s nella fila inferiore.
Neil,

1
possiamo prendere l'input come un quadrato riempito di spazi (cioè matrice)? È consentito all'output di avere uno spazio bianco attorno? Inoltre, vuoi dire davvero smallest number of characters, non byte?
dzaima,

1
Penso che 1) il classico labirinto dovrebbe avere a +nel mezzo della 1a fila 2) il !di Icicles dovrebbe essere sostituito con a -. Potresti ricontrollare questi?
Arnauld,

1
Con whitespace, ti basta dire solo lo spazio? Non voglio dover supportare le schede e probabilmente non vorrai nemmeno che io trasformi le nuove righe
Jo King,

Risposte:


11

APL (Dyalog Unicode) , 57 35 byte SBCS

–22 grazie a una nuova soluzione di ngn .

Funzione tacita anonima che prende come argomento una matrice di caratteri.

{⊃'+-|+'↓⍨25 4 2⊃¨⊂⍱∘⌽⍨' '≠,⍵}⌺3 3

Provalo online!

{... }⌺3 3 su ogni quartiere 3 per 3, applica la seguente funzione:

,⍵ corvo (appiattire)

' '≠ Booleano dove non spazio

⍱∘⌽⍨ che NOR è inverso (incl. né in alto NOR in basso, né a sinistra NOR a destra)

5 4 2⊃¨⊂scegli il 5 ° , 4 ° e 2 ° elemento dall'intera lista,
  cioè un sé vuoto, nessuna verticale, nessuna orizzontale

2⊥ valutare in base-2 (binario)
  cioè ≥4: sé vuoto; 3: nessun vicino; 2: nessun vicino orizzontale; 1: nessuna verticale; 0: ha entrambi

'+-|+'↓⍨ goccia che molti elementi di questa stringa
  cioè auto vuota: ; da solo +:; vicino di casa verticale (s) solo: |+; orizzontale -|+:; tutti e due:+-|+

 scegliere il primo elemento (pad con spazio se non sono disponibili)
  cioè auto vuoto: ; da solo +:; vicino di casa verticale (s) solo: |; orizzontale -:; tutti e due:+


Vecchia soluzione

Funzione tacita anonima che prende come argomento una matrice di caratteri.

{' +-|+'⊃⍨1⍳⍨(' '=5⊃,⍵),(∧/,⊢)∨/2 21' '≠(90 1)/,⍵}⌺3 3

Provalo online!

{... }⌺3 3 su ogni quartiere 3 per 3, applica la seguente funzione:

,⍵ corvo (appiattire)

(... )/ filtra usando la seguente maschera:

  9⍴0 1 rimodellare ciclicamente [0,1]alla lunghezza 9 (seleziona N, W, E, S)

' '≠ Booleano dove non spazio

1⌽ ruotare di un passo a sinistra; [W,E,S,N]

2 2⍴ rimodellare a matrice 2 per 2; [[W,E],[S,N]]

∨/ riga O riduzione O: [horizontal,vertical]

(... ) applica la seguente funzione tacita:

   l'identità; [horizontal,vertical]

  ∧/, preceduto dalla sua riduzione AND; [both,horizontal,vertical]

(... ), anteporre quanto segue:

  ,⍵ ravel (appiattire) il quartiere

  5⊃ scegli il 5 ° elemento (stesso)

  ' '= Booleano se spazio (ovvero vuoto)

 Ora abbiamo [empty,both,horizontal,vertical]

1⍳⍨ indice dell'estrema sinistra 1 (indica 5 se non ci sono vicini)

' +-|+'⊃⍨ usalo per scegliere il simbolo

   


6

JavaScript (ES6), 110 byte

Formato I / O: matrice di stringhe.

a=>a.map((s,y)=>s.replace(/\S/g,(_,x)=>'+|-+'[[-1,p=0,1,2].map(c=>p|=(a[y+c%2]||0)[x+~-c%2]>' '?c&1||2:0)|p]))

Provalo online!

O 108 byte usando invece una matrice di caratteri.


6

Python 2 , 181 168 byte

grazie a Leaky Nun per -13 byte

m=input()
f=lambda x,y:(['']+m+[''])[y+1][x:x+1]>' '
print[[(c<'!')*' 'or'+-|+'[f(x+1,y)|f(x-1,y)|2*f(x,y+1)|2*f(x,y-1)]for x,c in enumerate(r)]for y,r in enumerate(m)]

Provalo online!


5

MATLAB, 113 110 101 byte

function F(A)
B=A>32
c=[1 1 1]
f=@(c)conv2(B,c,'s')>1
h=f(c)
v=f(c')
char((13*h+92*v-94*(h&v)).*B+32)

Converte l'input in logico, applica la convoluzione in orizzontale e verticale e combina gli output per creare i corrispondenti caratteri.

3 byte salvati da @Adriaan per avermi detto che puoi bloccare l'output in PPCG: P

9 byte salvati grazie ai numerosi commenti di @flawr!



2

Retina 0.8.2 , 92 byte

\S
0
(?<=(.)*)0(?=(?>.*\n(?<-1>.)*)0)|0(?=(.)*)(?<=0(?>(?<-2>.)*\n.*))
1
T`d`+|`\b.\b
T`d`-+

Provalo online! Richiede un input rettangolare. Il link include casi di test. Spiegazione:

\S
0

Cambia tutti i non spazi in 0s.

(?<=(.)*)0(?=(?>.*\n(?<-1>.)*)0)|0(?=(.)*)(?<=0(?>(?<-2>.)*\n.*))
1

Cerca tutte le 0s con un'altra 0immediatamente sopra o sotto nella stessa colonna e modificale in 1. Le 1s ora sono i posti con vicini verticali, mentre le 0s non hanno vicini verticali.

T`d`+|`\b.\b

Cerca tutte le cifre senza vicini orizzontali. Neanche le 0s hanno vicini verticali, quindi diventano +s, mentre le 1s hanno vicini verticali, quindi diventano |s.

T`d`-+

Le cifre rimanenti hanno vicini orizzontali. Le 1s hanno anche vicini verticali, quindi diventano +s, mentre le 0s hanno solo vicini orizzontali, quindi diventano -s.


1

Python 3 , 336 byte

def g(s):
 h,j,s=' +|-+','',s.splitlines()
 s+=['']
 for n in range(len(s)):
  s[n]+=' '
  for i in range(len(s[n])-1):
   l,r,k=s[n][i-1],s[n][i+1],0
   try:u=s[n-1][i]
   except:u=' '
   try:d=s[n+1][i]
   except:d=' '
   if not s[n][i]==' ':
    k+=1
    if not u==d==' ':k+=1
    if not l==r==' ':k+=2
   j+=h[k]
  j+='\n'
 print(j)

Provalo online!

Ho dovuto usare molto codice per gestire gli errori del caso limite.


1

C (gcc) , 143 byte

char**y,*z,h,v;f(char**x){for(y=x;*y;++y)for(z=*y;*z;++z)if(*z-32){h=z[1]-32|z[-1]-32;v=y[1][z-*y]-32|y[-1][z-*y]-32;*z=h?v?43:45:(v?'|':43);}}

Provalo online!

La funzione f modifica una matrice di stringhe sul posto. L'area intorno all'array deve essere riempita con spazi (un po 'vincolati). Anche se questo non soddisfa esattamente i requisiti utilizzati dalla maggior parte delle soluzioni, è conforme alle regole se diciamo che rappresentiamo una nuova riga con due spazi (e prendiamo una serie di stringhe che terminano in nuove righe).

Ungolfed

f(char**x){
    char **y;
    for (y = x; *y; ++y) {
        char *z;
        for (z = *y; *z; ++z) {
            if (*z != ' ') {
                if (z[1] != ' ' || z[-1] != ' ') {
                    // Horizontal exists
                    if (y[1][z-*y] != ' ' || y[-1][z-*y] != ' ')
                        // Vertical exists
                        *z = '+';
                    else
                        *z = '-';
                } else {
                    // Horizontal doesn't exist
                    if (y[1][z-*y] != ' ' || y[-1][z-*y] != ' ')
                        // Vertical exists
                        *z = '|';
                    else
                        *z = '+';
                }
            }
        }
    }
}

Questa è stata una sfida divertente dell'aritmetica del puntatore. Usando l'iterazione del puntatore in stile C è facile ottenere i vicini orizzontali, ma quelli verticali erano più difficili. Fortunatamente il puntatore y è ancora in giro (che punta al valore iniziale di z) quindi posso dedurre il mio indice da esso e usarlo per accedere allo stesso elemento su una riga diversa. Mi è sembrato molto sbagliato scrivere y[-1][z-*y]mentre vola di fronte a uno stile ragionevole!


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.