26
\$\begingroup\$

Challenge

Given a string and a number, divide the string into that many equal-sized parts. For example, if the number is 3, you should divide the string into 3 pieces no matter how long the string is.

If the length of the string does not divide evenly into the number provided, you should round down the size of each piece and return a "remainder" string. For example, if the length of the input string is 13, and the number is 4, you should return four strings each of size 3, plus a remainder string of size 1.

If there is no remainder, you may simply not return one, or return the empty string.

The provided number is guaranteed to be less than or equal to the length of the string. For example, the input "PPCG", 7 will not occur because "PPCG" cannot be divided into 7 strings. (I suppose the proper result would be (["", "", "", "", "", "", ""], "PPCG"). It's easier to simply disallow this as input.)

As usual, I/O is flexible. You may return a pair of the strings and the remainder string, or one list of strings with the remainder at the end.

Test cases

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

Scoring

This is , so the shortest answer in each language wins.

Bonus points (not really ���) for making your solution actually use your language's division operator.

\$\endgroup\$
5
  • 1
    \$\begingroup\$ Bonus points? Oh man I gotta do this \$\endgroup\$ Commented Jul 1, 2017 at 0:12
  • \$\begingroup\$ For the bonus, Jelly, 3 bytes ;⁹/ \$\endgroup\$ Commented Jul 1, 2017 at 0:19
  • \$\begingroup\$ Related, but neither part is quite the same as this challenge. \$\endgroup\$ Commented Jul 1, 2017 at 0:20
  • \$\begingroup\$ To make it clearer please add a testcase PPCG ,7 so the remainder is PPCG \$\endgroup\$ Commented Jul 1, 2017 at 1:03
  • \$\begingroup\$ @JörgHülsermann That input is disallowed. I have added more details pertaining to that type of input and reformatted things to be more clear. \$\endgroup\$ Commented Jul 1, 2017 at 1:09

38 Answers 38

7
\$\begingroup\$

Python 2, 63 59 bytes

s,n=input()
b=len(s)/n
exec'print s[:b];s=s[b:];'*n
print s

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ Well done! I really don't think this can be golfed any further. \$\endgroup\$ Commented Jul 1, 2017 at 22:13
5
\$\begingroup\$

PHP>=7.1, 75 bytes

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

Testcases

PHP>=7.1, 52 bytes

print only the remainder

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

Test Cases

\$\endgroup\$
5
\$\begingroup\$

Pip, 21 bytes

20 bytes of code, +1 for -n flag.

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

Takes inputs as command-line arguments; outputs strings and remainder newline-separated. Try it online!

Explanation

Fun with regex operations!

Let's take abcdefg as our string and 3 as our number. We construct the regex (.{2})(.{2})(.{2}), which matches three runs of two characters and stores them in three capture groups. Then, using Pip's regex match variables, we can print 1) the list of capture groups ["ab";"cd";"ef"], and 2) the remainder of the string that wasn't matched "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
\$\endgroup\$
5
\$\begingroup\$

Haskell, 62 bytes

# is an operator taking a String and an Int, and returning a list of Strings.

Use as "Hello, world!"#4.

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

Try it online!

How it works

  • s is the input string and n is the number of non-remainder pieces.
  • d is the length of each "normal" piece. div is integer division.
  • The list comprehension constructs n+1 pieces, with the last being the remainder.
    • i iterates from 0 to n, inclusive.
    • For each piece, first the right amount (i*d) of initial characters are dropped from the beginning of s, then an initial substring is taken from the result.
    • The substring length taken should be d, except for the remainder piece.
      • The actual remainder must be shorter than n, as otherwise the normal pieces would be lengthened instead.
      • take returns the whole string if the length given is too large, so we can use any number >=n-1 for the remainder piece.
      • The expression d+n*0^(n-i) gives d if i<n and d+n if i==n. It uses that 0^x is 1 when x==0, but 0 if x>0.
