Faça um quebra-cabeças simples


22

(Nota: esta é a minha primeira pergunta de código de golfe, mas, até onde eu sei, ninguém mais fez exatamente isso, por isso devo ser bom.)

Sua tarefa é criar um programa ou função que inclua uma sequência de caracteres se um número inteiro ne retorne ou produza esse texto agrupado em várias linhas. Cada palavra deve estar totalmente em uma linha; ou seja, não há palavras divididas no meio. Cada linha não pode ter mais que ncaracteres, e você deve ajustar o máximo de palavras possível em cada linha.

Exemplo:

s = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed eget erat lectus. Morbi mi mi, fringilla sed suscipit ullamcorper, tristique at mauris. Morbi non commodo nibh. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Sed at iaculis mauris. Praesent a sem augue. Nulla lectus sapien, auctor nec pharetra eu, tincidunt ac diam. Sed ligula arcu, aliquam quis velit aliquam, dictum varius erat." 
n = 50

output:
Lorem ipsum dolor sit amet, consectetur adipiscing
elit. Sed eget erat lectus. Morbi mi mi, fringilla
sed suscipit ullamcorper, tristique at mauris.
Morbi non commodo nibh. Pellentesque habitant
morbi tristique senectus et netus et malesuada
fames ac turpis egestas. Sed at iaculis mauris.
Praesent a sem augue. Nulla lectus sapien, auctor
nec pharetra eu, tincidunt ac diam. Sed ligula
arcu, aliquam quis velit aliquam, dictum varius
erat.

Sua saída pode ser uma matriz de seqüências de caracteres ou uma única sequência com quebras de linha. Além disso, você pode assumir que nenhuma palavra terá mais do que nisso; portanto, não se preocupe em lidar com casos estranhos.

Aplicam-se as regras de E / S padrão e as brechas padrão são proibidas. Espaços à direita são permitidos.

Como se trata de , a solução de shortes em bytes vence.

Aqui está um exemplo de programa em Python que funcionaria.



3
n é o comprimento máximo da linha? ou o comprimento que precisamos atingir antes da quebra de linha?
david

1
@ David, ou o número de linhas?
Peter Taylor

1
28 bytes Python é relevante?
david

3
né o comprimento máximo da linha, desculpe-me por isso não estar claro. Eu vou esclarecer. Além disso, as regras foram atualizadas para que uma divisão simples não funcione.
ATMunn

Respostas:



5

PHP , 8 bytes

É certo que não é a solução mais original, mas o PHP tem uma função nativa que atende perfeitamente aos seus requisitos!

wordwrap:

string wordwrap ( string $str [, int $width = 75 [, string $break = "\n" [, bool $cut = FALSE ]]] )

Agrupa uma sequência em um determinado número de caracteres usando um caractere de quebra de sequência.

Use assim:

$str = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed eget erat lectus. Morbi mi mi, fringilla sed suscipit ullamcorper, tristique at mauris. Morbi non commodo nibh. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Sed at iaculis mauris. Praesent a sem augue. Nulla lectus sapien, auctor nec pharetra eu, tincidunt ac diam. Sed ligula arcu, aliquam quis velit aliquam, dictum varius erat.";
echo wordwrap($str, 50);

Ou Experimente online!


5

JavaScript (ES6),  75 73  72 bytes

Toma entrada como (string)(n).

s=>n=>s.split` `.map(w=>r=(u=r?r+' '+w:w)[n]?(o+=r+`
`,w):u,o=r='')&&o+r

Experimente online!

Variáveis

A saída formatada é armazenada em o (em verde abaixo).

A linha atualizada você é definida como a concatenação de:

  • a linha atual r (em preto abaixo)
  • um espaço se r não estiver vazio ou nada mais (em laranja abaixo)
  • a nova palavra W (em azul abaixo)

Precisamos inserir uma quebra de linha sempre que o n ésimo caractere de você for definido (indexado 0, em vermelho abaixo).

Exemplo

n=16 es = "Lorem Ipsum DOLOR"

Adicionando "LOREM":

0001020304050607080910111213141516euOREM

