Divida uma string

23

Desafio

Dada uma sequência e um número, divida a sequência em várias partes do mesmo tamanho. Por exemplo, se o número for 3, você deve dividir a sequência em 3 partes, independentemente do comprimento da sequência.

Se o comprimento da corda não se dividir igualmente no número fornecido, você deve arredondar para baixo o tamanho de cada peça e retornar uma corda "restante". Por exemplo, se o comprimento da string de entrada for 13 e o número for 4, você deverá retornar quatro strings cada uma do tamanho 3, mais uma string restante do tamanho 1.

Se não houver resto, você pode simplesmente não retornar um ou retornar a string vazia.

É garantido que o número fornecido seja menor ou igual ao comprimento da sequência. Por exemplo, a entrada "PPCG", 7não ocorrerá porque "PPCG"não pode ser dividida em sete cadeias. (Suponho que o resultado correto seria (["", "", "", "", "", "", ""], "PPCG"). É mais fácil simplesmente não permitir isso como entrada.)

Como de costume, a E / S é flexível. Você pode retornar um par de strings e o restante, ou uma lista de strings com o restante no final.

Casos de teste

"Hello, world!", 4 -> (["Hel", "lo,", " wo", "rld"], "!") ("!" is the remainder)
"Hello, world!", 5 -> (["He", "ll", "o,", " w", "or"], "ld!")
"ABCDEFGH", 2 -> (["ABCD", "EFGH"], "") (no remainder; optional "")
"123456789", 5 -> (["1", "2", "3", "4", "5"], "6789")
"ALABAMA", 3 -> (["AL", "AB", "AM"], "A")
"1234567", 4 -> (["1", "2", "3", "4"], "567")

Pontuação

Isso é , então a resposta mais curta em cada idioma vence.

Pontos de bônus (não realmente 😛) por tornar sua solução realmente usar o operador de divisão do seu idioma.

musicman523
fonte
1
Pontos bônus? Oh homem que eu tenho que fazer isso
Matthew Roh
Para o bônus, Jelly, 3 bytes;⁹/
Jonathan Allan
Relacionado , mas nenhuma parte é igual a este desafio.
musicman523
Para tornar mais claro por favor adicione uma testcase PPCG, 7de modo que o restante éPPCG
Jörg Hülsermann
@ JörgHülsermann Essa entrada não é permitida. Eu adicionei mais detalhes referentes a esse tipo de entrada e reformatei as coisas para ficar mais claro.
precisa

Respostas:

6

Python 2 , 63 bytes

s,n=input()
b=len(s)/n
while n:print s[:b];s=s[b:];n-=1
print s

Experimente online!

ovs
fonte
Bem feito! Realmente não acho que isso possa ser jogado mais.
musicman523
5

PHP> = 7.1, 75 bytes

[,$s,$d]=$argv;print_r(preg_split('/.{'.(strlen($s)/$d^0).'}\K/',$s,$d+1));

Casos de teste

PHP> = 7.1, 52 bytes

imprima apenas o restante

[,$s,$d]=$argv;echo substr($s,(strlen($s)/$d^0)*$d);

Casos de teste

Jörg Hülsermann
fonte
5

Pip , 21 bytes

20 bytes de código, +1 para -nsinalizador.

a~C(#a//b*XX)XbP$$$'

Recebe entradas como argumentos de linha de comando; produz strings e o restante é separado por nova linha. Experimente online!

Explicação

Diversão com operações regex!

Vamos tomar abcdefgcomo nossa string e 3como nosso número. Construímos a regex (.{2})(.{2})(.{2}), que corresponde a três execuções de dois caracteres e as armazena em três grupos de captura. Em seguida, usando as variáveis ​​de correspondência de regex do Pip, podemos imprimir 1) a lista de grupos de captura ["ab";"cd";"ef"]e 2) o restante da sequência que não foi correspondida "g".

                      a,b are cmdline args; XX is the regex `.` (match any one character)
    #a//b             Len(a) int-divided by b: the length of each chunk
         *XX          Apply regex repetition by that number to `.`, resulting in something
                        that looks like `.{n}`
  C(        )         Wrap that regex in a capturing group
             Xb       Repeat the whole thing b times
a~                    Match the regex against a
               P$$    Print $$, the list of all capture groups (newline separated via -n)
                  $'  Print $', the portion of the string after the match
