11
\$\begingroup\$

The Challenge

In this challenge you have to do two different (but related) tasks depending of the order of the input.
Your program will recieve a string s and an integer n as input and will

  • split s into pieces of length n if s comes first. The last element will be shorter if necessary.
  • split s into n pieces of equal length if n comes first. If len(s) is not a multiple of n the first len(s) mod n elements will be one longer.

You may only take those 2 inputs. s will never contain only digits.

Notes

  • You may use the reverse mapping. Note this in your answer if you do that.
  • s will only contain printable ASCII characters (no newlines).
  • You may not use any builtins that solve either those two tasks directly. All other builtins are allowed.
  • You have to take both arguments from the same source.
  • You may take the arguments in an ordered list or any other format which clearly indicates their order as long as it is unambiguous.
  • You may take the input as one string/ stream and use a character which is not a valid input (like a nullbyte) to separate them.
  • n will always be equal or less than the length of s and greater than zero.
  • You may output the resulting list in any resonable format as long as it clearly indicates the particular pieces and their order.

Example

Input: programming, 3
The last element contains only 2 characters, because 11 is not divisible by 3.
Output: ["pro", "gra", "mmi", "ng"]

Input: 3, programming
11 is not a multiple of 3, so the first 2 elements will be one longer:
Output: ["prog", "ramm", "ing"]

Rules

Test cases

The test cases got generated with this Pyth program (uses builtins, so no valid answer). Thanks to @FryAmTheEggman for providing the base version of that!

3, helloworld -> ['hell', 'owo', 'rld']
helloworld, 3 -> ['hel', 'low', 'orl', 'd']
1, programming -> ['programming']
programming, 1 -> ['p', 'r', 'o', 'g', 'r', 'a', 'm', 'm', 'i', 'n', 'g']
8, programming -> ['pr', 'og', 'ra', 'm', 'm', 'i', 'n', 'g']
programming, 8 -> ['programm', 'ing']
9, code golf -> ['c', 'o', 'd', 'e', ' ', 'g', 'o', 'l', 'f']
code golf, 9 -> ['code golf']
4, 133tspeak -> ['133', 'ts', 'pe', 'ak']
133tspeak, 4 -> ['133t', 'spea', 'k']

Happy Coding!

\$\endgroup\$
  • \$\begingroup\$ You may not use any builtins that solve those two tasks. Does that include other built-ins, such get every n-th character from a string or split at occurrences? \$\endgroup\$ – Dennis Apr 7 '16 at 16:54
  • \$\begingroup\$ @Dennis This was just meant to rule out builtins that solve this directly. I clarified. \$\endgroup\$ – Denker Apr 7 '16 at 16:55
  • \$\begingroup\$ If our language does not support arrays, how should we output? Would a newline between each result of the string be acceptable? \$\endgroup\$ – Conor O'Brien Apr 8 '16 at 3:50
  • \$\begingroup\$ Also, for languages where the input is an array of ambiguous numbers, what should the procedure be? \$\endgroup\$ – Conor O'Brien Apr 8 '16 at 3:54
  • \$\begingroup\$ @CᴏɴᴏʀO'Bʀɪᴇɴ Can't happen. s will never contain only digits. Also You may output the resulting list in any resonable format as long as it clearly indicates the particular pieces and their order which includes multiline output of course. \$\endgroup\$ – Denker Apr 8 '16 at 4:39

10 Answers 10

3
\$\begingroup\$

MATL, 46 26 21 27 29 42 bytes

