Divisez une chaîne


23

Défi

Étant donné une chaîne et un nombre, divisez la chaîne en autant de parties de taille égale. Par exemple, si le nombre est 3, vous devez diviser la chaîne en 3 morceaux, quelle que soit sa longueur.

Si la longueur de la chaîne ne se divise pas également en nombre fourni, vous devez arrondir la taille de chaque pièce et renvoyer une chaîne "restante". Par exemple, si la longueur de la chaîne d'entrée est 13 et le nombre est 4, vous devez renvoyer quatre chaînes de taille 3 chacune, plus une chaîne restante de taille 1.

S'il n'y a pas de reste, vous ne pouvez tout simplement pas en renvoyer un ou renvoyer la chaîne vide.

Le nombre fourni est garanti inférieur ou égal à la longueur de la chaîne. Par exemple, l'entrée "PPCG", 7ne se produira pas car elle "PPCG"ne peut pas être divisée en 7 chaînes. (Je suppose que le bon résultat serait (["", "", "", "", "", "", ""], "PPCG"). Il est plus facile de simplement refuser cela comme entrée.)

Comme d'habitude, les E / S sont flexibles. Vous pouvez renvoyer une paire de chaînes et la chaîne restante, ou une liste de chaînes avec le reste à la fin.

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

Notation

C'est le , donc la réponse la plus courte dans chaque langue l'emporte.

Points bonus (pas vraiment 😛) pour que votre solution utilise réellement l'opérateur de division de votre langue.


1
Points bonus? Oh mec, je dois faire ça
Matthew Roh


Lié , mais aucune partie n'est tout à fait la même chose que ce défi.
musicman523

Pour le rendre plus clair, veuillez ajouter un testcase PPCG, 7donc le reste estPPCG
Jörg Hülsermann

@ JörgHülsermann Cette entrée est interdite. J'ai ajouté plus de détails concernant ce type d'entrée et reformulé les choses pour être plus clair.
musicman523

Réponses:



5

PHP> = 7.1, 75 octets

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

Cas de test

PHP> = 7.1, 52 octets

imprimer uniquement le reste

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

Cas de test


5

Pip , 21 octets

20 octets de code, +1 pour l' -nindicateur.

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

Prend les entrées comme arguments de ligne de commande; affiche les chaînes et le reste séparé par des sauts de ligne. Essayez-le en ligne!

Explication

Amusez-vous avec les opérations regex!

Prenons abcdefgcomme chaîne et 3comme numéro. Nous construisons l'expression régulière (.{2})(.{2})(.{2}), qui correspond à trois séries de deux caractères et les stockons dans trois groupes de capture. Ensuite, en utilisant les variables de correspondance d'expression régulière de Pip, nous pouvons imprimer 1) la liste des groupes de capture ["ab";"cd";"ef"]et 2) le reste de la chaîne qui n'a pas été mise en correspondance "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 octets

# est un opérateur prenant un String et un Int, et retournant une liste de Strings.

Utilisé comme "Hello, world!"#4 .

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

Essayez-le en ligne!

Comment ça marche

  • s est la chaîne d'entrée et n le nombre de pièces non restantes.
  • d est la longueur de chaque pièce "normale". divest une division entière.
  • Les constructions de compréhension de liste n+1 morceaux, le dernier étant le reste.
    • i itère de 0 à n, inclus.
    • Pour chaque morceau, d'abord la bonne quantité ( i*d) de caractères initiaux est dropped du début des , puis une sous-chaîne initiale est taken du résultat.
    • La longueur de sous-chaîne prise doit être d , sauf pour la pièce restante.
      • Le reste réel doit être plus court que n , sinon les pièces normales seraient allongées à la place.
      • take renvoie la chaîne entière si la longueur donnée est trop grande, nous pouvons donc utiliser n'importe quel nombre >=n-1 pour la pièce restante.
      • L'expression d+n*0^(n-i)donne dsi i<net d+nsi i==n. Il utilise 0^xc'est 1quand x==0, mais 0si x>0.

Je devrai chercher où utiliser les listes de compréhension.
qfwfq

4

Python 2 , 68 67 65 octets

  • @ musicman123 a sauvé 2 octets: sortie sans entourer avec []
  • Merci à @Chas Brown pour 1 octet: x[p*i:p+p*i]asx[p*i][:p]
def f(x,n):p=len(x)/n;print[x[p*i:][:p]for i in range(n)],x[p*n:]

Essayez-le en ligne!


1
Économisez 1 octet en remplaçant x[p*i:p+p*i]parx[p*i:][:p]
Chas Brown

1
+1 pour :p😛 Bravo pour les autres réponses Python!
musicman523

