Dividi una stringa


23

Sfida

Data una stringa e un numero, dividi la stringa in così tante parti di uguali dimensioni. Ad esempio, se il numero è 3, è necessario dividere la stringa in 3 pezzi, indipendentemente dalla lunghezza della stringa.

Se la lunghezza della stringa non si divide uniformemente nel numero fornito, è necessario arrotondare per difetto le dimensioni di ciascun pezzo e restituire una stringa "rimanente". Ad esempio, se la lunghezza della stringa di input è 13 e il numero è 4, è necessario restituire quattro stringhe ciascuna della dimensione 3, più una stringa rimanente della dimensione 1.

Se non è presente alcun resto, è possibile non restituire semplicemente uno o restituire la stringa vuota.

Il numero fornito è garantito essere inferiore o uguale alla lunghezza della stringa. Ad esempio, l'input "PPCG", 7non avverrà perché "PPCG"non può essere diviso in 7 stringhe. (Suppongo che il risultato corretto sarebbe (["", "", "", "", "", "", ""], "PPCG"). È più semplice non consentire questo come input.)

Come al solito, l'I / O è flessibile. È possibile restituire una coppia di stringhe e la stringa del resto o un elenco di stringhe con il resto alla fine.

Casi test

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

punteggio

Questo è , quindi vince la risposta più breve in ogni lingua.

Punti bonus (non proprio 😛) per rendere la tua soluzione effettivamente utilizza l'operatore di divisione della tua lingua.


1
Punti bonus? Oh uomo, devo farlo
Matthew Roh,


Correlati , ma nessuna delle due parti è la stessa di questa sfida.
musicman523

Per rendere più chiaro, aggiungi una testcase PPCG, 7quindi il resto èPPCG
Jörg Hülsermann,

@ JörgHülsermann Quell'input non è consentito. Ho aggiunto ulteriori dettagli relativi a quel tipo di input e riformattato le cose per essere più chiari.
musicman523

Risposte:



5

PHP> = 7,1, 75 byte

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

Casi test

PHP> = 7.1, 52 byte

stampa solo il resto

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

Casi test


5

seme , 21 byte

20 byte di codice, +1 per la -nbandiera.

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

Accetta input come argomenti della riga di comando; stringhe di output e resto separato da nuova riga.Provalo online!

Spiegazione

Divertimento con le operazioni regex!

Prendiamo abcdefgcome nostra stringa e 3come il nostro numero. Costruiamo la regex (.{2})(.{2})(.{2}), che corrisponde a tre serie di due personaggi e le memorizza in tre gruppi di acquisizione. Quindi, usando le variabili di corrispondenza regex di Pip, possiamo stampare 1) l'elenco dei gruppi di acquisizione ["ab";"cd";"ef"]e 2) il resto della stringa che non è stata trovata "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 byte

#è un operatore che prende a Stringe an Inte restituisce un elenco diString s.

Usa come "Hello, world!"#4.

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

Provalo online!

Come funziona

  • sè la stringa di input ed nè il numero di pezzi non rimanenti.
  • dè la lunghezza di ogni pezzo "normale". divè divisione intera.
  • La comprensione dell'elenco costruisce n+1pezzi, l'ultimo è il resto.
    • iscorre da 0a n, compreso.
    • Per ogni pezzo, prima la giusta quantità ( i*d) di caratteri iniziali è dropped dall'inizio s, quindi una sottostringa iniziale è taken dal risultato.
    • La lunghezza della sottostringa dovrebbe essere d, ad eccezione del pezzo rimanente.
      • Il resto effettivo deve essere più corto di n, altrimenti si allungerebbero invece i pezzi normali.
      • takerestituisce l'intera stringa se la lunghezza fornita è troppo grande, quindi possiamo usare qualsiasi numero >=n-1per il resto.
      • L'espressione d+n*0^(n-i)dse i<ne d+nse i==n. Esso utilizza che 0^xè 1quando x==0, ma 0se x>0.

Dovrò cercare dove posso usare la comprensione dell'elenco.
qfwfq,

4

Python 2 , 68 67 65 byte

  • @ musicman123 salvato 2 byte: output senza racchiudere []
  • Grazie a @Chas Brown per 1 byte: x[p*i:p+p*i]comex[p*i][:p]