jtU?jtbUe!tn2Gn>?0t(]tgbw(}ie]!2t$X{Oc''Zt

Try it Online! (Updated slightly to work with the latest version of the language)

Explanation

j           % Explicitly grab the first input as a string
t           % Duplicate
U           % Attempt to convert it to a number
?           % If the conversion to a number was successful
    j       % Explicitly grab the second input as a string
    t       % Duplicate the value
    b       % Bubble-up the first element in the stack
    U       % Convert to a number from a string
    e       % Reshape the string into a nGroup x nPerGroup matrix
    !       % Take the transpose
    t       % Duplicate the result
    n       % Number of characters in the repmat result
    2Gn     % Number of characters in the string
    >?      % If chars in repmat > chars in string
        O   % Zero
        t   % Duplicate 
        (   % Assign the last element to a null character (bug in MATL)
    ]       % End if statement
    t       % Duplicate this matrix
    g       % Convert to a logical matrix
    b       % Bubble-up the original string
    w       % Flip the top two elements
    (       % Assign the non-empty characters to the chars from the input string
}           % Else the string comes first
    i       % Explicitly grab the second input (the number)
    e       % Reshape the characters into an nPerGroup x nGroup 2D array
]           % End of if statement
!           % Take the transpose so it reads left-to-right
2           % Number literal
t           % Duplicate
$X{         % Call num2cell to convert to a cell array
Oc          % Null character
''          % Empty string
Zt          % Replace null chars with empty strings
            % Implicit display of stack contents
\$\endgroup\$
  • \$\begingroup\$ What are those unprintables that appear at the end of some list elements? Those are not part of the input and should therefore not be part of the output either. \$\endgroup\$ – Denker Apr 8 '16 at 7:17
  • \$\begingroup\$ Isn't e a prohibited builtin ? \$\endgroup\$ – FliiFe Apr 8 '16 at 9:11
  • \$\begingroup\$ Maybe replace XUZN?... by U?... and swap the two if branches. Also, you don't need the 3$ \$\endgroup\$ – Luis Mendo Apr 8 '16 at 9:22
  • \$\begingroup\$ @DenkerAffe Sorry about that. Should be fixed now. \$\endgroup\$ – Suever Apr 8 '16 at 12:30
  • \$\begingroup\$ @FliiFe Based on the comments on the initial post, e doesn't directly solve the problem, so I don't consider it to be prohibited, no. \$\endgroup\$ – Suever Apr 8 '16 at 12:31
4
\$\begingroup\$

JavaScript (ES6), 132 bytes

(s,t)=>+t?[...Array(-~(~-s.length/+t))].map((_,i)=>s.substr(i*t,t)):[...Array(s=+s)].map(_=>t.slice(p,p-=~((t.length-p-1)/s--)),p=0)

This is probably hopelessly over-engineered.

\$\endgroup\$
  • \$\begingroup\$ Well, my (now deceased) solution was grossly under-engineered. +1 for you \$\endgroup\$ – edc65 Apr 8 '16 at 22:40
4
\$\begingroup\$

JavaScript (Firefox), 88 87 bytes

a=>b=>(s=+b?a:b,i=x=0,l=s.length,[for(c of s)if(r=s.slice(x,x+=+b||l/a+(i++<l%a)|0))r])

Call it like (...)("programming")(3) using Firefox 30+.

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

Ruby, 119 bytes

->x,y{r=[t=0];x.to_s==x ?(r.push x[t...t+=y]while x[t]):x.times{r.push y[t...t+=y.size/x+(r[y.size%x]? 0:1)]};r[1..-1]}

And I take first place by 2 bytes...

\$\endgroup\$
  • \$\begingroup\$ Regex objects in Ruby can have values injected into them the same way strings can, so x.scan(/.{,#{y}}) works just as well for splitting the strings in the first case. Or does that count as a builtin? \$\endgroup\$ – Value Ink Apr 8 '16 at 6:11
2
\$\begingroup\$

AWK, 121 130 128 122 Bytes

$1~/^[0-9]+$/{s=1}{a=$(s+1)
b=s?$1:$2
$0=""
for(j=-b;j<=c=length(a);)$0=$0 substr(a,j+=b+s,b+(s=s&&j<c%b*(b+1)?1:0))" "}1

The only issue is if the first entry is a string that starts with a numeric value. This would cause AWK to see the string as that number and the second entry as the string.

OK... fixed the numeric issue, but it added 9 bytes :(.

Reworked a bit to save a couple bytes.

Almost back to the original length. :)

\$\endgroup\$
  • \$\begingroup\$ OK, @DenkerAffe , fixed it to work in general and only (eventually) added 1 byte. \$\endgroup\$ – Robert Benson Apr 8 '16 at 13:53
1
\$\begingroup\$

Haskell, 131 bytes

import Data.Lists
q(d,m)=splitPlaces$(d+1<$[1..m])++[d,d..]
a#b|all(`elem`['0'..'9'])a=q(divMod(length b)$read a)b|1<2=q(read b,0)a

Usage example:

*Main> "8" # "programming"
["pr","og","ra","m","m","i","n","g"]
*Main> "programming" # "8"
["programm","ing"]

How it works: the main work is done by the helper function q which takes a pair of numbers (d,m) and a string s. It first builds a list of m times d+1 followed by infinite many d (e.g (1,3) -> [2,2,2,1,1,1,1,1,...]). It then uses splitPlaces to split s into chunks of lengths given by the list. splitPlaces stops if s runs out of elements, so an infinite list is fine.

The main function # checks which parameter is the number n / string str and calls q with either (div (length str) n, mod (length str) n) or (n, 0) plus str.

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

C# (LINQPAD) - 335 bytes

var y=Util.ReadLine().Split(',');int x,j=0;var t=int.TryParse(y[0].Trim(),out x);x=x==0?int.Parse(y[1].Trim()):x;var i=t?y[1].Trim():y[0];var z="";if(!t){while(i.Substring(j).Length>x){z+=i.Substring(j).Length>x?i.Substring(j,x)+", ":"";j+=x;}z+=i.Substring(j);}else z=string.Join(", ",i.Split(x).Select(s=>string.Concat(s)));z.Dump();

The input reading part took up a bit of space. Winner of longest answer.

Usage #1:

$ 3, helloworld

>> hell, owo, rld

Usage #2:

$ helloworld, 3

>>hel, low, orl, d
\$\endgroup\$
  • \$\begingroup\$ owo what's this? \$\endgroup\$ – Benjamin Urquhart May 19 at 12:41
0
\$\begingroup\$

Pyth, 181 bytes

Let's pretend the longest code in bytes wins \o/

DyGK@G0J:@G1"."1=YJV%lJKW<l@YN.EclJK=YXYN+@YN@YhN=Y.DYhN)FNr%lJK/-lJ%lJK/-lJ%lJKKW<l@YNsclJK=YXYN+@YN@YhN=Y.DYhN))RY)DPG=K@G1=J:@G0"."1=YJV/lJKW<l@YNK=YXYN+@YN@YhN=Y.DYhN))RY).xyQPQ