DLosc
fonte
5

Haskell , 62 bytes

#é um operador pegando ae Stringan Inte retornando uma lista de Strings.

Use como "Hello, world!"#4.

s#n|d<-length s`div`n=[take(d+n*0^(n-i))$drop(i*d)s|i<-[0..n]]

Experimente online!

Como funciona

  • sé a sequência de entrada e né o número de partes não restantes.
  • d é o comprimento de cada peça "normal". divé divisão inteira.
  • A compreensão da lista constrói n+1 peças, sendo o último o restante.
    • i itera de 0 para n, inclusive.
    • Para cada peça, primeiro a quantidade certa ( i*d) de caracteres iniciais é dropcalculada desde o início des , então uma substring inicial é taken a partir do resultado.
    • O comprimento da substring utilizado deve ser d , exceto a peça restante.
      • O restante real deve ser menor que n , caso contrário, as peças normais seriam alongadas.
      • take retorna a string inteira se o comprimento fornecido for muito grande, para que possamos usar qualquer número >=n-1 para a peça restante.
      • A expressão d+n*0^(n-i)fornece dse i<ne d+nse i==n. Usa que 0^xé 1quando x==0, mas 0se x>0.
Ørjan Johansen
fonte
Precisarei observar onde posso usar a compreensão da lista.
Qfwfq 01/07/19
4

Python 2 , 68 67 65 bytes

  • @ musicman123 salvou 2 bytes: saída sem anexar com []
  • Obrigado a @Chas Brown por 1 byte: x[p*i:p+p*i]comox[p*i][:p]
def f(x,n):p=len(x)/n;print[x[p*i:][:p]for i in range(n)],x[p*n:]

Experimente online!

officialaimm
fonte
1
Economize 1 byte substituindo x[p*i:p+p*i]porx[p*i:][:p]
Chas Brown
1
+1 por :p😛 Bem feito, superando as outras respostas do Python!
musicman523
Haha .. isso não foi intencional ...: p
officialaimm
1
Esta resposta foi excluída
musicman523
4

C ++ 14, 209 180 bytes

Isso é um pouco longo, mas usa o operador de divisão:

#include<bits/stdc++.h>
using q=std::string;using z=std::vector<q>;z operator/(q s,int d){int p=s.length()/d,i=0;z a;for(;i<d+1;){a.push_back(s.substr(i++*p,i^d?p:-1));}return a;}

Uso:

vector<string> result = string("abc")/3;

Versão online: http://ideone.com/hbBW9u

Ra8
fonte
4

Pitão, 9 bytes

cz*L/lzQS

Experimente online

Como funciona

Primeiro Qé autoinicializado para eval(input())e zé autoinicializado para input().

cz*L/lzQSQ
     lz      length of z
    /  Q     integer division by Q
  *L         times every element of
        SQ       [1, 2, …, Q]
cz           chop z at those locations
Anders Kaseorg
fonte
3

Gelatina , 11 bytes

Ld⁹x,1$}R⁸ṁ

Experimente online!

Dennis
fonte
Falha para o "123456789", 5 testcase
Ørjan Johansen
Completamente interpretou mal o desafio. Obrigado!
Dennis
3

Ferrugem , 107 bytes

fn f(s:&str,n:usize)->(Vec<&str>,&str){let c=s.len()/n;((0..n).map(|i|&s[i*c..i*c+c]).collect(),&s[c*n..])}

Experimente online!

Formatado:

fn q129259(s: &str, n: usize) -> (Vec<&str>, &str) {
    let c = s.len() / n;
    ((0..n).map(|i| &s[i * c..i * c + c]).collect(), &s[c * n..])
}

Isso simplesmente maps índices nas fatias corretas da fonte str( collectem umVec ) e corta o restante.

Infelizmente, não posso fazer um fechamento (74 bytes):

|s,n|{let c=s.len()/n;((0..n).map(|i|&s[i*c..i*c+c]).collect(),&s[c*n..])}

como o compilador falha com

error: the type of this value must be known in this context
 --> src\q129259.rs:5:18
  |
5 |          let c = s.len() / n;
  |                  ^^^^^^^

e se eu fornecer o tipo de s:&str, as vidas estão erradas:

