Renderizar un laberinto ASCII


18

¡Mira! ¡Es un laberinto ASCII! Soo coolzors, bolas de asombro y esas cosas.

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

Pero, pero, pero ... es un dolor determinar en qué dirección van todas las partes del laberinto. Solo quiero dibujar el diseño y el laberinto se hace mucho más grande sin mucho tiempo.

¿Y si pudiera dibujar esto en ...

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

¡Eso sería muy dulce!


Las reglas (porque las reglas son frías):

  • Escriba código para convertir una cadena en un laberinto ascii y generar el resultado.
  • Cualquier carácter que no sea un espacio en blanco se leerá como un muro.
  • Cada personaje de muro decidirá qué personaje se basará en sus vecinos (solo en las direcciones Norte, Sur, Este y Oeste).
    • Si un carácter no tiene vecinos que no sean espacios en blanco, será un signo más (+).
    • Si un personaje tiene vecinos en ambas direcciones vertical (Norte-Sur) y horizontal (Este-Oeste), será un signo más (+).
    • Si un personaje tiene vecinos solo en dirección vertical (Norte-Sur), será un símbolo de tubería (|).
    • Si un personaje tiene vecinos solo en dirección horizontal (Este-Oeste), será un signo menos (-).
  • La entrada puede ser una sola cadena (con líneas separadas por caracteres de nueva línea o una matriz de cadenas).
  • Todos los caracteres de entrada serán caracteres ASCII imprimibles, no necesita lidiar con caracteres extendidos.
  • Use cualquier idioma antiguo que desee.
  • Si hay un espacio en blanco antes de una línea, debe ser la misma cantidad en cada línea. Cualquier espacio en blanco después de cada línea de salida está bien.
  • Intenta resolverlo con el menor número de bytes.

Casos de prueba:

1: marco

Entrada:

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

Salida:

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

2: laberinto clásico

Entrada:

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

Salida:

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

3: Huevos verdes, hombre.

Entrada:

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!

Salida:

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

4: carámbanos

Entrada:

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

Salida:

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

1
¿No debería terminar la tercera línea de huevos verdes y jamón ---?
LiefdeWen

1
Los resultados para vecinos mixtos aún no están claros; No estoy seguro de por qué los carámbanos tendrían alguna -s o por qué el laberinto clásico no tiene cuatro +s en la fila inferior.
Neil

1
¿Se nos permite tomar la entrada como un cuadrado rellenado con espacios (es decir, matriz)? ¿Se permite que la salida tenga espacios en blanco adicionales a su alrededor? Además, ¿realmente quieres decir smallest number of characters, no bytes?
dzaima

1
Creo que 1) el laberinto clásico debería tener un +en el medio de la primera fila 2) el !de Icicles debería reemplazarse por a -. ¿Podría, por favor, verificar estos dos?
Arnauld

1
Por whitespace, ¿te refieres solo al espacio? No quiero tener que soportar pestañas y probablemente tampoco quieras que transforme nuevas líneas
Jo King

Respuestas:


11

APL (Dyalog Unicode) , 57 35 bytes SBCS

–22 gracias a una nueva solución de ngn .

Función tácita anónima que toma una matriz de caracteres como argumento.

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

Pruébalo en línea!

{}⌺3 3 En cada vecindario de 3 por 3, aplique la siguiente función:

,⍵ ravel (aplanar)

' '≠ Booleano donde no espacio

⍱∘⌽⍨ que NOR es inverso (incl. ni superior ni inferior, ni izquierda ni derecha)

5 4 2⊃¨⊂recoger 5 º , 4 º , y 2 nd elemento de toda esa lista
  es decir, auto vacía, no vertical, no horizontal

2⊥ evaluar en base-2 (binario)
  es decir ≥4: auto vacío; 3: sin vecinos; 2: sin vecinos horizontales; 1: sin vertical; 0: tiene ambos

'+-|+'↓⍨ gota que muchos elementos de esta cadena
  es decir, auto vacío: ; solo: +; vecino (s) vertical (es) solamente |+:; horizontal: -|+; ambos:+-|+

 recoger el primer elemento (almohadilla con espacio si no están disponibles)
  es decir, auto vacío: ; solo: +; vecino (s) vertical (es) solamente |:; horizontal: -; ambos:+