def f(x,n):p=len(x)/n;print[x[p*i:][:p]for i in range(n)],x[p*n:]

Provalo online!


1
Salva 1 byte sostituendo x[p*i:p+p*i]conx[p*i:][:p]
Chas Brown il

1
+1 per :p😛 Ben fatto superando le altre risposte di Python!
musicman523

Haha .. che non era affatto previsto ....: p
officialaimm,

1
Questa risposta ora è stata superata
musicman523

4

C ++ 14, 209 180 byte

È un po 'troppo lungo, ma utilizza l'operatore di divisione:

#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;

Versione online: http://ideone.com/hbBW9u


4

Pyth, 9 byte

cz*L/lzQS

Provalo online

Come funziona

Il primo Qviene autoinizializzato eval(input())e zviene autoinizializzato 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

Ruggine , 107 byte

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..])}

Provalo online!

formattato:

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..])
}

Questo semplicemente maps indici sulle sezioni corrette della sorgente str( collecting in a Vec) e suddivide il resto.

Sfortunatamente, non posso renderlo una chiusura (74 byte):

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

poiché il compilatore fallisce

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 fornisco il tipo di s:&str, le vite sono sbagliate:

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 byte

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

O^$`.

¶1+$

O^$`.

Provalo online! Spiegazione: Il primo stadio converte il numero di parti in unario e prende anche la lunghezza della stringa. Il secondo stadio quindi divide la lunghezza per il numero di parti, lasciando qualsiasi residuo. Il terzo stadio moltiplica nuovamente il risultato per il numero di parti. Questo ci dà il numero corretto di stringhe della lunghezza corretta, ma non hanno ancora il contenuto. Il numero di parti può ora essere eliminato dalla quarta fase. Il quinto stadio inverte tutti i personaggi. Ciò ha l'effetto di cambiare il contenuto originale con le stringhe segnaposto, ma sebbene sia ora nel posto giusto, è nell'ordine inverso. I segnaposto hanno servito al loro scopo e sono eliminati dalla sesta fase. Finalmente il settimo livello riporta i personaggi nel loro ordine originale.


3

Perl 6 , 36 byte

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

Provalo online!

Restituisce un elenco di elenchi di stringhe, in cui l'ultimo elemento è il resto (se presente).

Spiegazione:

{                                  }  # 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 byte

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

Restituisce una matrice di due elementi: le parti di stringa divise e la parte rimanente.

Test dello snippet

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

Japt , 18 byte

¯W=Ul fV)òW/V pUsW

Provalo online! (usa -Qflag per visualizzare l'output)

Spiegazione

¯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]

Try it online!


Welcome to PPCG! I added a "Try it online" link to your post. I think you can slightly shorten your solution by making it a full program rather than a function. Try it online!
musicman523

2

05AB1E, 12 bytes

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

Try it online!

Explanation

²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 by reversing the input-order.
Kevin Cruijssen

2

Brachylog, 16 bytes

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

Try it online!

Takes input as a list [string, number] and outputs as a list [remainder, parts]. (Commas were replaced with semicolons in the "Hello, world!" test cases for clarity, since the string fragments don't get printed with quotes.)

                    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.

(I also replaced a comma in the code with a semicolon for a consistent output format. With the comma, cases with no remainder would just output the parts without an empty remainder, and as nice as that is for some purposes, I don't actually know why it works that way...)

After this came out to be a whole 16 bytes, I tried to make something based on +₁ᵗ⟨ġl⟩ work, but as the fixes got longer and longer I decided that I would just stick with my original solution for now.



2

Excel Formula, 185 173 165 161 149 bytes

The following should be entered as an array formula (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))))

Where A1 contains your input (e.g. 12345678) and B1 contains the divisor. This also uses Excel's division operator for a bonus.

After entering the formula as an array formula, highlight it in the formula bar and evaluate it using F9 to return the result, for example:

Excel formula evaluation showing split groups

-12 bytes: replace each INDIRECT("1:"&B1+1) with OFFSET(A1,,,B1+1) to save 2 bytes per occurence, plus some tidying removing redundant brackets.

-8 bytes: remove redundant INDEX function.

