Seu desafio é formatar uma lista de palavras em várias linhas que não tenham mais que um determinado número de caracteres, para que cada linha contenha o maior número possível de palavras e que nenhuma seja desnecessariamente cortada.
Entrada
A entrada será uma lista de palavras separadas por espaço e, em seguida, um número que seja pelo menos 4.
Resultado
A saída deve ser as palavras de entrada agrupadas em linhas, para que nenhuma das linhas contenha mais caracteres que o número de entrada. As palavras devem ser exibidas na ordem em que foram inseridas. As palavras devem ser separadas por vírgula e depois por um espaço, exceto no final de cada linha, onde o espaço não é necessário. Se uma palavra for muito longa para caber em uma linha, ela deve ser cortada o menos possível enquanto segue as outras regras e "..." deve ser adicionado ao final.
Casos de teste
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...
Respostas:
Ilegível , 2559 bytes
Esse desafio é assustadoramente adequado para ilegível.
A primeira versão disso era 3379 bytes, apenas para lhe dar uma idéia do quanto eu joguei isso.
O programa aceita a entrada exatamente como descrito no desafio: uma lista de palavras separadas por espaço (que também podem conter dígitos e sinais de pontuação), seguida por um espaço e um número inteiro que é pelo menos 4 (números mais baixos geram loops infinitos) .
Explicação
Vou mostrar como o programa processa a entrada
thyme horseradish peppermint 10
. A saída esperada éthyme,\nhorser...,\npeppermint
.Primeiro, começamos na célula 7 e lemos toda a entrada, mas subtraímos 32 de cada caractere para que os espaços se tornem zeros.
Por razões óbvias, isso deixa o ponteiro em execução (chamado p aqui, armazenado na célula # 0) no final. Usamos um loop while para encontrar a última lacuna, que é o começo do número que define a largura da saída (célula nº 36 neste exemplo).
Agora queremos decodificar o número (ou seja, converter de decimal). O resultado final será nas células t e r . Contamos com o fato de que eles começam do zero.
Para cada dígito no número, faça o seguinte:
'0'
com'9'
códigos ASCII 48–57; portanto, após a subtração anterior de 32, eles são 16–25; portanto, adicionamos 15–24 a t , o que cancela com −15. nós configuramos para mais cedo. Também é importante que isso zere as células que costumavam conter os caracteres de dígito para que o código subseqüente possa reconhecer o final da lista de palavras.Finalmente, usamos outro loop while simples (diminuindo t como o contador) para converter o número que acabamos de calcular em unário. Armazenamos uma sequência de 1s indo para a esquerda a partir da célula # 0. Isso se baseia no fato de que a célula nº 1, nosso ponteiro em execução para este ( q ), começa em 0. Temos um 1s a menos porque os loops em Ilegível são assim:
Depois disso, não precisamos mais do valor em r , então reutilizamos essa célula para outra coisa. Nós redefinir a ponteiros p e q e inicializar algumas células com códigos ASCII de caracteres que precisamos mais tarde. Eu também rotulei c e s, que usaremos mais tarde, e confiaremos no fato de que s começa em zero:
Ei, espera um pouco. Por que a célula # 0 está vermelha? ... Bem, isso é para destacar um truque sorrateiro. Lembre-se de que produzimos um 1 a menos? O truque é que usamos a célula # 0 como uma "extensão" para corrigir isso. Isso funciona porque sabemos que p nunca será 0. Dessa forma, o bloco vermelho agora tem 10 células de largura, exatamente o número que queremos. Ele também salva 9 caracteres para poder inicializar q para 1 em vez de 0.
Agora, entramos no loop while, que percorre as palavras e gera todas elas.
Etapa 1: descubra se a próxima palavra se encaixará na linha atual. Para fazer isso, basta mover p para a direita eq para a esquerda com um loop while até que p atinja a próxima lacuna:
Agora que p está à direita da palavra, podemos verificar se esta é a última palavra da lista, verificando se * (p + 1) é zero. Também armazenamos esse valor (que em nosso exemplo é 72 porque é o "h" de "rábano silvestre" menos 32) em c porque precisamos dele novamente mais tarde. Nesse caso, não é zero; portanto, precisamos gerar uma vírgula junto com a palavra, para que a palavra tenha um caractere a mais. Considere isso diminuindo q mais uma vez. Por fim, use outro loop while para retornar p ao início da palavra.
Agora sabemos que a palavra se encaixará na linha atual porque q está apontando para um valor diferente de zero, então tudo o que precisamos fazer é:
Saída até agora:
thyme,
Em seguida, a próxima iteração do grande loop é iniciada. Como antes, verificamos se a próxima palavra se encaixa no restante da linha, diminuindo q à medida que passamos pela palavra da esquerda para a direita. Observe que q ainda é –5 da iteração anterior, mantendo o controle de quantos caracteres já imprimimos na linha atual. Depois de contar os caracteres em "rábano", mais um para a vírgula, mais um porque s é diferente de zero, indicando que também precisamos gerar um espaço, q terá ultrapassado o final do bloco de 1s:
Agora q aponta para uma célula zero, o que significa que o "rábano silvestre" não se ajustará à linha atual. O que fazemos agora depende se s é diferente de zero. No nosso caso, é o que significa que precisamos avançar para a próxima linha. Tudo o que precisamos fazer é:
Saída até agora:
thyme,\n
Para a próxima iteração, p está no mesmo lugar que antes, portanto, veremos a mesma palavra novamente. Como antes, contamos os caracteres em "raiz-forte", definimos c como 80 novamente quando notamos que há outra palavra após esta, diminui q para a vírgula e retrocede p de volta ao início da palavra:
Como na iteração anterior, descobrimos que "raiz forte" ainda não se encaixa porque q acaba em uma célula que é zero. No entanto, desta vez s é zero, o que significa que fazemos algo diferente da última vez. Precisamos produzir parte da palavra, três pontos e uma vírgula. Nossa largura é 10, portanto, precisamos gerar 6 caracteres da palavra. Vamos ver onde terminamos se:
A fita agora fica assim:
Eu marquei um espaço de 6 células aqui. Como você pode ver, precisamos gerar caracteres até q = -1. Isso é muito eficiente em termos de código para verificar (basicamente
while ((++q)+1) { ... }
). Então:print(print(print('.')))
). Pegamos o valor ASCII da célula nº 5 e adicionamos 2 para obter o código ASCII do ponto.Depois de tudo isso, também imprimimos uma nova linha (usando a célula nº 3) e configuramos q de volta para 1. Também podemos definir s como 0, mesmo que já seja 0, o que torna o mesmo que fizemos anteriormente quando envolvemos o arquivo próxima linha (quando s é diferente de zero), para evitar repetir o código, fazemos isso após o condicional que verifica s .
Saída até agora:
thyme,\nhorser...,\n
Há apenas uma iteração restante. Desta vez, depois de contar as letras da palavra, obtemos o seguinte:
Desta vez, como não há nada após p , definimos c como 0 para indicar “sem vírgula” e, portanto, não diminuímos q mais uma vez. Como q agora aponta para uma célula diferente de zero, sabemos que a palavra se ajustará; portanto, o mesmo código é executado como na primeira iteração, exceto que, desta vez, c é zero e, portanto, simplesmente não imprime a vírgula.
Resultado:
thyme,\nhorser...,\npeppermint
Nesta explicação passo a passo, não incluí um caso em que o código realmente imprimiria um espaço, mas acho que deveria estar bem claro agora. Se o código achar que a palavra se encaixa ( * q ≠ 0) e s é diferente de zero, ele simplesmente produzirá um espaço antes da palavra.
fonte
JavaScript (ES6), 171
Como uma função anônima retornando a saída como uma matriz
(como isso geralmente é permitido, a menos que seja explicitamente proibido: meta meta )
fonte
Python 2, 206 bytes
fonte