Vieja solución

Función tácita anónima que toma una matriz de caracteres como argumento.

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

Pruébalo en línea!

{}⌺3 3 En cada vecindario de 3 por 3, aplique la siguiente función:

,⍵ ravel (aplanar)

()/ Filtrar usando la siguiente máscara:

  9⍴0 1 reformar cíclicamente [0,1]a la longitud 9 (selecciona N, W, E, S)

' '≠ Booleano donde no espacio

1⌽ gire un paso a la izquierda; [W,E,S,N]

2 2⍴ remodelar a matriz 2 por 2; [[W,E],[S,N]]

∨/ reducción OR por fila: [horizontal,vertical]

(... ) aplique la siguiente función tácita:

   la identidad; [horizontal,vertical]

  ∧/, precedido por su reducción Y; [both,horizontal,vertical]

(... ), anteponer lo siguiente:

  ,⍵ desentrañar el barrio

  5⊃ recoger el 5 º elemento (en sí misma)

  ' '= Booleano si espacio (es decir, vacío)

 Ahora tenemos [empty,both,horizontal,vertical]

1⍳⍨ índice del extremo izquierdo 1 (da 5 si no hay vecinos)

' +-|+'⊃⍨ usar eso para elegir el símbolo

   


6

JavaScript (ES6), 110 bytes

Formato de E / S: conjunto de cadenas.

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

Pruébalo en línea!

O 108 bytes usando una matriz de caracteres en su lugar.


6

Python 2 , 181 168 bytes

gracias a Leaky Nun por -13 bytes

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

Pruébalo en línea!


5

MATLAB, 113 110 101 bytes

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)

Convierte la entrada a lógica, aplica convolución en horizontal y vertical y combina las salidas para hacer los caracteres correspondientes.

@Adriaan guardó 3 bytes por decirme que puede obstruir la salida en PPCG: P

¡9 bytes guardados gracias a numerosos comentarios de @flawr!



2

Retina 0.8.2 , 92 bytes

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

Pruébalo en línea! Requiere entrada rectangular. El enlace incluye casos de prueba. Explicación:

\S
0

Cambiar todos los no espacios a 0s.

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

Busque todas las 0s con otra 0inmediatamente arriba o abajo en la misma columna y cámbielas a 1. Las 1s son ahora los lugares con vecinos verticales, mientras que las 0s no tienen vecinos verticales.

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

Busque todos los dígitos sin vecinos horizontales. Los 0s tampoco tienen vecinos verticales, por lo que se convierten en +s, mientras que los 1s tienen vecinos verticales, por lo que se convierten en |s.

T`d`-+

Los dígitos restantes tienen vecinos horizontales. Los 1s también tienen vecinos verticales, por lo que se convierten en +s, mientras que los 0s solo tienen vecinos horizontales, por lo que se convierten en -s.


1

Python 3 , 336 bytes

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)

Pruébalo en línea!

Tuve que usar mucho código para lidiar con los errores de caso límite.


1

C (gcc) , 143 bytes

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);}}

Pruébalo en línea!

La función f modifica una matriz de cadenas en el lugar. El área alrededor de la matriz debe rellenarse con espacios (un poco restringidos). Aunque esto no cumple exactamente con los requisitos que la mayoría de las soluciones están usando, sí se ajusta a las reglas si decimos que representamos una nueva línea con dos espacios (y tomamos una serie de cadenas que terminan en nuevas líneas).

Sin golf

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 = '+';
                }
            }
        }
    }
}

Este fue un desafío divertido de la aritmética de punteros. Usando la iteración de puntero estilo C es fácil obtener los vecinos horizontales, pero los verticales fueron más difíciles. Afortunadamente, el puntero y todavía está alrededor (que apunta al valor inicial de z) para que pueda deducir mi índice de él y usarlo para acceder al mismo elemento en una fila diferente. ¡Me sentí muy mal escribiendo y[-1][z-*y]ya que vuela frente a cualquier estilo razonable!


Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.