Adicionando "IPSUM":

0001020304050607080910111213141516euOREMEuPSvocêM

Adicionando "DOLOR":

0001020304050607080910111213141516euOREMEuPSvocêMDOeuOR

0001020304050607080910111213141516euOREMEuPSvocêMDOeuOR


Espaços à direita são permitidos. talvez r+w+' '?
l4m2

5

Perl 6 , 46 29 bytes

{;*.comb(/.**{1..$_}[\s|$]/)}

Experimente online!

Solução baseada em Regex que recebe entrada com curry, gosta f(n)(s)e retorna uma lista de linhas. Cada linha, exceto a última, possui um espaço em branco à direita

Explicação:

{;*                         }   # Anonymous code block that returns a Whatever lambda
   .comb(/                /)    # Split the string by
          .**{1..$_}            # Up to n characters
                    [\s|$]      # Terminated by a whitespace char or the end of the string

4

Vim, 15 bytes / pressionamentos de tecla

DJ:se tw=<C-r>"
gq_

Uma pergunta sobre formatação de texto? Eu sei exatamente a ferramenta para o trabalho! E ainda tem meu nome nas duas primeiras teclas: D

<C-r>meios ctrl-r.

Isso pode ser um pouco mais curto no V , mas eu prefiro responder no vanilla vim para obter respostas que realmente mostrem como o vim conciso pode ser o desafio certo. E a diferença é tão pequena de qualquer maneira.

Também pode ser o seguinte para 15 bytes:

:se tw=<C-r><C-w>
ddgq_

Experimente online!


1
Explicação:: DJ:Este programa foi criado pelo DJ, nosso gato favorito com um diamante no pescoço. [...]
Erik the Outgolfer

4

R , 36 27 bytes

R tem isso como um built-in ( strwrap), retornamos um vetor de linhas de divisão.

function(s,n)strwrap(s,n+1)

Experimente online!


1
Sim, isso deve ser permitido. Matrizes de linhas são permitidas, então não vejo por que isso seria diferente.
ATMunn

4

Haskell , 70 bytes

s!n|length s<=n=[s]|(t,_:d)<-splitAt(until((<'!').(s!!))pred n)s=t:d!n


3

Java (JDK) , 46 44 bytes

Basicamente, uma solução de regex pura em Java, quase certamente a mais curta que já escrevi.

Um brinde a Kevin por ajudar a reduzir ainda mais os bytes no regex!

n->s->s.replaceAll(".{1,"+n+"}( |$)","$0\n")

Experimente online!

Usando um lamdba com caril, ele cria uma regex para corresponder avidamente a ncaracteres seguidos por um espaço ou final de sequência. Em seguida, substitui esses caracteres por si mesmos, seguidos por uma nova linha.


@KevinCruijssen, [ $]na verdade, apenas corresponde a um espaço ou, $se bem me lembro, ao invés do final da string. No entanto, parece funcionar, então parece que ele pode ser jogado em um único espaço por menos bytes.
Luke Stevens

Ah, pode ser apenas um espaço, pois você adiciona novas linhas e não precisa adicionar uma nova linha final no final.
Kevin Cruijssen

1
Você pode obter mais 2 bytes de golfe removendo os parênteses na regex e usar em $0vez de $1.
Kevin Cruijssen

@KevinCruijssen Nice one! É uma pena que replaceAllé tão detalhado!
Luke Stevens

2
Para mim está errado, apareça se eu modificar a frase em latim do exercício da maneira que termina com "... dictum varius abc erat". Existe uma nova linha desnecessária após a letra c ...
RosLuP /

2

Mathematica, 16 bytes

InsertLinebreaks

Função incorporada. Pega uma string e um número inteiro como entrada e retorna uma string como saída.

InsertLinebreaks["string", n]
 insere caracteres de nova linha para não deixar mais que n caracteres.


2

Powershell, 40 83 bytes

Caso de teste n=80adicionado.

param($s,$n)$s-split' '|%{if(($o+$_|% le*)-lt$n){$o+=' '*!!$o+$_}else{$o;$o=$_}}
$o

Script de teste:

$f = {

param($s,$n)$s-split' '|%{if(($o+$_|% le*)-lt$n){$o+=' '*!!$o+$_}else{$o;$o=$_}}
$o

}

@(
,(50, "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed eget erat lectus. Morbi mi mi, fringilla sed suscipit ullamcorper, tristique at mauris. Morbi non commodo nibh. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Sed at iaculis mauris. Praesent a sem augue. Nulla lectus sapien, auctor nec pharetra eu, tincidunt ac diam. Sed ligula arcu, aliquam quis velit aliquam, dictum varius erat.",
"Lorem ipsum dolor sit amet, consectetur adipiscing",
"elit. Sed eget erat lectus. Morbi mi mi, fringilla",
"sed suscipit ullamcorper, tristique at mauris.",
"Morbi non commodo nibh. Pellentesque habitant",
"morbi tristique senectus et netus et malesuada",
"fames ac turpis egestas. Sed at iaculis mauris.",
"Praesent a sem augue. Nulla lectus sapien, auctor",
"nec pharetra eu, tincidunt ac diam. Sed ligula",
"arcu, aliquam quis velit aliquam, dictum varius",
"erat.")
,(80, "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed eget erat lectus. Morbi mi mi, fringilla sed suscipit ullamcorper, tristique at mauris. Morbi non commodo nibh. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Sed at iaculis mauris. Praesent a sem augue. Nulla lectus sapien, auctor nec pharetra eu, tincidunt ac diam. Sed ligula arcu, aliquam quis velit aliquam, dictum varius erat.",
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed eget erat lectus.",
"Morbi mi mi, fringilla sed suscipit ullamcorper, tristique at mauris. Morbi non",
"commodo nibh. Pellentesque habitant morbi tristique senectus et netus et",
"malesuada fames ac turpis egestas. Sed at iaculis mauris. Praesent a sem augue.",
"Nulla lectus sapien, auctor nec pharetra eu, tincidunt ac diam. Sed ligula arcu,",
"aliquam quis velit aliquam, dictum varius erat.")
) | %{
    $n,$s,$expected = $_
    $result = &$f $s $n
    "$result"-eq"$expected"
    # $result   # uncomment this line to dispaly a result
}

Saída:

True
True


Obrigado. O ternário falso é uma expressão. Este script contém um implícito returnna elseparte e uma declaração na thenparte.
Mazzy


2

Japonês , 20 bytes

¸rÈ+Yi[X·ÌY]¸Ê>V?R:S

Experimente online!

Obrigado a Bubbler e Shaggy pela ajuda

Explicação:

¸                       #Split into words
 r                      #For each word, add them to the output in this way:
     i                  # Choose a character using this process:
       X·Ì              #  Get the last line of the output
          Y             #  And the current word
      [    ]¸           #  Join them with a space
             Ê>V?       #  If the resulting line is greater than the allowed length:
                ?R      #   Choose "/n" (newline)
                  :S    #  Otherwise choose " " (space)
     i                  # Add the chosen character to the output
  È+Y                   # Add the current word to the output

24 bytes com [X,Y].join(...).
Bubbler


1

Retina 0.8.2 , 37 bytes

.+$
$*
!`(?=\S.*¶(1)+)(?<-1>.)+(?=\s)

Experimente online! Toma se nem linhas separadas. Explicação:

.+$
$*

Converta npara unário.

(?=\S.*¶(1)+)(?<-1>.)+(?=\s)

Combine os espaços não em branco e, em seguida, olhe para a frente ne conte-os como $#1. Em seguida, volte e use um grupo de equilíbrio para corresponder aos ncaracteres seguidos por espaços em branco.

!`

Produza as correspondências como uma lista de linhas.


Existe uma maneira no Retina de colocar a primeira entrada em um regex que usamos com a segunda entrada? Então, algo como isto: .{1,50} e$0¶ , mas onde 50é recebido como entrada?
21718 Kevin Murrijssen

@KevinCruijssen Na Retina 1, você provavelmente pode usar um estágio Eval para obter um resultado semelhante, mas isso é chato, então eu não me incomodei.
Neil