\$\endgroup\$
1
  • \$\begingroup\$ I'll need to watch for where I can use list comprehensions. \$\endgroup\$
    – qfwfq
    Commented Jul 1, 2017 at 17:18
4
\$\begingroup\$

Python 2, 68 67 65 bytes

  • @musicman123 saved 2 bytes:output without enclosing with []
  • Thanks to @Chas Brown for 1 Byte: x[p*i:p+p*i] as x[p*i][:p]
def f(x,n):p=len(x)/n;print[x[p*i:][:p]for i in range(n)],x[p*n:]

Try it online!

\$\endgroup\$
4
  • 1
    \$\begingroup\$ Save 1 byte by replacing x[p*i:p+p*i] with x[p*i:][:p] \$\endgroup\$
    – Chas Brown
    Commented Jul 1, 2017 at 3:06
  • 1
    \$\begingroup\$ +1 for :p 😛 Well done outgolfing the other Python answers! \$\endgroup\$ Commented Jul 1, 2017 at 4:15
  • \$\begingroup\$ Haha.. that was not intended at all.... :p \$\endgroup\$
    – 0xffcourse
    Commented Jul 1, 2017 at 4:16
  • 1
    \$\begingroup\$ This answer has now been outgolfed \$\endgroup\$ Commented Jul 1, 2017 at 16:18
4
\$\begingroup\$

C++14, 209 180 bytes

That's a bit too long, but uses the division operator:

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

Online version: http://ideone.com/hbBW9u

\$\endgroup\$
4
\$\begingroup\$

Pyth, 9 bytes

cz*L/lzQS

Try it online

How it works

First Q is autoinitialized to eval(input()) and z is autoinitialized to 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
\$\endgroup\$
3
\$\begingroup\$

Jelly, 11 bytes

Ld⁹x,1$}R⁸ṁ

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ Fails for the "123456789", 5 testcase \$\endgroup\$ Commented Jul 1, 2017 at 1:00
  • \$\begingroup\$ Completely misread the challenge. Thanks! \$\endgroup\$
    – Dennis
    Commented Jul 1, 2017 at 1:37
3
\$\begingroup\$

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

Try it online!

Formatted:

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

This simply maps indices onto the correct slices of the source str (collecting into a Vec) and slices out the remainder.

Unfortunately, I cannot make this a closure (74 bytes):

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

as the compiler fails with

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

and if I provide the type of s:&str, the lifetimes are wrong:

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)
  | |_____________^
\$\endgroup\$
3
\$\begingroup\$

Retina, 92 bytes

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

O^$`.

¶1+$

O^$`.

Try it online! Explanation: The first stage converts the number of parts to unary and also takes the length of the string. The second stage then divides the length by the number of parts, leaving any remainder. The third stage multiplies the result by the number of parts again. This gives us the correct number of strings of the correct length, but they don't have the content yet. The number of parts can now be deleted by the fourth stage. The fifth stage reverses all of the characters. This has the effect of switching the original content with the placeholder strings, but although it's now in the right place, it's in reverse order. The placeholders have served their purpose and are deleted by the sixth stage. Finally the seventh stage reverses the characters back into their original order.

\$\endgroup\$
3
\$\begingroup\$

Perl 6, 36 bytes

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

Try it online!

Returns a list of lists of strings, where the last element is the remainder (if there is one).

Explanation:

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

\$\endgroup\$
2
\$\begingroup\$

JavaScript (ES6), 77 bytes

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

Returns an array of two elements: the divided string parts and the remainder part.

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

\$\endgroup\$
2
\$\begingroup\$

Japt, 18 bytes

¯W=Ul fV)òW/V pUsW

Test it online! (uses -Q flag to visualize the output)

Explanation

¯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
\$\endgroup\$
2
\$\begingroup\$

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

Well, looks like this qualifies for the bonus points. May I please receive a cookie instead? Oh wait, they aren't real? Darn...

Try It Online!

\$\endgroup\$
1
2
\$\begingroup\$

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!