Try it here ! (The online interpreter seem to have a bug, it displays the input while it should not)

Here's the output from the terminal:

» pyth split.pyth <<<'["helloworld", 3]' 
['hel', 'low', 'orl', 'd']
» pyth split.pyth <<<'[3, "Helloworld"]'
['Hell', 'owo', 'rld']

Seriously, I am open to new approach. I'm new to python, so I probably missed a few shorthands.

I mean, I think my answer is deseperate from the point it is longer than the javascript answer...

\$\endgroup\$
  • \$\begingroup\$ Can you provide a sample input and output? \$\endgroup\$ – Leaky Nun Apr 8 '16 at 1:22
  • \$\begingroup\$ Note the official solution under the header testcases. The testcases are generated by Pyth. The solution is .xcsJKcJsK, where J and K are the two arguments. \$\endgroup\$ – Leaky Nun Apr 8 '16 at 1:24
  • \$\begingroup\$ @KennyLau I added a link to the online pyth interpreter. Strangely, it outputs the input too while I'm sure it did not yesterday... Will try to fix that. \$\endgroup\$ – FliiFe Apr 8 '16 at 8:53
  • \$\begingroup\$ use spaces to suppress printing \$\endgroup\$ – Leaky Nun Apr 8 '16 at 9:41
  • \$\begingroup\$ @KennyLau spaces where ? \$\endgroup\$ – FliiFe Apr 8 '16 at 9:44
0
\$\begingroup\$

PHP, 114 bytes

[$t,$n,$p]=$argv;for(@+$p?$s=$n:$f=$n*($p=strlen($s=$p)/$n)%$n;$t;)echo$t=substr($s,$a+=$e,$e=$p+($i++<$f)|0),"
";
  • String should not start with digits.
    (Replace +@$p with is_numeric($p) to fix.)
  • Output should not contain a chunk "0".
    (Insert ~ for printable ASCII, a& for any ASCII before $t; to fix.)
  • Run with -nr or try it online.
\$\endgroup\$
0
\$\begingroup\$

PowerShell, 122 118 bytes

param($a,$b)if($a-is[int]){$a,$b=$b,((($l=$b|% Le*)-($c=$l%$a))/$a)}$a-split("(..{$b})"*$c+"(.{0,$b})"*$a.Length)-ne''

Try it online!

Less golfed:

param($a,$b)
if($a-is[int]){
    $length=$b|% Length
    $c=$length%$a
    $a,$b=$b,(($length-$c)/$a)  # recalc length and swap
}
$pattern="(..{$b})"*$c+"(.{0,$b})"*$a.Length
$parts=$a -split $pattern       # pattern like '(..{3})(..{3})(.{0,3})(.{0,3})(.{0,3})'
$parts -ne ''                   # output not empty parts
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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