error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in function call due to conflicting requirements
 --> src\q129259.rs:6:27
  |
6 |          ((0..n).map(|i| &s[i * c..i * c + c]).collect(), &s[c * n..])
  |                           ^^^^^^^^^^^^^^^^^^^
  |
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the body at 4:18...
 --> src\q129259.rs:4:19
  |
4 |       (|s: &str, n| {
  |  ___________________^
5 | |          let c = s.len() / n;
6 | |          ((0..n).map(|i| &s[i * c..i * c + c]).collect(), &s[c * n..])
7 | |      })(s, n)
  | |______^
note: ...so that reference does not outlive borrowed content
 --> src\q129259.rs:6:27
  |
6 |          ((0..n).map(|i| &s[i * c..i * c + c]).collect(), &s[c * n..])
  |                           ^
note: but, the lifetime must be valid for the lifetime 'a as defined on the body at 3:58...
 --> src\q129259.rs:3:59
  |
3 |   fn q129259<'a>(s: &'a str, n: usize) -> (Vec<&str>, &str) {
  |  ___________________________________________________________^
4 | |     (|s: &str, n| {
5 | |          let c = s.len() / n;
6 | |          ((0..n).map(|i| &s[i * c..i * c + c]).collect(), &s[c * n..])
7 | |      })(s, n)
8 | | }
  | |_^
note: ...so that expression is assignable (expected (std::vec::Vec<&'a str>, &'a str), found (std::vec::Vec<&str>, &str))
 --> src\q129259.rs:4:5
  |
4 | /     (|s: &str, n| {
5 | |          let c = s.len() / n;
6 | |          ((0..n).map(|i| &s[i * c..i * c + c]).collect(), &s[c * n..])
7 | |      })(s, n)
  | |_____________^
CAD97
fonte
3

Retina , 92 bytes

(.+)¶(.+)
$2$*1¶$.1$*1¶$1
(1+)¶(\1)+
$1¶$#2$*1¶
\G1(?=1*¶(1+))
$1¶
¶¶1+

O^$`.

¶1+$

O^$`.

Experimente online! Explicação: O primeiro estágio converte o número de partes em unário e também leva o comprimento da sequência. O segundo estágio divide o comprimento pelo número de partes, deixando o restante. O terceiro estágio multiplica o resultado pelo número de peças novamente. Isso nos dá o número correto de strings do comprimento correto, mas elas ainda não têm o conteúdo. O número de peças agora pode ser excluído no quarto estágio. O quinto estágio inverte todos os personagens. Isso tem o efeito de alternar o conteúdo original com as cadeias de espaço reservado, mas, embora agora esteja no lugar certo, está na ordem inversa. Os espaços reservados cumpriram seu objetivo e são excluídos pela sexta etapa. Finalmente, o sétimo estágio reverte os personagens de volta à sua ordem original.

Neil
fonte
3

Perl 6 , 36 bytes

{$^a.comb.rotor($a.comb/$^b xx$b,*)}

Experimente online!

Retorna uma lista de listas de strings, onde o último elemento é o restante (se houver um).

Explicação:

{                                  }  # Anonymous code block
 $^a.comb                             # Split the string into a list of chars
         .rotor(                  )   # And split into
                            xx$b      # N lists
                $a.comb/$^b           # With string length/n size
                                ,*    # And whatever is left over  
Brincadeira
fonte
2

JavaScript (ES6), 77 bytes

(s,d,n=s.length)=>[s.match(eval(`/.{${n/d|0}}/g`)).slice(0,d),s.slice(n-n%d)]

Retorna uma matriz de dois elementos: as partes da string dividida e a parte restante.

Snippet de teste

f=
(s,d,n=s.length)=>[s.match(eval(`/.{${n/d|0}}/g`)).slice(0,d),s.slice(n-n%d)]
<div oninput="O.innerHTML=I.value&&J.value?JSON.stringify(f(I.value,+J.value)):''">String: <input id=I> Number: <input id=J size=3></div>
<pre id=O>

Justin Mariner
fonte
2

Japonês , 18 bytes

¯W=Ul fV)òW/V pUsW

Teste online! (usa -Qsinalizador para visualizar a saída)

Explicação

