Su desafío es formatear una lista de palabras en varias líneas que no tengan más de un número dado de caracteres, de modo que cada línea contenga la mayor cantidad de palabras posible y ninguna palabra se corte innecesariamente.
Entrada
La entrada será una lista de palabras separadas por espacios y luego un número que sea al menos 4.
Salida
La salida debe ser las palabras de entrada agrupadas en líneas para que ninguna de las líneas contenga más caracteres que el número de entrada. Las palabras deben salir en el orden en que fueron ingresadas. Las palabras deben estar separadas por una coma y luego un espacio, excepto al final de cada línea, donde el espacio no es necesario. Si una palabra es demasiado larga para caber en una línea, se debe cortar lo menos posible mientras se siguen las otras reglas, y se debe agregar "..." al final.
Casos de prueba
Input:
foo bar baz qux 12
Output:
foo, bar,
baz, qux
Input:
foo bar baz qux 5
Output:
foo,
bar,
baz,
qux
Input:
strength dexterity constitution intelligence wisdom charisma 10
Output:
strength,
dexterity,
consti...,
intell...,
wisdom,
charisma
Input:
quas wex exort 4
Output:
...,
wex,
e...
Respuestas:
Ilegible , 2559 bytes
Este desafío es inquietantemente apto para ilegible.
La primera versión de esto tenía 3379 bytes, solo para darte una idea de cuánto jugué al golf.
El programa acepta la entrada exactamente como se describe en el desafío: una lista de palabras separadas por espacios (que también pueden contener dígitos y signos de puntuación), seguidas de un espacio y un número entero que es al menos 4 (los números más bajos generan bucles infinitos) .
Explicación
Voy a guiarlo a través de cómo el programa procesa la entrada
thyme horseradish peppermint 10
. La salida esperada esthyme,\nhorser...,\npeppermint
.Primero comenzamos en la celda # 7 y leemos la entrada completa, pero restamos 32 de cada carácter para que los espacios se conviertan en ceros.
Por razones obvias, esto deja el puntero en ejecución (llamado p aquí, almacenado en la celda # 0) al final. Usamos un bucle while para encontrar el último espacio, que es el comienzo del número que define el ancho de la salida (celda # 36 en este ejemplo).
Ahora queremos decodificar el número (es decir, convertir de decimal). El resultado final estará en ambas celdas t y r . Confiamos en el hecho de que comienzan en cero.
Para cada dígito en el número, haga lo siguiente:
'0'
que'9'
tienen códigos ASCII 48-57, así que después de la resta anterior de 32 que son 16-25, así que en realidad añadimos a 15-24 t , que cancela con el -15 Lo configuramos para antes. También es importante que esto ponga a cero las celdas que solían contener los caracteres de dígitos para que el código posterior pueda reconocer el final de la lista de palabras.Finalmente, usamos otro ciclo while simple (decrementando t como el contador) para convertir el número que acabamos de calcular en unario. Almacenamos una cadena de 1s hacia la izquierda desde la celda # 0. Esto se basa en el hecho de que la celda n. ° 1, nuestro puntero en ejecución para esto ( q ), comienza en 0. Obtenemos un 1 menos porque los bucles en Unreadable son así:
Después de esto, ya no necesitamos el valor en r , por lo que reutilizamos esa celda para otra cosa. Restablecemos los punteros p y q e inicializamos algunas celdas con códigos ASCII de caracteres que necesitamos más adelante. También he etiquetado c y s que usaremos más tarde, y confiaremos en el hecho de que s comienza en cero:
Oye, espera un minuto. ¿Por qué la celda # 0 es de color rojo? ... Bueno, esto es para resaltar un truco furtivo. ¿Recuerdas que sacamos uno 1 muy pocos? El truco es que usamos la celda # 0 como una "extensión" para corregir eso. Esto funciona porque sabemos que p nunca será 0. De esta manera, el bloque rojo ahora tiene 10 celdas de ancho, exactamente el número que queremos. También guarda 9 caracteres para poder inicializar q a 1 en lugar de 0.
Ahora ingresamos al ciclo while que pasa por las palabras y las genera todas.
Paso 1: averigua si la siguiente palabra se ajustará a la línea actual. Hacemos esto simplemente moviendo p hacia la derecha yq hacia la izquierda con un ciclo while hasta que p llegue al siguiente espacio:
Ahora que p está a la derecha de la palabra, podemos verificar si esta es la última palabra en la lista comprobando si * (p + 1) es cero. También almacenamos ese valor (que en nuestro ejemplo es 72 porque es la "h" de "rábano picante" menos 32) en c porque lo necesitaremos nuevamente más tarde. En este caso, no es cero, por lo que tendremos que mostrar una coma junto con la palabra, por lo que la palabra tiene un carácter más largo. Tenga esto en cuenta disminuyendo q una vez más. Finalmente, use otro bucle while para mover p al principio de la palabra.
Ahora sabemos que la palabra se ajustará a la línea actual porque q apunta a un valor distinto de cero, por lo que todo lo que tenemos que hacer es:
Salida hasta ahora:
thyme,
Entonces comienza la siguiente iteración del bucle grande. Como antes, verificamos si la siguiente palabra se ajusta al resto de la línea disminuyendo q a medida que avanzamos por la palabra de izquierda a derecha. Tenga en cuenta que q todavía es −5 de la iteración anterior, haciendo un seguimiento de cuántos caracteres ya hemos impreso en la línea actual. Después de contar los caracteres en "rábano picante", más uno para la coma, más uno porque s no es cero, lo que indica que también necesitamos generar un espacio, q habrá superado el final del bloque de 1s:
Ahora q apunta a una celda cero, lo que significa que "rábano picante" no encajará en la línea actual. Lo que hacemos ahora depende de si s no es cero. En nuestro caso lo es, lo que significa que debemos pasar a la siguiente línea. Todo lo que tenemos que hacer para eso es:
Salida hasta ahora:
thyme,\n
Para la próxima iteración, p está en el mismo lugar que antes, por lo que volveremos a ver la misma palabra. Como antes, contamos los caracteres en “rábano picante”, establecemos c nuevamente en 80 cuando notamos que hay otra palabra después de esta, decrementamos q para la coma y rebobinamos p al principio de la palabra:
Como en la iteración anterior, encontramos que "rábano picante" todavía no encaja porque q termina en una celda que es cero. Sin embargo, esta vez s es cero, lo que significa que hacemos algo diferente que la última vez. Necesitamos mostrar algo de la palabra, tres puntos y una coma. Nuestro ancho es 10, por lo que debemos generar 6 caracteres de la palabra. Veamos dónde terminamos si:
La cinta ahora se ve así:
He marcado un lapso de 6 celdas aquí. Como puede ver, necesitamos generar caracteres hasta q = −1. Esto es muy eficiente en el código para verificar (básicamente
while ((++q)+1) { ... }
). Entonces:print(print(print('.')))
). Tomamos el valor ASCII de la celda # 5 y le agregamos 2 para obtener el código ASCII del punto.Después de todo esto, también imprimimos una nueva línea (usando la celda n. ° 3) y establecemos q nuevamente en 1. También podemos establecer s en 0 aunque ya sea 0, lo que hace que sea lo mismo que hicimos anteriormente cuando ajustamos siguiente línea (cuando s no era cero), por lo que para evitar repetir el código, lo hacemos después del condicional que verifica s .
Salida hasta ahora:
thyme,\nhorser...,\n
Solo queda una iteración. Esta vez, después de contar las letras de la palabra, obtenemos esto:
Esta vez, no hay nada después de p , por lo que establecemos c en 0 para indicar "sin coma" y, en consecuencia, no disminuimos q una vez más. Como q ahora apunta a una celda que no es cero, sabemos que la palabra se ajustará, por lo que se ejecuta el mismo código que en la primera iteración, excepto que esta vez c es cero, por lo que simplemente no imprimirá la coma.
Salida:
thyme,\nhorser...,\npeppermint
En este tutorial no incluí un caso en el que el código realmente imprimiera un espacio, pero creo que ahora debería estar bastante claro. Si el código encuentra que la palabra se ajusta ( * q ≠ 0) y s no es cero, simplemente generará un espacio antes de la palabra.
fuente
JavaScript (ES6), 171
Como una función anónima que devuelve la salida como una matriz
(ya que esto generalmente está permitido a menos que esté explícitamente prohibido: meta meta )
fuente
Python 2, 206 bytes
fuente