Dada una mesa, colocar en las sillas

41

Reto

Se le dará una tabla como entrada, dibujada con ASCII |y _. Su tarea es colocar las sillas a su alrededor.

Ejemplo

Entrada:

 ____
|    |
|    |
|    |
|    |
|____|

Salida:

 _^_^_
<     >
|     |
<     >
|     |
<_ _ _>
  v v

Esas sillas están hechas de <>y v^.

Otro ejemplo:

La línea debe tener tantas sillas como sea posible.

  _____
 |     |_____
 |           |
 |           |
 |           |
 |      _____|
 |_____|


  _^_^_
 <     |_^_^_
 |           >
 <           |
 |           |
 <      _ _ _>
 |_ _ _| v v
   v v

Debe haber espacios entre cada silla. Y >_^_^_<no es válido, debería serlo |_^_^_|.

  _____       _____
 |     |_____|     |
 |                 |
 |                 |
 |                 |
 |      ___________|
 |_____|


  _^_^_       _^_^_
 <     |_^_^_|     >
 |                 |
 <                 >
 |                 |
 <      _ _ _ _ _ _>
 |_ _ _| v v v v v
   v v

No se pueden colocar sillas en el interior de una "dona".

  _________________
 |      _____      |
 |     |     |     |
 |     |     |     |
 |     |_____|     |
 |_________________|


  _^_^_^_^_^_^_^_^_
 <      _____      >
 |     |     |     |
 <     |     |     >
 |     |_____|     |
 <_ _ _ _ _ _ _ _ _>
   v v v v v v v v

^y vpriorizar <y >. No hay silla sola (debe tener al menos una |o _en la fila).

  _________________
 |      _____      |
 |     |     |     |
 |     |     |_____|
 |     |_____
 |___________|


  _^_^_^_^_^_^_^_^_
 <      _ _ _      >
 |     | v v |     |
 <     >     <_ _ _>
 |     |_^_^_  v v
 <_ _ _ _ _ _|
   v v v v v

Este es el código de golf, por lo que gana el código más corto.

Tim
fuente
2
Estoy confundido, ¿por qué las sillas están incrustadas en la mesa desde los lados?
Optimizador
Si no recuerdo mal, su publicación original de sandbox tenía un espacio entre la línea vertical de la mesa y la línea de la silla. Al igual que hay un pequeño espacio entre las líneas horizontales de la mesa y las sillas.
Optimizador
1
parece que las sillas se colocan a 1 distancia entre sí, pero el entorno de cualquier entrada no es divisible por 2. cómo el programa debería comenzar a poner sillas. en sentido horario o antihorario? desde la esquina superior derecha, la esquina superior izquierda, etc.
1
También creo que hay un problema en la tercera muestra: hay un espacio adicional entre la segunda y la tercera silla "superior", y también en el último ejemplo, en la esquina inferior derecha
1
El primer caso de prueba parece estar roto. La entrada tiene solo 4 de ancho y la salida es de 5.
Wheat Wizard

Respuestas:

34

Python 2, 1033 1007 924 879 829 787 713 699 692 691 688 687 672 670 664 659 654 648 643 642 630 625 623 620 570 560 554 545 518 514 513 510 505 492 476 454 451 443 bytes

6 bytes guardados gracias a Riley

6 bytes guardados gracias a Adnan

Como esta pregunta tiene más de un año y todavía no tiene respuestas, pensé en intentarlo.

n,i,o,u="\nI _";R=lambda x:range(1,x-1)
b=open(i).read()
s=b.split(n)
z=max(map(len,s))+3
a=[list(i+x.ljust(z,i))for x in[i]+s+[i]]
for x in R(len(a))*len(b):
 A=a[x];B=a[x+1];C=a[x-1]
 for y in R(z):
    D=A[y-1:y+2];k=B[y];j=A[y+1]
    if(i in[C[y],k]+D+(k==u)*B[y-1:y+2]or"V"==j)&(A[y]==o):A[y]=i
    if"|"==A[y]==C[y]:A[y]={i:"|",j:">",A[y-1]:"<"}[i]
    if[u]*3==D:A[y],B[y]={i:u+k,C[y]:"^"+k,k:" V"}[i]
print n.join(`y`[2::5]for y in a).replace(i,o)

Pruébalo en línea!

El programa lee la mesa en un archivo llamado Ie imprime la mesa con sus sillas std::out. No estaba seguro acerca de un montón de casos límite, así que tomé mi mejor juicio (lo que tomó el menor esfuerzo) pero parece pasar todos los casos de prueba. Algunas de las salidas no coinciden exactamente, pero todas tienen el mismo número de sillas.

Explicación

La primera línea simplemente establece algunas definiciones que nos ahorrarán bytes en el futuro:

(Descomprimiré estas macros para facilitar la lectura en líneas futuras)

n,i,o="\nI ";R=lambda x:range(1,x-1)

Luego abriremos un archivo llamado Iporque ya tenemos una variable que es la abreviatura de eso, por lo que ahorra algunos bytes.

b=open("I").read().split("\n")

Nos dividimos a lo largo de las nuevas líneas para crear una lista de cadenas (las filas de la imagen)

s=b.split(n)

Luego encuentro la longitud de la línea más larga para poder rellenar todas las líneas a esa longitud. (También agrego 3 porque necesitamos un poco de relleno adicional)

 z=max(map(len,s))+3