Haha .. ce n'était pas prévu du tout ....: p
officialaimm

1
Cette réponse a maintenant été dépassée
musicman523

4

C ++ 14, 209 180 octets

C'est un peu trop long, mais utilise l'opérateur de division:

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

Usage:

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

Version en ligne: http://ideone.com/hbBW9u


4

Pyth, 9 octets

cz*L/lzQS

Essayez-le en ligne

Comment ça marche

Le premier Qest automatiquement initialisé à eval(input())et zest automatiquement initialisé à 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

Rouille , 107 octets

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

Essayez-le en ligne!

Formaté:

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

Il s'agit simplement d' mapindexer les tranches correctes de la source str( collecten a Vec) et de découper le reste.

Malheureusement, je ne peux pas en faire une fermeture (74 octets):

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

comme le compilateur échoue avec

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

et si je fournis le type de s:&str, les durées de vie sont fausses:

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

Rétine , 92 octets

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

O^$`.

¶1+$

O^$`.

Essayez-le en ligne! Explication: La première étape convertit le nombre de parties en unaire et prend également la longueur de la chaîne. La deuxième étape divise ensuite la longueur par le nombre de pièces, en laissant le reste. La troisième étape multiplie à nouveau le résultat par le nombre de pièces. Cela nous donne le nombre correct de chaînes de la bonne longueur, mais elles n'ont pas encore le contenu. Le nombre de pièces peut maintenant être supprimé par la quatrième étape. La cinquième étape inverse tous les personnages. Cela a pour effet de basculer le contenu d'origine avec les chaînes d'espace réservé, mais bien qu'il soit maintenant au bon endroit, il est dans l'ordre inverse. Les espaces réservés ont atteint leur objectif et sont supprimés à la sixième étape. Enfin, la septième étape remet les personnages dans leur ordre d'origine.


3

Perl 6 , 36 octets

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

Essayez-le en ligne!

Renvoie une liste de listes de chaînes, où le dernier élément est le reste (s'il y en a un).

Explication:

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

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

Renvoie un tableau de deux éléments: les parties de chaîne divisées et la partie restante.

Extrait de test

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 octets

¯W=Ul fV)òW/V pUsW

Testez-le en ligne! (utilise un -Qindicateur pour visualiser la sortie)

Explication

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

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

Essayez-le en ligne!


Bienvenue chez PPCG! J'ai ajouté un lien "Essayez-le en ligne" à votre message. Je pense que vous pouvez raccourcir légèrement votre solution en en faisant un programme complet plutôt qu'une fonction. Essayez-le en ligne!
musicman523

2

05AB1E , 12 octets

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

Essayez-le en ligne!

Explication

²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 octets en inversant l'ordre d'entrée.
Kevin Cruijssen

2

Brachylog , 16 octets

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

Essayez-le en ligne!

Prend les entrées sous forme de liste [string, number]et les sorties sous forme de liste [remainder, parts]. (Les virgules ont été remplacées par des points-virgules dans les cas de test "Bonjour, monde!" Pour plus de clarté, car les fragments de chaîne ne sont pas imprimés avec des guillemets.)

                    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.

(J'ai également remplacé une virgule dans le code par un point-virgule pour un format de sortie cohérent. Avec la virgule , les cas sans reste produiraient simplement les parties sans reste vide, et aussi agréable que cela soit à certaines fins, je ne le fais pas sais vraiment pourquoi ça marche comme ça ...)

Après que cela soit devenu un total de 16 octets, j'ai essayé de faire quelque chose basé sur le +₁ᵗ⟨ġl⟩travail, mais comme les correctifs devenaient de plus en plus longs, j'ai décidé que je resterais avec ma solution d'origine pour l'instant.



2

Formule Excel, 185 173 165 161 161 149 octets

Les éléments suivants doivent être saisis sous forme de formule matricielle ( 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))))

A1contient votre entrée (par exemple 12345678) et B1contient le diviseur. Cela utilise également l'opérateur de division d'Excel pour un bonus.

Après avoir entré la formule en tant que formule matricielle, mettez-la en surbrillance dans la barre de formule et évaluez-la en utilisant F9pour renvoyer le résultat, par exemple:

Excel formula evaluation showing split groups

-12 octets: remplacez chacun INDIRECT("1:"&B1+1)par OFFSET(A1,,,B1+1)pour économiser 2 octets par occurrence, plus un certain nettoyage supprimant les crochets redondants.

-8 octets: supprime la INDEXfonction redondante .

-4 octets: retravailler la gestion du "reste".

-12 octets: supprime la redondance INT(LEN(A1)/B1)en décalant le tableau généré ROW(OFFSET(A1,,,B1+1))par -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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.