Fondo
(Basado en una historia verdadera y desgarradora)
En mi tiempo, he jugado con Lisp y lenguajes similares a menudo. He escrito con ellos, los ejecuté, los interpreté, los diseñé e hice que las máquinas escribieran con ellos por mí ... Y si hay algo que me molesta, es ver a Lisp que no cumple con mi estilo de formato específico.
Desafortunadamente, algunos editores de texto ( tos XCode tos ) tienden a eliminar mis hermosas pestañas y espacios cada vez que se copia y pega el código ... Tome esta sintaxis tipo Lisp bellamente espaciada:
(A
(B
(C)
(D))
(E))
(¿Dónde ABCDE
están las funciones arbitrarias)
ALGUNOS editores de texto descifran este hermoso código con el siguiente fin:
(A
(B
(C)
(D))
(E))
¡Que desastre! ¡Eso no es legible!
¿Ayudame aqui?
El reto
Su objetivo en este desafío es tomar una serie de funciones separadas por líneas nuevas en un formato que se describe a continuación y devolver un arreglo más hermoso que resalte la legibilidad y la elegancia.
La entrada
Definimos una función F
de N
argumentos de aridad como una construcción similar a la siguiente:
(F (G1 ...) (G2 ...) (G3 ...) ... (GN ...))
donde G1, G2, ..., GN
están todas las funciones en sí mismas. Una 0
función arity A
es simplemente (A)
, mientras que una 2
función arity B
es de la forma(B (...) (...))
Su código debe tomar la entrada como una serie de funciones con una sola línea nueva antes del paréntesis principal de cada función (excepto la primera función). El ejemplo anterior es una entrada válida.
Puedes asumir:
- Los paréntesis son equilibrados.
- Una función nunca tendrá que sangrarse más de 250 veces.
- CADA función está rodeada de paréntesis:
()
- El nombre de una función solo contendrá caracteres ASCII imprimibles.
- El nombre de una función nunca contendrá paréntesis o espacios.
- Hay una nueva línea final opcional en la entrada.
La salida
Su código debe generar el mismo conjunto de funciones, donde los únicos cambios realizados son las adiciones de espacios o pestañas antes de los paréntesis principales de las funciones. La salida debe cumplir con las siguientes reglas:
- La primera función (y las funciones de nivel superior posteriores) proporcionadas no deben tener espacios anteriores
- Un argumento sobre la ubicación horizontal de una función es exactamente una pestaña a la derecha de la ubicación horizontal de esa función.
- Una pestaña está definida por la implementación, pero debe tener al menos 3 espacios.
- Opcionalmente, puede imprimir un máximo de dos espacios después de cada línea.
Reglas
- Este es el código de golf: ¡el código más corto gana!
- Las lagunas estándar no están permitidas.
Ejemplos
Entrada:
(A
(B
(C)
(D))
(E))
Salida:
(A
(B
(C)
(D))
(E))
Entrada:
(!@#$%^&*
(asdfghjklm
(this_string_is_particularly_long
(...))
(123456789)))
(THIS_IS_TOP_LEVEL_AGAIN
(HERE'S_AN_ARGUMENT))
Salida:
(!@#$%^&*
(asdfghjklm
(this_string_is_particularly_long
(...))
(123456789)))
(THIS_IS_TOP_LEVEL_AGAIN
(HERE'S_AN_ARGUMENT))
Entrada:
(-:0
(*:0
(%:0
(Arg:6)
(Write:0
(Read:0
(Arg:30))
(Write:0
(Const:-6)
(Arg:10))))
(%:0
(Const:9)
(/:0
(Const:-13)
(%:0
(Arg:14)
(Arg:0)))))
(WriteArg:22
(-:0
(Const:45)
(?:0
(Arg:3)
(Arg:22)
(Arg:0)))))
Salida:
(-:0
(*:0
(%:0
(Arg:6)
(Write:0
(Read:0
(Arg:30))
(Write:0
(Const:-6)
(Arg:10))))
(%:0
(Const:9)
(/:0
(Const:-13)
(%:0
(Arg:14)
(Arg:0)))))
(WriteArg:22
(-:0
(Const:45)
(?:0
(Arg:3)
(Arg:22)
(Arg:0)))))
fuente
()
?Respuestas:
Pyth,
24201918 bytesIncrementa un contador para cada línea, cuenta el número total de paréntesis de cierre encontrados hasta el momento y lo resta del contador. Luego sangramos por
counter
pestañas.fuente
*4
es una preferencia codificada y redundante.FN.z+*ZC9N~Z-1/N\)
le permite usar el ancho de sangría de su editor y guarda un byte.\<tab>
oC9
.Common Lisp -
486414bytes (versión Rube Goldberg)Enfoque
En lugar de hacer como todos los demás y contar los paréntesis a mano, invoquemos al lector Lisp y hagámoslo de la manera correcta :-)
(
,)
o espacios en blanco como cadenas.read
función estándar para construir listas reales.p
a cada una de esas listas, que las escriben recursivamente en la salida estándar con el formato solicitado. En particular, las cadenas se imprimen sin comillas.Como consecuencia de este enfoque:
Ejemplo
Lectura de un archivo, usando este contenedor:
Aquí está el resultado:
(Parece que las pestañas se convierten en espacios aquí)
Bonito estampado (versión golfizada)
Contrariamente a la versión original más segura, esperamos que la entrada sea válida.
fuente
Retina ,
8983 bytesDonde
<tab>
representa un carácter de tabulación real (0x09) y<empty>
representa una línea vacía. Después de hacer esos reemplazos, puede ejecutar el código anterior con la-s
bandera. Sin embargo, no estoy contando ese indicador, porque también podría poner cada línea en su propio archivo fuente, en cuyo caso las 7 nuevas líneas serían reemplazadas por 7 bytes de penalización para los archivos fuente adicionales.Este es un programa completo, que toma información sobre STDIN e imprime el resultado en STDOUT.
Explicación
Cada par de líneas define una sustitución de expresiones regulares. La idea básica es hacer uso de los grupos de equilibrio de .NET para contar la profundidad actual hasta un determinado
(
, y luego insertar tantas pestañas antes de eso(
.Primero, preparamos la entrada. Realmente no podemos volver a escribir un número condicional de pestañas, si no podemos encontrarlas en algún lugar de la cadena de entrada para capturarlas. Entonces comenzamos duplicando toda la entrada, separada por una pestaña. Tenga en cuenta que el
s`
solo activa el modificador de una sola línea (o "punto-todo"), que garantiza que.
también coincida con las nuevas líneas.Ahora convertimos cada personaje después de esa pestaña en una pestaña también. Esto nos da una cantidad suficiente de pestañas al final de la cadena, sin modificar la cadena original hasta el momento.
Esta es la carne de la solución. El
m
ys
activa el modo multilínea (para que^
coincida con el comienzo de las líneas) y el modo de una sola línea. El+
le dice a Retina que siga repitiendo esta sustitución hasta que la salida deje de cambiar (en este caso, eso significa hasta que el patrón ya no coincida con la cadena).El patrón en sí coincide con un prefijo de la entrada hasta un no procesado
(
(es decir, un(
que no tiene pestañas antes, pero debería). Al mismo tiempo, determina la profundidad del prefijo con grupos de equilibrio, de modo que la altura de la pila2
corresponderá a la profundidad actual y, por lo tanto, al número de pestañas que necesitamos agregar. Esa es esta parte:O coincide con a
(
, empujándolo hacia la2
pila, o coincide con a)
, sacando la última captura de la2
pila, o coincide con otra cosa y deja la pila intacta. Dado que se garantiza que los paréntesis estén equilibrados, no debemos preocuparnos por tratar de saltar de una pila vacía.Después de haber pasado por la cadena de esta manera y encontrar un no procesado
(
para detenerse, la búsqueda anticipada salta hacia adelante hasta el final de la cadena y captura pestañas en el grupo3
mientras emerge de la2
pila hasta que está vacía:Al usar un
+
allí, nos aseguramos de que el patrón solo coincida con cualquier cosa si se inserta al menos una pestaña en la coincidencia; esto evita un bucle infinito cuando hay múltiples funciones de nivel raíz.Por último, nos deshacemos de esas pestañas de ayuda al final de la cadena para limpiar el resultado.
fuente
C:
9594 caracteresTodavía no está muy golfizado, y de la pregunta no estoy seguro de si las pestañas son aceptables, que es lo que uso aquí.
Sin golf:
Editar: Hecho para que se cierre en EOF.
fuente
if(c<11)
lugar deif(c==10)
?Julia,
10399979488 bytesEsto define una función sin nombre que acepta una cadena e imprime la versión con sangría. Para llamarlo, dale un nombre, por ejemplo
f=p->...
. Tenga en cuenta que la entrada debe ser una cadena de Julia válida, por lo$
que se deben escapar los signos de dólar ( ).Ungolfed + explicación:
Ejemplo, pretender que cada conjunto de cuatro espacios es una pestaña:
Cualquier sugerencia es más que bienvenida!
fuente
Haskell,
8381Una solución muy libre de puntos.
fuente
h=
.Perl, 41
40
caracteres+1
para-p
.Corre con:
fuente
Python 2 -
8878 BytesSolución bastante sencilla (y no muy corta):
fuente
'\t'
lugar de' '
y guardar un byte; 2) no es necesario asignarinput.split()
a una variable, ya que solo se usa una vez (lo mismo parac
, así como -d
solo mueve laprint
instrucción); 3) la precedencia del operador significa quel*c
no se necesitan paréntesis . Además, parece quef
no se usa para nada, ¿es una reliquia de una versión anterior?raw_input
lugar deinput
(¡y no olvide los paréntesis después!).CJam, 20 bytes
Pruébelo en línea en el intérprete de CJam .
Cómo funciona
fuente