1

Carvão , 19 bytes

Nθ←F⪪S «¿‹⁺LιⅈθM→⸿ι

Experimente online! Link é a versão detalhada do código. Recebe entrada de ne sem linhas separadas. Explicação:

Nθ

Entrada n.

Mova o cursor para a esquerda um quadrado para equilibrar o movimento certo desde a primeira iteração do loop.

F⪪S «

Divida a string em espaços e faça um loop sobre as palavras.

¿‹⁺Lιⅈθ

Calcule se a próxima palavra alcançará a borda direita.

M→

Caso contrário, mova um quadrado para a direita.

⸿

Se ele iniciar uma nova linha.

ι

Saída a palavra.



1

05AB1E , 18 bytes

õs#vDy«g²›i,}yðJ}?

Experimente online.

Explicação:

õ                   # Push an empty string "" to the stack
 s                  # Swap to take the (implicit) string input
  #                 # Split it by spaces
   v            }   # For-each `y` over the words:
    D               #  Duplicate the top of the stack
                    #  (which is the empty string in the very first iteration)
     y«             #  Append the current word `y`
       g            #  Get its length
        ²›i }       #  If its lengthy is larger than the second input:
           ,        #   Pop and output the current duplicated value with trailing newline
             yð     #  Push the word `y` and a space " "
               J    #  Join the entire stack together
                 ?  # After the loop, output the last part as well (without newline)

1

Java 8, 135 bytes

n->s->{String r="",S[]=s.split(" "),t=r;for(int i=0;i<S.length;)if((t+S[i]).length()>n){r+=t+"\n";t="";}else t+=S[i++]+" ";return r+t;}

Experimente online.

Explicação:

n->s->{                      // Method with integer & String parameters and String return
  String r="",               //  Result-String, starting empty
         S[]=s.split(" "),   //  Input-String split by spaces
         t=r;                //  Temp-String, starting empty as well
  for(int i=0;i<S.length;)   //  Loop `i` in the range [0, amount_of_words):
    if((t+S[i]).length()>n){ //   If `t` and the word are larger than the integer input:
      r+=t+"\n";             //    Add `t` and a newline to the result
      t="";}                 //    And reset `t` to an empty String
     else                    //   Else:
       t+=S[i++]+" ";        //    Append the word and a space to `t`
                             //    (and then increase `i` by 1 with `i++` for the next word
                             //     of the next iteration)
  return r+t;}               //  Return the result-String appended with `t` as result


1

APL (Dyalog Unicode) , SBCS de 14 bytes

Função Infix; argumento da esquerda é n, argumento da direita é n.

CY'dfns'wrap

Experimente online!

⎕CYc op y na biblioteca dfns

 então

wrap[c]  usar o envoltório [n] função

[c]  código dessa função
[n]  notas para essa função


Versão golfada de wrap, 59 bytes SBCS

{⍺≥≢⍵:⍵⋄(t↑⍵),2↓⎕TC,⍺∇⍵↓⍨t+b⊃⍨t←⊃⌽⍺,g/⍨⍺≥g←⍸(⍺+1)↑b' '=⍵}

Experimente online!

{... } dfn; é argumento à esquerda (largura), é argumento à direita (string)

≢⍵ registro (número de caracteres) da sequência

⍺≥: Se a largura for maior ou igual a isso, então:

   retornar a string

 de outra forma:

  ' '=⍵ Máscara booleana em que os espaços em branco são iguais à string

  b← armazenar em b(para b lanks)

  ()↑ Use o seguinte número de elementos:

   ⍺+1 um a mais que a largura

  i ndices onde a verdadeira

  g← armazenar em g(para g aps)

  ⍺≥ Máscara booleana em que a largura é maior ou igual à

  g/⍨ filtrar os índices de gap por esse

  ⍺, acrescente isso à largura

  ⊃⌽ escolha o último elemento disso (lit. escolha o primeiro dos invertidos)

  t← loja em t(para t ake)

  b⊃⍨ use isso para escolher um elemento da máscara de b lanks

  t+ adicione isso a t

  ⍵↓⍨ solte muitos caracteres da string

  ⍺∇ recaia sobre isso com o mesmo argumento à esquerda

  ⎕TC, acréscimo que à lista de t erminal c ontrolo caracteres (8: HT, 10: NL, 13: CR)

  2↓ elimine os dois primeiros caracteres (deixando apenas 13: CR)

  (), Anexa isso ao seguinte:

   t↑⍵ os primeiros tcaracteres da string