¯W=Ul fV)òW/V pUsW  : Implicit: U = input string, V = input integer
   Ul fV            : Floor U.length to a multiple of V.
 W=                 : Assign this value to variable W.
¯       )           : Take the first W characters of U (everything but the remainder).
         òW/V       : Partition this into runs of length W / V, giving V runs.
              pUsW  : Push the part of U past index W (the remainder) to the resulting array.
                    : Implicit: output result of last expression
ETHproductions
fonte
2

Python, 82 76 74 bytes

def G(h,n):l=len(h);r=l/n;print[h[i:i+r]for i in range(0,n*r,r)],h[l-l%n:]

Bem, parece que isso se qualifica para os pontos de bônus. Em vez disso, posso receber um cookie? Oh espera, eles não são reais? Caramba ...

Experimente Online!

R. Kap
fonte
1
Você prefere um cookie ou economiza 6 bytes fatorandolen(h) ? :)
musicman523
2

Python, 95, 87, 76 73 bytes

def f(s,n):
 a=[];i=len(s)/n
 while n:a+=s[:i],;s=s[i:];n-=1
 print a+[s]

Experimente online!

Ankit
fonte
Bem-vindo ao PPCG! Adicionei um link "Experimente online" à sua postagem. Eu acho que você pode diminuir um pouco sua solução, tornando-a um programa completo e não uma função. Experimente online!
musicman523
2

05AB1E , 12 bytes

