Algunas personas insisten en usar espacios para tabulación y sangría.
Para la tabulación, eso es indiscutiblemente incorrecto. Por definición, los tabuladores deben usarse para la tabulación.
Incluso para la sangría, los tabuladores son objetivamente superiores:
Existe un claro consenso en la comunidad de Stack Exchange.
Usar un solo espacio para la sangría es visualmente desagradable; usar más de uno es un desperdicio.
Como todos los jugadores de bacalao
y golfsaben, los programas deben ser lo más cortos posible. No solo ahorra espacio en el disco duro, sino que también se reducen los tiempos de compilación si hay que procesar menos bytes.Al ajustar el ancho de la pestaña 1 , el mismo archivo se ve diferente en cada computadora, por lo que todos pueden usar su ancho de sangría favorito sin modificar el archivo real.
Todos los buenos editores de texto usan tabuladores por defecto (y definición).
¡Lo digo y siempre tengo razón!
Lamentablemente, no todos escuchan la razón. Alguien le ha enviado un archivo que lo está haciendo mal TM y usted tiene que arreglarlo. Podrías hacerlo manualmente, pero habrá otros.
Ya es bastante malo que los espaciadores estén desperdiciando su valioso tiempo, por lo que decide escribir el programa más corto posible para solucionar el problema.
Tarea
Escriba un programa o una función que haga lo siguiente:
Lea una sola cadena desde STDIN o como una línea de comando o argumento de función.
Identifique todas las ubicaciones donde se hayan utilizado espacios para tabulación o sangría.
Una serie de espacios es una sangría si ocurre al comienzo de una línea.
Una serie de dos o más espacios es tabulación si no es una sangría.
Un espacio único que no es sangrado puede o no haber sido usado para tabulación. Como era de esperar cuando usas el mismo personaje para diferentes propósitos, no hay una manera fácil de saberlo. Por lo tanto, diremos que el espacio se ha utilizado para la confusión .
Determine el ancho de pestaña 1 más largo posible para el que todos los espacios utilizados para tabulación o sangría se puedan reemplazar con tabuladores, sin alterar la apariencia del archivo.
Si la entrada no contiene ni tabulación ni sangría, es imposible determinar el ancho de la pestaña. En este caso, omita el siguiente paso.
Usando el ancho de tabulación previamente determinado, reemplace todos los espacios utilizados para tabulación o sangría con tabuladores.
Además, siempre que sea posible sin alterar la apariencia del archivo, reemplace todos los espacios utilizados para la confusión con tabuladores. (En caso de duda, elimine los espacios).
Devuelva la cadena modificada de su función o imprímala en STDOUT.
Ejemplos
Todos los espacios de
a bc def ghij
son tabulación
Cada serie de espacios rellena la cadena anterior de caracteres que no son espacios con un ancho de 5, por lo que el ancho de tabulación correcto es 5 y el resultado correcto 2 es
a--->bc-->def->ghij
Los dos primeros espacios de
ab cde f ghi jk lm
son tabulación, los otros confunden.
El ancho de pestaña correcto es 4, por lo que la salida correcta 2 es
ab->cde>f ghi>jk lm
El último espacio permanece intacto, ya que se representaría como dos espacios si se reemplaza por un tabulador:
ab->cde>f ghi>jk->lm
Todos menos uno espacios de
int main( ) { puts("TABS!"); }
son sangría, el otro es confusión.
Los niveles de sangría son 0, 4 y 8 espacios, por lo que el ancho de pestaña correcto es 4 y la salida correcta 2 es
int --->main( ) --->{ --->--->puts("TABS!"); --->}
El espacio en
( )
se representaría como tres espacios si se reemplaza por un tabulador, por lo que permanece intacto.Los dos primeros espacios de
x yz w
son sangría, los demás confusión.
El ancho de pestaña adecuado es 2 y la salida correcta 2 es
->x>yz w
El último espacio se representaría como dos espacios si se reemplaza por un tabulador, por lo que permanece intacto.
Los dos primeros espacios de
xy zw
son sangría, los otros tres son tabulación.
Solo un ancho de tabulación de 1 permite eliminar todos los espacios, por lo que la salida correcta 2 es
>>xy>>>zw
Todos los espacios de
a b c d
son confusión
No existe el ancho de pestaña más largo posible, por lo que la salida correcta 2 es
a b c d
Reglas adicionales
La entrada consistirá completamente en caracteres ASCII imprimibles y saltos de línea.
Puede suponer que hay como máximo 100 líneas de texto y como máximo 100 caracteres por línea.
Si elige STDOUT para la salida, puede imprimir un solo salto de línea final.
Aplican reglas estándar de código de golf .
1 El ancho de tabulación se define como la distancia en caracteres entre dos tabulaciones consecutivas , utilizando una fuente monoespaciada.
2 Las flechas de arte ASCII representan los tabuladores que Stack Exchange se niega a representar correctamente, para lo cual he enviado un informe de error. La salida real debe contener tabuladores reales.
fuente
programs should be as short as possible
¡Creo que he encontrado al hermano perdido de Arthur Whitney!Respuestas:
Pyth,
102103 bytesPruébalo en línea
Idea interesante, pero dado que las pestañas en la entrada rompen el concepto, no es muy útil.
Editar: Corregido error. muchas gracias @aditsu
fuente
PowerShell,
414409 bytesSeguí adelante y usé nuevas líneas en lugar de
;
donde sea posible para facilitar la visualización. Estoy usando terminaciones de línea de Unix, por lo que no debería afectar el recuento de bytes.Cómo ejecutar
Copie el código en el
SpaceMadness.ps1
archivo, luego canalice la entrada en el script. Asumiré que el archivo que necesita conversión se llamataboo.txt
:De PowerShell:
Desde el símbolo del sistema:
Lo probé con PowerShell 5, pero debería funcionar en 3 o superior.
Pruebas
Aquí hay un script rápido de PowerShell que es útil para probar lo anterior:
Ponga esto en el mismo directorio que
SpaceMadness.ps1
, yo llamo a estetester.ps1
, llámelo así:Tienes la idea. Escupe el contenido de cada archivo después de la conversión, y se ejecuta
[RegEx]::Escape()
para escapar de los espacios y las pestañas, por lo que es realmente conveniente ver lo que realmente se ha cambiado.La salida se ve así (pero con colores):
Explicación
La primera línea define la mayor función común de factor / divisor
g
tan sucintamente como pude manejar, que toma una matriz (número arbitrario de números) y calcula GCD de forma recursiva utilizando el algoritmo euclidiano .El propósito de esto era determinar el "ancho de tabulación más largo posible" tomando el índice + longitud de cada sangría y tabulación como se define en la pregunta, luego introduciéndolo en esta función para obtener el MCD que creo que es lo mejor que podemos hacer para el ancho de la pestaña. La longitud de una confusión siempre será 1, por lo que no contribuye en nada a este cálculo.
$b
define un bloque de script porque molestamente necesito llamar a ese código dos veces, así que guardo algunos bytes de esa manera. Este bloque toma la cadena (o matriz de cadenas)$n
y ejecuta una expresión regular en ella (sls
oSelect-String
), devolviendo objetos coincidentes. De hecho, estoy obteniendo sangrías y tabulaciones en una aquí, lo que realmente me ahorró un procesamiento adicional al capturarlas por separado.$n
se usa para diferentes cosas dentro y fuera del bucle principal (realmente malo, pero necesario aquí para que pueda incrustarlo en$b
el bloque de script y usarlo tanto dentro como fuera del bucle sin una largaparam()
declaración y sin pasar argumentos.$s
se le asigna el ancho de la pestaña, llamando al$b
bloque en la matriz de líneas en el archivo de entrada, luego sumando el índice y la longitud de cada coincidencia, devolviendo la matriz de las sumas como un argumento en la función GCD. Entonces,$s
el tamaño de nuestra pestaña se detiene ahora.Entonces comienza el ciclo. Repetimos cada línea en la matriz de líneas de entrada
$n
. Lo primero que hago en el bucle es asignar$n
(alcance local) el valor de la línea actual por la razón anterior.$w
obtiene el valor de la llamada al scriptblock solo para la línea actual (las sangrías y tabulaciones para la línea actual).$c
obtiene un valor similar, pero en cambio encontramos todas las confusiones .Sumo
$w
y$c
cuáles son matrices, dándome una matriz con todas las coincidencias de espacio que necesito,sort
en orden descendente por índice, y empiezo a iterar sobre cada coincidencia para la línea actual.El tipo es importante. Al principio descubrí de la manera más difícil que reemplazar partes de una cadena basada en valores de índice es una mala idea cuando la cadena de reemplazo es más pequeña y cambia la longitud de la cadena. Los otros índices quedan invalidados. Entonces, al comenzar con los índices más altos en cada línea, me aseguro de que solo acorte la cadena desde el final y me muevo hacia atrás para que los índices siempre funcionen.
En este bucle,
$x
está en el índice de la coincidencia actual y$l
es la duración de la coincidencia actual.$s
de hecho puede ser0
y eso causa una molesta división por cero error, así que estoy verificando su validez y luego haciendo los cálculos.El
!(($x+$l)%$s)
bit es el único punto en el que verifico si una confusión debe reemplazarse con una pestaña o no. Si el índice más la longitud dividida por el ancho de la pestaña no tiene resto, entonces es bueno reemplazar esta coincidencia con una pestaña (esa matemática siempre funcionará en las muescas y tabulaciones , porque su tamaño es lo que determina el ancho de la pestaña para empezar).Para el reemplazo, cada iteración del bucle de coincidencia funciona en la línea actual de la entrada, por lo que es un conjunto acumulativo de reemplazos. La expresión regular solo busca
$l
espacios precedidos por$x
cualquier carácter. Lo reemplazamos con$l/$s
caracteres de tabulación (o 1 si ese número está por debajo de cero).Esta parte
(($l/$s),1-ge1)[0]
es una forma elegante y complicada de decirif (($l/$s) -lt 0) { 1 } else { $l/$s }
o alternativamente[Math]::Max(1,($l/$s))
. Forma una matriz de$l/$s
y1
, luego usa-ge 1
para devolver una matriz que contiene solo los elementos que son mayores o iguales a uno, luego toma el primer elemento. Viene en unos pocos bytes más cortos que la[Math]::Max
versión.Entonces, una vez que se realizan todos los reemplazos, la línea actual se devuelve desde la iteración
ForEach-Object
(%
), y cuando se devuelven todos (una matriz de líneas fijas), se-join
edita con nuevas líneas (ya que al principio nos dividimos en nuevas líneas).Siento que hay margen de mejora aquí que estoy demasiado agotado para atrapar en este momento, pero tal vez veré algo más tarde.
fuente
PHP -
278210 bytesLa función funciona probando el ancho de cada pestaña, comenzando con un valor de 100, la longitud máxima de una línea y, por lo tanto, el ancho máximo de la pestaña.
Para cada ancho de pestaña, dividimos cada línea en "bloques" de esa longitud. Para cada uno de estos bloques:
Una vez que cada bloque de una línea ha sido analizado, memorizamos un salto de línea. Si todos los bloques de todas las líneas se analizaron con éxito, devolvemos la cadena que hemos memorizado. De lo contrario, si se ha intentado cada ancho de pestaña estrictamente positivo, no hubo tabulación ni sangría, y devolvemos la cadena original.
Aquí está la versión sin golf:
Un agradecimiento especial a DankMemes por guardar 2 bytes.
fuente
for($t=101;--$t;)
lugar defor($t=100;$t;--$t)
CJam, 112
Pruébalo en línea
Tenía que responder a este desafío, porque debo hacer mi parte para ayudar a librar al mundo de esta abominación. Las pestañas son obviamente superiores, pero lamentablemente, algunas personas simplemente no pueden ser razonadas.
Explicación:
fuente
PowerShell ,
165160153152142138137 bytesPruébalo en línea!
Menos golfizado:
fuente