0

JavaScript + HTML + CSS, 117 64 bytes

-53 bytes, cortesia de @Neil

n=50
s="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed eget erat lectus. Morbi mi mi, fringilla sed suscipit ullamcorper, tristique at mauris. Morbi non commodo nibh. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Sed at iaculis mauris. Praesent a sem augue. Nulla lectus sapien, auctor nec pharetra eu, tincidunt ac diam. Sed ligula arcu, aliquam quis velit aliquam, dictum varius erat."
f=(n,s)=>document.body.innerHTML+=`<tt><p style=width:${n}ch>${s}`
f(n,s)


1
Pelo menos no meu navegador, você pode reduzir (n,s)=>document.body.innerHTML+=`<p style=width:${n}ch><tt>${s}</tt></p>` para 74 bytes. Se você estiver disposto a desenterrar versões antigas do Firefox, poderá salvar outros 8 bytes com (n,s)=>document.body.innerHTML+=`<pre wrap width=${n}>${s}</pre>` .
Neil

@ Neil Bom uso de chunidades. O Firefox 65 calcula 50chcomo 500px; O Chromium 70 calcula 50chcomo400px
guest271314

Esta resposta está errada. elit. Sed eget erat lectus. Morbi mi mi, fringilla sed(Segunda linha) tem mais de 50 caracteres. Estou usando o Chrome mais recente.
Mbomb007

Consegui ajustar minha sugestão original para trabalhar no Chrome, colocando o <p>interior do <tt>.
Neil



0

C # (.NET Core) , 162 bytes

string[]t(string n,int a){var g="";for(int i=0;i++<Math.Floor((double)n.Length/a);)g+=$"^.{{{i*a-1}}}|";return Regex.Split(n,$@"(?n)(?<=({g.Trim('|')})\S*)\s");}}

Essa função usa um regex que corresponde ao espaço em branco mais próximo que fica perto do enésimo ou múltiplo de enésimo caractere e divide a sequência com base nele.

Experimente online!

O link TIO é um programa completo e a função possui uma palavra-chave estática para que a função possa ser chamada de main.

Regex de teste


Isso não fornece a saída correta para o caso de teste - algumas linhas têm mais de 50 caracteres. Você quer "antes" e não "próximo", e também a divisão em um ponto deve depender de onde foi dividida anteriormente.
Ørjan Johansen

0

C # (compilador interativo do Visual C #) , 78 bytes

s=>n=>System.Text.RegularExpressions.Regex.Replace(s,".{1,"+n+"}( |$)","$0\n")

Experimente online!

