Mini-golfe de segunda-feira: Uma série de desafios curtos de golfe com código , publicados (espero!) Toda segunda-feira.
Muitos aplicativos da Web (especialmente as mídias sociais) truncam automaticamente longas passagens de texto para que se ajustem à formatação do aplicativo. Neste desafio, criaremos um algoritmo para aparar automaticamente uma passagem de texto em um determinado comprimento.
Desafio
O objetivo do desafio é escrever um programa ou função que aceite dois argumentos:
- T , o texto a ser truncado.
- L , o comprimento máximo para retornar.
E retorna T , truncado com a seguinte lógica:
- Se o comprimento de T for menor ou igual a L , nenhum truncamento será necessário. Retorne a string original.
- Trunque T no comprimento L -2. Se isso não contiver espaços ou hífens, retorne T truncado para exatamente L -3 caracteres, seguido por reticências
...
. - Caso contrário, apare o final do resultado até o último espaço ou hífen. Adicione uma elipse
...
e retorne o resultado.
Detalhes
- T e L podem ser obtidos em qualquer ordem e em qualquer formato.
- Você pode assumir que 3 < L <2 31 .
- Você não pode usar reticências horizontais U + 2026
…
; você deve usar três períodos. - A entrada não começará com um espaço ou um hífen.
- A entrada não conterá nenhum espaço em branco que não seja espaços regulares. (Sem guias, novas linhas etc.)
Casos de teste
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
Saídas:
"This is some very long..."
"This-is-some-long-hyphen..."
"Programming Puzzles & Code Golf is a question and..."
"abcdefghijklmnopq..."
"a..."
"Very long."
(Observe que as aspas são apenas para especificar que são strings; elas não precisam ser incluídas.)
Pontuação
Este é o code-golf , pelo que o código válido mais curto em bytes vence. O desempatador vai para o envio que atingiu sua contagem final de bytes primeiro. O vencedor será escolhido na próxima segunda-feira, 5 de outubro. Boa sorte!
Edit: Parabéns ao seu vencedor, @Jakube with Pyth novamente, com 25 bytes!
Respostas:
Pitão, 25 bytes
Experimente on-line: Demonstration or Test Suite
Explicação:
fonte
Perl,
695952 bytesCódigo de 51 bytes + linha de comando de 1 byte. Assume que é permitido que a entrada numérica seja fornecida com o parâmetro -i.
Uso:
fonte
Python 2,
7873 bytesO formato de entrada segue o exemplo de entrada.
fonte
JavaScript (ES6),
123786761 bytesEu não esperava poder reduzir tanto isso, mas acontece que a combinação de emenda / substituição é capaz de cobrir todos os casos em que o truncamento é necessário.
O primeiro argumento é a string, o segundo é o comprimento. Agradecimentos especiais a edc65 pela otimização da verificação de comprimento!
Aqui está o código original (123 bytes):
fonte
.length
para verificar o comprimento de uma string(T,L)=>T[L]?T.slice(0,L-2).replace(/([ -][^ -]*|.)$/,'...'):T
pontuação 61[ -][^ -]
com\s\S
mais para salvar 5 bytesTI-BASIC, 87 bytes
O TI-BASIC não possui muitos comandos de manipulação de string, portanto, precisamos encontrar o último índice manualmente: se a string não contiver a string a ser pesquisada,
inString(
retornará 0. Procuramos hífens e espaços começando em todas as posições de 1 paraL
e registre o maior número menor ou igual aL-3
. Se esse númeroI
ainda for 0, usamosL-3
o índice final.Devido às limitações da calculadora, o maior índice endereçável de uma string é 9999; portanto, isso falhará para cadeias maiores.
Eu confio no comportamento da calculadora de inicializar automaticamente a variável
I
para 0, então excluaI
ou limpe a memória da calculadora antes de executar.fonte
C # .NET,
187169 bytesHmm...
fonte
Python 2, 105 bytes
Chamado com
fonte
Groovy, 95 bytes
Bem simples, provavelmente pode ser jogado mais longe
fonte
CJam, 34 bytes
Experimente online: Chrome | Raposa de fogo
fonte
T-SQL, 145 bytes
uso:
exec a("This is some very long text.", 25) exec a("This-is-some-long-hyphen-separated-text.", 33)
fonte
rs , 116
Pelo menos é mais curto que C # ...
Demonstração ao vivo e casos de teste.
fonte
Ceilão
386333252230222216171153131111Original Não Goleado:
São 386 bytes / caracteres. Algumas características interessantes aqui:
A
x[y:z]
sintaxe é açúcar sintático parax.measure(y, z)
e retorna um subintervalo dex
inícioy
com comprimentoz
- para seqüências de caracteres, este é um substring. (Também háx[y..z]
sintaxe, que é uma extensão do índice y até z, tanto inclusivas quanto também com aberturas pela metadex[...z]
ex[y...]
.)List.lastIndexWhere
pega um predicado (ou seja, uma função que pega um elemento da lista e retorna um booleano, ou seja, aquiCallable<Boolean, [Character]>
) e fornece o índice do último elemento da lista em que o predicado é atendido (ou nulo, se nunca for atendido). Como strings são listas, isso também funciona para strings.O resultado disso
spaceIndex
é do tipoInteger|Null
ou,Integer?
para abreviar - ou seja, pode ser um número inteiro ounull
(o único valor do tipoNull
). (O nomespaceIndex
vem de quando eu não percebi que isso-
também era especial - achobreakIndex
que seria melhor.)Com
exists spaceIndex
podemos verificar sespaceIndex
não é nulo e, então, fazer algo diferente. (Dentro deste bloco if, o compilador sabe que não é nulo ... sem isso, teria reclamado se eu usassespaceIndex
acesso à string.)Em vez da função local
spacePredicate
, também podemos usar uma função anônimaIsso nos leva a 333 caracteres:
A próxima otimização é usar nomes mais curtos de variáveis e funções, o que nos reduz em 81 bytes para 252:
A função predicado, na verdade, não precisa do seu tipo de argumento declarado, que pode ser inferido pelo compilador. O mesmo para o tipo de
i
(onde ainda precisamos escrevervalue
para marcá-lo como uma declaração). Agora essa declaração é curta o suficiente para caber em uma linha, reduzindo-nos a 230:Em vez de
e == ' ' || e == '-'
também podemos escrevere in [' ', '-']
(oue in {' ', '-'}
, este é um construtor iterável em vez de um tuplo). Oin
operador mapeia para o método Category.contains, o que nos leva à idéia de que podemos passar ocontains
método dessa tupla diretamente (é possível chamar qualquer objeto, aceitando também o caractere), sem o(e) => ...
clichê (222 bytes):Na verdade, outra categoria que contém os mesmos dois caracteres é a sequência de dois caracteres
" -"
. (Além disso, ele também contém suas substrings, mas isso não dói aqui). 216 bytes.Acho que tiramos o máximo proveito dessa linha, vamos nos voltar para as outras ... as duas últimas declarações de retorno têm alguma semelhança que podemos explorar - elas diferem em
i
vs.l-3
e estão usandoi
exatamente quando não é nulo, caso contráriol-3
. Felizmente, é exatamente para isso que oelse
operador é feito!(Os parênteses parecem ser necessários aqui, pois
else
têm uma precedência mais baixa que[:]
.) São 171 caracteres. Agorai
é usado apenas uma vez, para que possamos incorporá-lo, levando-nos a 153 caracteres:Também podemos substituir essa
if-return-return
combinação por uma combinação dos operadoresthen
eelse
em umreturn
. (then
retorna é o segundo operando quando o primeiro é verdadeiro, caso contrário, nulo, o que permiteelse
retornar seu segundo operando.) 131 bytes (embora algumas das economias sejam os espaços em branco que serão eliminados de qualquer maneira):Uma função que contém apenas um retorno com uma expressão pode, alternativamente, ser escrita com a notação "flecha gorda", fornecendo 123:
A remoção do espaço em branco desnecessário nos dá os 111 bytes finais:
String t(String s,Integer l)=>s.size<l then s else s[0:(s[0:l-2].lastIndexWhere(" -".contains)else l-3)]+"...";
Além disso, aqui está uma função que imprime os exemplos da pergunta (usando o nome
t
que é usado após a etapa dois):fonte
Shell POSIX + GNU sed, 65 bytes
Este é um trabalho feito para sed! Mas eu precisava do shell para obter o limite de comprimento (talvez o Perl fosse melhor). A parte sed se expande para uma sequência bastante simples, com saltos condicionais quando terminamos:
fonte
Mathematica 192 bytes
Chamado como
fonte
> <>, 74 bytes
Essa solução requer que a sequência esteja truncada e
L
já esteja na pilha, nessa ordem.Há 7 bytes desperdiçados causados por problemas de alinhamento, ainda tentando resolver esses problemas.
fonte
C # (157):
Com base na resposta de Salah Alami , mas mais curto. A classe string deriva de
IEnumerable<char>
, então, em vez deT.Contains(" ")||T.Contains("-")
, eu uso" -".Any(x=>T.Contains(x))
.Solução:
Ungolfed:
Atualizar:
Economizou 6 bytes graças ao comentário de SLuck49, usando em
Any(T.Contains)
vez deAny(x=>T.Contains(x))
.fonte
.Any(x=>T.Contains(x))
que você pode usar diretamente o método em vez de um lambda como.Any(T.Contains)
para salvar 6 bytesGS2 , 29 bytes
Este programa recebe entrada padrão. A primeira linha é a sequência e a segunda é o número do comprimento alvo.
Às vezes, o código GS2 pode ser um pouco difícil de ler. :) Aqui estão alguns comentários.
fonte
Groovy, 56 bytes
Copiei a resposta de Kleyguerth primeiro, daí os mesmos nomes de variáveis ...
Apare a string em 2 caracteres, e a maior parte do trabalho é feita pela regex, substitua um traço ou um espaço seguido por qualquer número de caracteres que não sejam um traço ou um espaço no final da string com um "." OU substitua qualquer caractere no final da string se todos os caracteres anteriores a ela não forem um traço ou um espaço com um ".". Mais difícil de colocar em palavras do que escrever o regex ...
Edit: Na verdade, basta remover a parte da string que corresponde ao regex e adicionar "..." no final:
fonte
Gelatina , 29 bytes
Experimente online!
Programa completo.
fonte
Limpo , 89 bytes
Experimente online!
Como uma função
$ :: Int String -> String
fonte
C # (compilador interativo do Visual C #) , 117 bytes
Baseado no @ Abba's, baseado na resposta do @Salah Alami. Em vez de usar
Contains
e um desnecessárioSubstring
chamada , ele usa IndexOf para verificar se existe um hífen ou espaço na cadeia truncada.Experimente online!
fonte