Luego realizamos el relleno real y creamos un borde de Icaracteres alrededor del borde. Esto se debe a que más adelante tendremos que diferenciar entre el interior y el exterior de la forma. También cambiaremos el tipo de datos de una lista de cadenas a una lista de caracteres (cadenas de longitud 1).

a=[list("I"+x.ljust(z,"I"))for x in["I"]+s+["I"]]

La siguiente línea es solo otra definición para guardar bytes.

(También desempacaré este)

B=R(len(a))

Ahora queremos difundir los Ipersonajes a todas partes fuera de la forma. Podemos hacer esto con un autómata pseudocelular. Cada uno Ise extenderá a cualquier personaje adyacente . Podríamos repetir hasta que el autómata se estabilice, sin embargo, esto no puede tomar más iteraciones de las que hay caracteres, por lo que simplemente recorremos cada carácter en b(la entrada original)

for _ in b:

Para cada iteración, queremos pasar sobre cada carácter en la lista 2D (excluyendo el relleno más externo)

 for x in range(1,len(a)-1):
    A=a[x]  #<--Another definition I will fill in for clarity
    for y in range(1,z-1):

Para cada posición ejecutamos el siguiente código:

if("I" in[a[x+1][y],a[x-1][y]]+a[x][y-1:y+2])&(a[x][y]==" "):a[x][y]=" "

Vamos a romper esto.

Tenemos un if con dos condiciones separadas por un &(bit a bit and)

El primero simplemente verifica si hay un Ien cualquiera de las celdas adyacentes y el segundo simplemente verifica si la celda actual es a " ". Si pasamos esas condiciones, establecemos que la celda actual sea an I.


Ahora que hemos determinado el exterior y el interior de la forma, podemos comenzar a colocar las sillas alrededor de la mesa.

Una vez más, recorremos todas las celdas (y establecemos algunas más shorthands)

for x in range(1,len(a)-1):
 A=a[x]
 for y in range(1,z-1):
        k=a[x+1][y]

Ahora aquí está mi parte favorita. Si hasta ahora has recorrido mi aburrido golf, principalmente basado en la definición, te recompensaré con un buen truco de golf inteligente (si lo digo yo mismo).

Un poco de historia en python:

En Python, si intenta asignar una clave de diccionario dos veces, asigna la última. Por ejemplo

>>> {1:"a",1:"b"}[1]
'b'

Abusaremos de esta propiedad para asignar la celda actual a un personaje en particular.

La primera condición es

if["_"]*3==a[x][y-1:y+2]:a[x][y],a[x+1][y]={"I":"_"+a[x+1][y],a[x-1][y]:"^ ",a[x+1][y]:" V"}["I"]

Si la celda está en el medio de un borde de 3 _caracteres, reasignaremos la celda actual y la celda debajo de ella. Lo asignaremos al resultado de indexar un diccionario sobrecargado por I. Primero establecemos nuestro valor predeterminado con el par, "I":"_"+a[x+1][y]esto significa que si no hay cambio, asignaremos las dos celdas a sus valores originales. A continuación agregamos el par a[x-1][y]:"^ ". Esto no hará nada (importante) a menos que la celda sobre la actual ( a[x-1][y]) esté llena de un I. Si tiene una entrada I, anulará el valor predeterminado que nos indica que coloquemos una silla en la celda actual. A continuación, pasamos a la celda debajo de la celda actual si esa celda se Ianula nuevamente para colocar una silla hacia arriba debajo del punto actual.

La siguiente condición es un poco más simple

if"|"==a[x][y]==a[x-1][y]:a[x][y]={"I":"|",A[y+1]:">",A[y-1]:"<"}["I"]   

Verificamos si la celda actual y la celda superior son ambas |. Si es así, creamos un diccionario.

El primer par en el diccionario "I":"|"establece el valor predeterminado. Dado que vamos a acceder a la clave Isi Ino se reasigna, volverá por defecto a |(el carácter que ya es) y no hará nada.

Luego, agregamos las dos teclas. A[y+1]:">",A[y-1]:"<"Si cualquiera de las dos celdas a la izquierda y a la derecha lo son I, reasignará la celda actual a una silla que apunte en la dirección del exterior.


Ahora solo tenemos que dar salida. Sin embargo, no podemos simplemente imprimir, hay un par de cosas de limpieza que tenemos que hacer primero. Tenemos que convertir de nuevo a una cadena y eliminar todos los Icorreos electrónicos que creamos. Esto se hace en una línea.

print "\n".join(`y`[2::5]for y in a).replace("I"," ")
Asistente de trigo
fuente
¿No puedes usar un espacio para el primer nivel de sangría, una pestaña para dos, una pestaña y un espacio para tres? Eso ahorrará unos pocos bytes.
Riley
3
Esta puede ser la respuesta más re-golfizada.
Urna de pulpo mágico
2
¿En i,o="I "lugar de i="I";o=" "trabajar?
Adnan
1
@ErikGolfer エ リ ッ ク ゴ ル フ ァ ー Hacer ncostos cuesta 4 bytes y me ahorra 6. Aunque no lo uso a menudo, ahorra 2 bytes.
Wheat Wizard
1
@ Pietu1998 Gracias por señalar eso. Solucioné el problema
Wheat Wizard