O crédito vai para @LukeStevens por ter apresentado a versão Java ... Aparentemente, o .NET faz com que você importe o RegularExpressionsnamespace para fazer uma substituição :(

Aqui está minha versão original que se divide no caractere de espaço e usa o LINQ para juntá-los novamente:

C # (compilador interativo do Visual C #) , 91 bytes

s=>n=>s.Split(' ').Aggregate((a,w)=>a+(a.Length-a.LastIndexOf('\n')+w.Length>n?'\n':' ')+w)

Experimente online!



0

APL (NARS), 48 caracteres, 96 bytes

{⊃⍵{⍺≥≢⍵:⊂⍵⋄k←1+⍺-' '⍳⍨⌽r←⍺↑⍵⋄(⊂k↑r),⍺∇k↓⍵}⍨⍺+1}

teste:

  f←{⊃⍵{⍺≥≢⍵:⊂⍵⋄k←1+⍺-' '⍳⍨⌽r←⍺↑⍵⋄(⊂k↑r),⍺∇k↓⍵}⍨⍺+1}
  s←"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed eget erat lectus. Morbi mi mi, fringilla sed suscipit ullamcorper, tristique at mauris. Morbi non commodo nibh. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Sed at iaculis mauris. Praesent a sem augue. Nulla lectus sapien, auctor nec pharetra eu, tincidunt ac diam. Sed ligula arcu, aliquam quis velit aliquam, dictum varius erat."
  50 f s
Lorem ipsum dolor sit amet, consectetur adipiscing 
elit. Sed eget erat lectus. Morbi mi mi, fringilla 
sed suscipit ullamcorper, tristique at mauris.     
Morbi non commodo nibh. Pellentesque habitant      
morbi tristique senectus et netus et malesuada     
fames ac turpis egestas. Sed at iaculis mauris.    
Praesent a sem augue. Nulla lectus sapien, auctor  
nec pharetra eu, tincidunt ac diam. Sed ligula     
arcu, aliquam quis velit aliquam, dictum varius    
erat.                                              

Eu não sei em "{⊃⍵ {⍺≥≢⍵: ⊂⍵⋄ ..." Se está certo ≥ ou está ali>> ...
RosLuP

0

C, 63 bytes

b(a,n)char*a;{while(strlen(a)>n){for(a+=n;*a-32;--a);*a++=10;}}

A função deste exercício b (a, n) quebraria a linha "a", como o exercício disse, de forma a não alterar seu comprimento (se vemos o resultado como uma sequência), porque alteramos alguns espaços em \ n ou nova linha em Lugar, colocar. A string de entrada "a" também não deve ter nenhum caractere \ n para a função b () (poderia ter \ n na string de entrada para bs ())

A função b (a, n) seria aceitável apenas porque a restrição deste exercício, que impõe cada palavra de "a", tem comprimento <n se isso não for verdade, essa função pode ir
para um loop infinito ... (muito errado no meu modo de ver, então eu copio também a função mais boa porque nesse caso retornaria -1 e não iria para um loop infinito; é bs (a, n) abaixo) não excluo ambas as funções estão com erros .. .

#define R(x,y) if(x)return y
#define U unsigned
U bs(char*a,U n)
{U c,q,r=1,i,j;
 R(!a||n<1||n++>0xFFFF,-1);
 for(j=c=i=0;;++i,++c)
    {R(i==-1,-1);q=a[i];
     if(q==10)goto l;
     if(c>=n){R(i-j>n,-1);a[i=j]=10;l:c=-1;++r;}
     R(!q,r);
     if(q==32)j=i;
    }
}

resultado de b () passado em uma função que adiciona comprimento de linha a cada linha

Lorem ipsum dolor sit amet, consectetur adipiscing [50]
elit. Sed eget erat lectus. Morbi mi mi, fringilla [50]
sed suscipit ullamcorper, tristique at mauris. [46]
Morbi non commodo nibh. Pellentesque habitant [45]
morbi tristique senectus et netus et malesuada [46]
fames ac turpis egestas. Sed at iaculis mauris. [47]
Praesent a sem augue. Nulla lectus sapien, auctor [49]
nec pharetra eu, tincidunt ac diam. Sed ligula [46]
arcu, aliquam quis velit aliquam, dictum varius [47]
erat. [5]

@ceilingcat ok, o código acima também levaria em consideração o \ n ... um bug que encontrei com o código foi que a última linha não foi impressa corretamente ... por que você não escreve sua resposta C como outra? Ele venceria o meu porque é mais curto ... por exemplo, o verdadeiro eu uso a primeira linha (ou instrução ";") para a verificação de entrada apenas porque para mim a entrada precisa ser verificada mesmo que seja um pouco mais grandes; Eu tentei sem sucesso escrever a função em APL ...
RosLuP /

@ceilingcat na última resposta, visto que a pergunta não diz se a string de entrada tem ou não tem '\ n' char e visto que o exemplo não tem '\ n', suponho que a string de entrada não tenha um novo caractere de linha ...
RosLuP

Apenas 83 ... Sim, eu tenho que ver se eu ganho 3 caracteres usando a definição de função antiga ...
RosLuP

Apenas 81 .... .... ....
RosLuP 12/12

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.