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.


1
Pontos bônus? Oh homem que eu tenho que fazer isso
Matthew Roh


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:




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

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.

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!


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


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


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)
  | |_____________^

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.


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  

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>


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


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!


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

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.



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.




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"}}

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)

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)?


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.

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│   │
└──┴───┘

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()


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!


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

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!


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
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.