\$\endgroup\$
1
  • \$\begingroup\$ 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! \$\endgroup\$ Commented Jul 1, 2017 at 16:17
2
\$\begingroup\$

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
\$\endgroup\$
1
  • 1
    \$\begingroup\$ 9 bytes by reversing the input-order. \$\endgroup\$ Commented May 8, 2019 at 7:44
2
\$\begingroup\$

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.

\$\endgroup\$
2
\$\begingroup\$

C(gcc), 72 bytes

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

Try It Online

\$\endgroup\$
0
2
\$\begingroup\$

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.

\$\endgroup\$
2
\$\begingroup\$

V (vim), 62 bytes

YpC<c-r>=strlen('<c-r>"')
<esc>jYp<c-x>"aDkk:s:\n:/
C<c-r>=<c-r>"
<esc>"bDkkqq@blha
<esc>q@a@q

Try it online!

takes input as 2 lines, returns the divisions on separate lines.

a is useful here to append a newline after the current character.

\$\endgroup\$
1
\$\begingroup\$

Python 2, 77 76 bytes

-1 byte thanks to 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:]]

Try it online!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ This is one byte shorter as a function. Try it online! \$\endgroup\$ Commented Jul 1, 2017 at 1:36
1
\$\begingroup\$

Ruby, 53 bytes

->s,n{a=s.scan(/.{,#{s.size/n}}/);[a[0,n],a[n,n]*'']}

Try it online!

\$\endgroup\$
1
\$\begingroup\$

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"}}
\$\endgroup\$
1
\$\begingroup\$

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)
\$\endgroup\$
3
  • 2
    \$\begingroup\$ 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/… . \$\endgroup\$ Commented Jul 1, 2017 at 7:17
  • 1
    \$\begingroup\$ Also, take a look at Tips for golfing in Haskell for some useful tricks. \$\endgroup\$
    – sudee
    Commented Jul 1, 2017 at 7:22
  • \$\begingroup\$ @ØrjanJohansen Thanks! I forgot that semicolons were valid, and that let in the guard is pretty devious. But shorter code is more readable, right? \$\endgroup\$
    – qfwfq
    Commented Jul 1, 2017 at 17:16
1
\$\begingroup\$

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?

\$\endgroup\$
2
  • 1
    \$\begingroup\$ This doesn't split in the way required. e.g. the Hello, world! 5 testcase is wrong. Try it online! \$\endgroup\$ Commented Jul 2, 2017 at 1:28
  • \$\begingroup\$ Well I'm going to look for another built-in.... \$\endgroup\$ Commented Jul 2, 2017 at 4:46
1
\$\begingroup\$

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.
\$\endgroup\$
1
\$\begingroup\$

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│   │
└──┴───┘
\$\endgroup\$
1
  • \$\begingroup\$ Thanks. Read too fast. Comment removed \$\endgroup\$
    – Jonah
    Commented May 9, 2019 at 12:39
1
\$\begingroup\$

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

\$\endgroup\$
2
  • \$\begingroup\$ 63 bytes -- simplified the indexing a bit. \$\endgroup\$
    – Giuseppe
    Commented May 9, 2019 at 14:35
  • \$\begingroup\$ @Giuseppe Haha, I must have tried every variant of adding and multiplying on the index, but missed that one. Good catch. \$\endgroup\$ Commented May 10, 2019 at 8:21
1
\$\begingroup\$

JavaScript, 49 bytes

d=(s,n)=>s.match(eval(`/.{1,${0|s.length/n}}/g`))

Try It Online

d=(s,n)=>s.match(eval(`/.{1,${0|s.length/n}}/g`))

var ret = d("######.######..#####..########..##.##..##.##.....##.....######.######.##.....##..#####.....##.....##.....##...####.....##......####...######", 5);
for (var r in ret)
    console.log(ret[r]);

\$\endgroup\$
1
\$\begingroup\$

Stax, 12 bytes

î╩╘30¥♂┴ÿ&╕¡

Run and debug it

\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.