Mini golf de lunes: una serie de desafíos de código corto de golf , publicados (¡ojalá!) Todos los lunes.
Muchas aplicaciones web (especialmente las redes sociales) truncan automáticamente largos pasajes de texto para que se ajusten al formato de la aplicación. En este desafío, vamos a crear un algoritmo para recortar automáticamente un pasaje de texto a una cierta longitud.
Reto
El objetivo del desafío es escribir un programa o función que tome dos argumentos:
- T , el texto a truncar.
- L , la longitud máxima para volver.
Y devuelve T , truncado con la siguiente lógica:
- Si la longitud de T es menor o igual que L , no se necesita truncamiento. Devuelve la cadena original.
- Truncar T a la longitud L -2. Si no contiene espacios ni guiones, devuelva T truncado a exactamente L -3 caracteres, seguido de puntos suspensivos
...
. - De lo contrario, recorte el final del resultado hasta el último espacio o guión. Agregue puntos suspensivos
...
y devuelva el resultado.
Detalles
- T y L pueden tomarse en cualquier orden y en cualquier formato.
- Puede suponer que 3 < L <2 31 .
- No puede usar puntos suspensivos horizontales U + 2026
…
; debes usar tres períodos. - La entrada no comenzará con un espacio o un guión.
- La entrada no contendrá ningún espacio en blanco que no sean espacios regulares. (Sin pestañas, líneas nuevas, etc.)
Casos de prueba
Entradas:
"This is some very long text." 25
"This-is-some-long-hyphen-separated-text." 33
"Programming Puzzles & Code Golf is a question and answer site for programming puzzle enthusiasts and code golfers." 55
"abcdefghijklmnopqrstuvwxyz" 20
"a b c" 4
"Very long." 100
Salidas:
"This is some very long..."
"This-is-some-long-hyphen..."
"Programming Puzzles & Code Golf is a question and..."
"abcdefghijklmnopq..."
"a..."
"Very long."
(Tenga en cuenta que las comillas son solo para especificar que se trata de cadenas; no es necesario que se incluyan).
Tanteo
Este es el código de golf , por lo que gana el código válido más corto en bytes. Tiebreaker va a la presentación que alcanzó su conteo final de bytes primero. El ganador será elegido el próximo lunes 5 de octubre. ¡Buena suerte!
Editar: ¡ Felicidades a tu ganador, @Jakube con Pyth nuevamente, con 25 bytes!
Respuestas:
Pyth, 25 bytes
Pruébelo en línea: Demostración o conjunto de pruebas
Explicación:
fuente
Perl,
695952 bytesCódigo de 51 bytes + línea de comando de 1 byte. Asume que la entrada numérica se puede dar con el parámetro -i.
Uso:
fuente
Python 2,
7873 bytesEl formato de entrada sigue la entrada de ejemplo.
fuente
JavaScript (ES6),
123786761 bytesNo esperaba poder reducir esto tanto, pero resulta que el combo de empalme / reemplazo es capaz de cubrir todos los casos donde se necesita truncamiento.
El primer argumento es la cadena, el segundo es la longitud. ¡Un agradecimiento especial a edc65 por la optimización de verificación de longitud!
Aquí está el código original (123 bytes):
fuente
.length
verificar la longitud de una(T,L)=>T[L]?T.slice(0,L-2).replace(/([ -][^ -]*|.)$/,'...'):T
puntuación de cadena 61[ -][^ -]
con\s\S
para guardar 5 bytes másTI-BASIC, 87 bytes
TI-BASIC no tiene muchos comandos de manipulación de cadenas, por lo que debemos encontrar el último índice de forma manual: si la cadena no contiene la cadena para buscar,
inString(
devuelve 0. Buscamos guiones y espacios que comienzan en cada posición desde 1 aL
y registrar el mayor número menor o igual aL-3
. Si ese númeroI
sigue siendo 0, usamosL-3
como índice final en su lugar.Debido a las limitaciones de la calculadora, el índice direccionable más grande de una cadena es 9999; por lo tanto, esto fallará para cadenas más grandes.
Confío en el comportamiento de la calculadora de inicializar automáticamente la variable
I
a 0, por lo tanto, elimineI
o borre la memoria de la calculadora antes de ejecutarla.fuente
C # .NET,
187169 bytesHmm ...
fuente
Python 2, 105 bytes
Llamado con
fuente
Groovy, 95 bytes
Bastante sencillo, probablemente se pueda jugar más golf
fuente
CJam, 34 bytes
Pruébelo en línea: Chrome | Firefox
fuente
T-SQL, 145 bytes
uso:
exec a("This is some very long text.", 25) exec a("This-is-some-long-hyphen-separated-text.", 33)
fuente
rs , 116
Al menos es más corto que C # ...
Demostración en vivo y casos de prueba.
fuente
Ceilán
386333252230222216171153131111Original sin golf:
Esto es 386 bytes / caracteres. Algunas características interesantes aquí:
La
x[y:z]
sintaxis es azúcar sintáctica parax.measure(y, z)
, y devuelve un subrango dex
inicioy
con longitudz
; para cadenas, esta es una subcadena. (También hay unax[y..z]
sintaxis, que es un intervalo desde el índice y a la z, ambos incluidos, así como tramos medio abiertosx[...z]
yx[y...]
).List.lastIndexWhere
toma un predicado (es decir, una función que toma un elemento de lista y devuelve un booleano, es decir, aquí unCallable<Boolean, [Character]>
), y proporciona el índice del último elemento de lista donde se cumple el predicado (o nulo, si nunca se cumple). Como las cadenas son listas, esto también funciona para las cadenas.El resultado de esto
spaceIndex
es de tipoInteger|Null
, oInteger?
para abreviar, es decir, puede ser un número entero onull
(el único valor de tipoNull
). (El nombrespaceIndex
proviene de cuando no me di cuenta de que eso-
también era especial, supongobreakIndex
que sería mejor).Con
exists spaceIndex
podemos verificar sispaceIndex
no es nulo y hacer algo diferente entonces. (Dentro de este bloque si, el compilador sabe que no es nulo ... sin eso se habría quejado si hubiera usadospaceIndex
acceder a la cadena).En lugar de la función local
spacePredicate
, también podemos usar una función anónimaEsto nos lleva a 333 caracteres:
La siguiente optimización es usar nombres más cortos de variables y funciones, lo que nos reduce en 81 bytes a 252:
La función de predicado en realidad no necesita su tipo de argumento declarado, que puede ser inferido por el compilador. Lo mismo para el tipo de
i
(donde todavía tenemos que escribirvalue
para marcarlo como una declaración). Ahora esa declaración es lo suficientemente corta como para caber en una línea, llevándonos a 230:En lugar de
e == ' ' || e == '-'
, también podemos escribire in [' ', '-']
(oe in {' ', '-'}
, este es un constructor iterable en lugar de uno de tupla). Elin
operador se asigna al método Category.contains, lo que nos lleva a la idea de que podemos pasar elcontains
método de esa tupla directamente (es invocable tomar cualquier objeto, por lo que también acepta caracteres), sin el(e) => ...
repetitivo (222 bytes):En realidad, otra categoría que contiene los mismos dos caracteres es la cadena de dos caracteres
" -"
. (Además, también contiene sus subcadenas, pero eso no duele aquí). 216 bytes.Supongo que sacamos el máximo provecho de esta línea, pasemos a las otras ... las dos últimas declaraciones de retorno tienen alguna similitud que podemos explotar: simplemente difieren en
i
vs.l-3
y se usani
solo cuando no es nulo, de lo contrariol-3
. Afortunadamente, ¡esto es exactamente para loelse
que está hecho el operador!(Los paréntesis parecen ser necesarios aquí, ya que
else
tiene una precedencia menor que[:]
). Esto es 171 caracteres. Ahorai
se usa solo una vez, por lo que podemos alinearlo, llevándonos a 153 caracteres:También podemos reemplazar esta
if-return-return
combinación por una combinación de los operadoresthen
yelse
en unoreturn
. (then
devuelve el segundo operando cuando el primero es verdadero, de lo contrario es nulo, lo que luego permiteelse
devolver su segundo operando.) 131 bytes (aunque algunos de los ahorros son los espacios en blanco que eliminaremos de todos modos):Una función que contiene solo un retorno con una expresión puede escribirse alternativamente con la notación de "flecha gorda", dando 123:
Eliminar el espacio en blanco innecesario nos da los 111 bytes finales:
String t(String s,Integer l)=>s.size<l then s else s[0:(s[0:l-2].lastIndexWhere(" -".contains)else l-3)]+"...";
Además, aquí hay una función que imprime los ejemplos de la pregunta (usando el nombre
t
que se usa después del paso dos):fuente
POSIX shell + GNU sed, 65 bytes
Este es un trabajo hecho para sed! Pero necesitaba un shell para obtener el límite de longitud (quizás Perl sería mejor). La parte sed se expande a una secuencia bastante simple, con saltos condicionales cuando terminamos:
fuente
Mathematica 192 bytes
Llamado
fuente
> <>, 74 bytes
Esta solución requiere que la cadena esté truncada y
L
que ya esté en la pila, en ese orden.Hay 7 bytes desperdiciados causados por problemas de alineación, que todavía intentan eliminarlos.
fuente
C # (157):
Basado en la respuesta de Salah Alami , pero más corto. La clase de cadena se deriva de
IEnumerable<char>
, por lo que en lugar deT.Contains(" ")||T.Contains("-")
, yo uso" -".Any(x=>T.Contains(x))
.Solución:
Sin golf:
Actualizar:
Guardado 6 bytes gracias al comentario de SLuck49, utilizando en
Any(T.Contains)
lugar deAny(x=>T.Contains(x))
.fuente
.Any(x=>T.Contains(x))
que pueda utilizar directamente el método en lugar de un lambda como.Any(T.Contains)
para guardar 6 bytesGS2 , 29 bytes
Este programa toma entrada estándar. La primera línea es la cadena y la segunda es el número de longitud objetivo.
El código GS2 puede ser un poco difícil de leer a veces. :) Aquí hay algunos comentarios.
fuente
Groovy, 56 bytes
Copié la respuesta de Kleyguerth primero, de ahí los mismos nombres de variables ...
Recorte la cadena hacia abajo por 2 caracteres, luego la mayoría de los trabajos se realiza mediante la expresión regular, reemplace un guión o un espacio seguido de cualquier número de caracteres que no sean un guión o un espacio al final de la cadena con un "." O reemplace cualquier carácter al final de la cadena si todos los caracteres anteriores no son ni un guión ni un espacio con un ".". Más difícil de poner en palabras que escribir la expresión regular ...
Editar: en realidad, puede eliminar la parte de la cadena que coincide con la expresión regular y agregar "..." al final:
fuente
Jalea , 29 bytes
Pruébalo en línea!
Programa completo
fuente
Limpio , 89 bytes
Pruébalo en línea!
Como una función
$ :: Int String -> String
fuente
C # (compilador interactivo de Visual C #) , 117 bytes
Basado en @ Abba's, que se basa en la respuesta de @Salah Alami. En lugar de usar
Contains
unaSubstring
llamada innecesaria , usa IndexOf para verificar si existe un guión o espacio en la cadena truncada.Pruébalo en línea!
fuente