²g¹‰`s¹.D)R£

Experimente online!

Explicação

²g¹‰`s¹.D)R£
²g           # Push length of string
  ¹          # Push amount of pieces
   ‰         # divmod of the two
    `s       # Flatten the resulting array and flip it around
      ¹.D    # Repeat the resulting length of the pieces amount of pieces times(wow that sounds weird)
         )   # Wrap stack to array
          R  # Reverse (so the remainder is at the end)
           £ # Split the input string into pieces defined by the array
Datboi
fonte
1
9 bytes , revertendo a ordem de entrada.
Kevin Cruijssen
2

Braquilog , 16 bytes

kʰ↙Xḍ₎Ylᵛ&ht↙X;Y

Experimente online!

Pega entrada como uma lista [string, number]e sai como uma lista [remainder, parts]. (Vírgulas foram substituídas por ponto e vírgula nos casos de teste "Olá, mundo!" Para maior clareza, pois os fragmentos de sequência não são impressos com aspas.)

                    The input
 ʰ                  with its first element
k ↙X                having the last X elements removed
    ḍ               and being cut into a number of pieces
     ₎              where that number is the last element of the input
      Y             is Y
       lᵛ           the elements of which all have the same length,
         &          and the input
          h         's first element
           t↙X      's last X elements
              ;     paired with
               Y    Y
                    are the output.

(Também substituí uma vírgula no código por um ponto-e-vírgula para um formato de saída consistente. Com a vírgula , os casos sem resto apenas produziriam as partes sem um restante vazio e, por mais legal que seja para alguns propósitos, não realmente sei por que funciona dessa maneira ...)

Depois de 16 bytes, tentei criar algo com base no +₁ᵗ⟨ġl⟩trabalho, mas, conforme as correções aumentavam cada vez mais, decidi que continuaria usando minha solução original por enquanto.

String não relacionada
fonte
2

C (gcc), 72 bytes

d;f(s,n)char*s;{for(d=strlen(s)/n;n--;puts(""))s+=write(1,s,d);puts(s);}

Experimente Online

Johan du Toit
fonte
2

Fórmula do Excel, 185 173 165 161 149 bytes

O seguinte deve ser inserido como uma fórmula de matriz ( Ctrl+ Shift+ Enter):

=MID(A1,(ROW(OFFSET(A1,,,B1+1))-1)*INT(LEN(A1)/B1)+1,INT(LEN(A1)/B1)*ROW(OFFSET(A1,,,B1+1))/IF(ROW(OFFSET(A1,,,B1+1))=B1+1,1,ROW(OFFSET(A1,,,B1+1))))

Onde A1contém sua entrada (por exemplo 12345678) e B1contém o divisor. Isso também usa o operador de divisão do Excel para um bônus.

Depois de inserir a fórmula como uma fórmula de matriz, destaque-a na barra de fórmulas e avalie-a usando F9para retornar o resultado, por exemplo:

Avaliação da fórmula do Excel mostrando grupos divididos

-12 bytes: substitua cada um INDIRECT("1:"&B1+1)por OFFSET(A1,,,B1+1)para salvar 2 bytes por ocorrência, além de alguns ajustes, removendo colchetes redundantes.

-8 bytes: remove a INDEXfunção redundante .

-4 bytes: retrabalho a manipulação "restante".

-12 bytes: remova redundante INT(LEN(A1)/B1)deslocando a matriz gerada ROW(OFFSET(A1,,,B1+1))por -1.

i_saw_drones
fonte
1

Python 2 , 77 76 bytes

-1 byte graças a musicman523.

def f(s,n):l=len(s);print[s[i:i+l/n]for i in range(0,l-n+1,l/n)]+[s[l-l%n:]]

Experimente online!

totalmente humano
fonte
1
Este é um byte mais curto como uma função. Experimente online!
musicman523
1

Mathematica, 58 bytes

{#~Partition~a,#2}&@@TakeDrop[#,(a=Floor[Length@#/#2])#2]&

Função pura, tendo como entrada uma lista de caracteres e um número inteiro positivo. Por exemplo, o último caso de teste é chamado por

{#~Partition~a,#2}&@@TakeDrop[#,(a=Floor[Length@#/#2])#2]&[{"1","2","3","4","5","6","7"},4]

e retorna:

{{{"1"}, {"2"}, {"3"}, {"4"}}, {"5", "6", "7"}}
Greg Martin
fonte
1

Haskell, 120 88 bytes (graças a Ørjan Johansen!)

Faz div como o operador da divisão?

Estou curioso para saber como resolver isso, ainda não aprendi todos os truques.

q=splitAt;x!s|n<-div(length s)x,let g""=[];g s|(f,r)<-q n s=f:g r,(a,b)<-q(n*x)s=(g a,b)
qfwfq
fonte
2
Uma reescrita rápida com a maioria dos truques básicos: t=splitAt;x!s|n<-div(length s)x,let g""=[];g s|(f,r)<-t n s=f:g r,(a,b)<-t(n*x)s=(g a,b). Portanto, (1) Um identificador usado repetidamente pode ser abreviado, especialmente se for longo. (2) Protetores e protetores de padrões são quase sempre menores que let... in, wheree if then else. (3) A correspondência de padrões geralmente é melhor que o teste de igualdade. (OK, que letem um protetor de padrões não é tão básico, eu aprendi recentemente com outra pessoa aqui.) E confira codegolf.stackexchange.com/questions/19255/… .
Ørjan Johansen
1
Além disso, dê uma olhada em Dicas para jogar golfe em Haskell para alguns truques úteis.
Sudee
@ ØrjanJohansen Obrigado! Esqueci que o ponto e vírgula era válido e que letna guarda é bastante desonesto. Mas código mais curto é mais legível, certo?
Qfwfq 01/07/19
1

Ohm, 3 bytes (não concorrente?)

lvσ

Não concorrente porque o built-in ainda não foi implementado no TIO e não tenho um PC à mão para testar se ele funciona na última versão do repositório.

Incorporado ¯ \\ _ (ツ) _ / ¯. Eu usei o built-in errado ... Mas ei, ainda há outro por aí.Agora eu usei o built-in errado duas vezes (ou um interno funciona errado com os restantes).

Recebo pontos de bônus porque vé a divisão (do piso)?

Roman Gräf
fonte
1
Isso não se divide da maneira necessária. por exemplo, o Hello, world! 5testcase está errado. Experimente online!
Ørjan Johansen
Bem, eu vou procurar outro embutido ....
Roman Gräf
1

CJam , 16 bytes

{_,2$//_2$<@@>s}

Bloco anônimo esperando os argumentos na pilha e deixa o resultado na pilha depois.

Experimente online!

Explicação

Espera argumentos como number "string".

_,              e# Copy the string and get its length.
  2$            e# Copy the number.
    /           e# Integer divide the length by the number.
     /          e# Split the string into slices of that size.
      _         e# Copy the resulting array.
       2$       e# Copy the number.
         <      e# Slice the array, keeping only the first <number> elements.
          @@    e# Bring the number and original array to the top.
            >   e# Slice away the first <number> elements,
             s  e# and join the remaining elements into a string.
Gato de negócios
fonte
1

J , 26 bytes

(]$~[,(<.@%~#));]{.~0-(|#)

Além de espaços elminantes e etapas intermediárias, isso ainda não foi jogado. Espero que tenha percorrido o longo caminho de alguma forma, com meus parênteses e referências a argumentos ( [e] ).

Consulte o notebook Jupyter para ver os casos de teste, como os seguintes:

   5 chunk test2
┌──┬───┐
│He│ld!│
│ll│   │
│o,│   │
│ w│   │
│or│   │
└──┴───┘
dinamarquês
fonte
Obrigado. Leia rápido demais. Comentário removido
Jonah
1

R , 79 63 bytes

-16 de Giuseppe corrigindo a indexação

function(s,n,k=nchar(s),l=k%/%n)substring(s,0:n*l+1,c(1:n*l,k))

Experimente online!

Construído para fornecer entradas vetoriais para substring()

CriminallyVulgar
fonte
63 bytes - simplificou um pouco a indexação.
Giuseppe
@ Giuseppe Haha, eu devo ter tentado todas as variantes de adição e multiplicação no índice, mas perdi essa. Boa pegada.
CriminallyVulgar
0

PHP , 152 bytes

Obrigado @ JörgHülsermann (dica de colchetes!)

$c=$s=explode('|',readline());
while($s[1]--)$s[0]=preg_replace('/^'.($l[]=substr($s[0],0,strlen($c[0])/$c[1])).'/','',$s[0]);
$l[r]=$s[0];
print_r($l);

Experimente online!

kip
fonte
1
Seu PHP Way não funciona porque ele substitui não apenas no começo. preg_replaceé uma alternativa ou você pode usar[,$s,$d]=$argv;print_r(array_slice(str_split($s,$l=strlen($s)/$d^0),0,$d)+[$d=>substr($s,$l*$d)]);
Jörg Hülsermann 2/17/17
Você pode me explicar com um código de exemplo por que não funciona meu código PHP?
Kip
1
Experimente online! Ele substitui tudo Ana primeira corrida
Jörg Hülsermann
1
Você pode descartar a construção array_walk se usar colchetes Experimente online!
Jörg Hülsermann 02/07/2017
Boa dica! Eu esqueci totalmente
kip
0

Python 3 , 94 bytes

i=input().split('|')
s,n=i[0],int(i[1])
c=len(s)//n
while n:print(s[:c]);s=s[c:];n-=1
print(s)

Experimente online!

kip
fonte
Assumir que a entrada está em uma variável não é um método de entrada válido .
Ørjan Johansen
O que significa isso Como de costume, a E / S é flexível. ? De qualquer forma, obrigado, eu editar a minha resposta ...
Kip
1
Os métodos padrão do PPCG são bastante flexíveis. Apenas não tanto assim.
Ørjan Johansen
0

PowerShell v3 + , 72 , 80 bytes

Supõe que $scontém a sequência de entrada; $ncontém o número de caracteres por "peça". Isso também pressupõe que "StrictMode" está desativado. Caso contrário, um erro seria retornado devido à indexação adicional em uma matriz do que realmente existe (ou seja, se a matriz tiver 4 elementos e eu chamar o quinto elemento inexistente). Com o StrictMode desativado, o PS não se importa e ignora o erro.

for($i = 0;$i -le $s.Length;$i+=$n+1){-join($s|% ToCharA*)[$i..($i+$n)]}

Usando a notação, ($s|% ToCharA*)pude salvar 1 caractere em comparação com$s.ToCharArray() :)

Atualizar:

Código atualizado para realmente satisfazer os requisitos dos desafios. Novamente assume que $scontém a string de entrada; no entanto, esse tempo $ncontém o número de "peças". O restante é impresso por último. E eu usei o operador de divisão do PowerShell

0..($n-1)|%{$p=[math]::Floor($s.length/$n)}{$s|% Su*($_*$p) $p}{$s|% Su*($n*$p)}

Experimente online!

GAT
fonte
Eu acredito que você entendeu mal a pergunta, a entrada é o número de peças (excluindo o restante).
Ørjan Johansen
Oh, você está certo. Eu li mal a pergunta ontem à noite:) Vou postar minha solução atualizada quando tiver uma chance.
GAT