-4 bytes: rework "remainder" handling.

-12 bytes: remove redundant INT(LEN(A1)/B1) by offsetting array generated by ROW(OFFSET(A1,,,B1+1)) by -1.




1

Mathematica, 58 bytes

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

Pure function taking a list of characters and a positive integer as input. For example, the last test case is called by

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

and returns:

{{{"1"}, {"2"}, {"3"}, {"4"}}, {"5", "6", "7"}}

1

Haskell, 120 88 bytes (thanks to Ørjan Johansen!)

Does div count as the division operator?

I am curious how I could cut this down, I haven't learned all the tricks yet.

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
A quick rewrite with the most basic tricks: 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). So, (1) A repeatedly used identifier may be abbreviated, especially if it's long. (2) Guards and pattern guards are almost always shorter than let ... in, where and if then else. (3) Pattern matching is often better than equality testing. (OK, that let in a pattern guard isn't that basic, I recently learned it from someone else here.) And check out codegolf.stackexchange.com/questions/19255/… .
Ørjan Johansen

1
Also, take a look at Tips for golfing in Haskell for some useful tricks.
sudee

@ØrjanJohansen Thanks! I forgot that semicolons were valid, and that let in the guard is pretty devious. But shorter code is more readable, right?
qfwfq

1

Ohm, 3 bytes (non-competing?)

lvσ

Non competing because the built-in isn't implemented yet in TIO and i have no PC handy to test whether it works in the latest pull in the repo.

Built-in ¯\\_(ツ)_/¯. I used the wrong built-in... But hey there is still an other one laying around. Now I used the wrong built-in two times (or one built-in works wrong with remainders).

Do I get bonus points because v is (floor) division?


1
This doesn't split in the way required. e.g. the Hello, world! 5 testcase is wrong. Try it online!
Ørjan Johansen

Well I'm going to look for another built-in....
Roman Gräf

1

CJam, 16 bytes

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

Anonymous block expecting the arguments on the stack and leaves the result on the stack after.

Try it online!

Explanation

Expects arguments as 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-(|#)

Apart from elminating spaces and intermediate steps, this hasn't been golfed. I expect that I've taken the long way somehow, what with my parentheses and argument references ([ and ]).

See Jupyter notebook for test cases, such as the following:

   5 chunk test2
┌──┬───┐
│He│ld!│
│ll│   │
│o,│   │
│ w│   │
│or│   │
└──┴───┘

Thanks. Read too fast. Comment removed
Jonah

1

R, 79 63 bytes

-16 from Giuseppe fixing the indexing

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

Try it online!

Built around giving vector inputs to substring()


63 bytes -- simplified the indexing a bit.
Giuseppe

@Giuseppe Haha, I must have tried every variant of adding and multiplying on the index, but missed that one. Good catch.
CriminallyVulgar

0

PHP, 152 bytes

Thanks @JörgHülsermann (brackets tip!)

$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);

Try it online!


1
Your PHP Way doesn't work cause it replaces not only at the beginning. preg_replace is an alternative or you can use [,$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

Can you explain me with a example code why doesn't work my PHP code ?
kip

1
Try it online! It replaces all A in the first run
Jörg Hülsermann

1
You can drop the array_walk construct if you use brackets Try it online!
Jörg Hülsermann

Nice tip ! I totally forgot
kip


0

PowerShell v3+, 72, 80 bytes

Assumes $s contains the input string; $n contains the number of characters per "piece". This also assumes that "StrictMode" is off. Otherwise, an error would be returned because of indexing further into an array than actually exists (i.e. if array has 4 elements and i call the non-existent 5th element). With StrictMode off, PS doesn't care and it'll ignore the error.

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

Using notation ($s|% ToCharA*) i was able to save 1 character compared to $s.ToCharArray() : )

Update:

Updated code to actually satisfy challenges requirements. Again assumes $s contains the input string; however, this time $n contains the number of "pieces". The remainder is printed out last. And i used PowerShell's division operator

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

Try it online!


I believe you've misunderstood the question, the input is the number of pieces (excluding remainder).
Ørjan Johansen

Oh, you're right. I mis-read the question last night : ) I'll post my updated solution when i have a chance.
GAT
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.