12
\$\begingroup\$

Given a list of integers L, and an integer N, output L splitted in N sublists of equal lenghts.

Non-divisible lengths

If N does not divide the length of L, then it is not possible that all sublists have equal length.

In any case, the last sublist of the output is the one that adapts its length to contain the remainder of the list.

This means that all sublists of L except for the last one should be of length length(L) // N, where // is floored division (e.g. 3//2 = 1).

Some rules

  • L can be empty.

  • N >= 1.

  • You may use any built-in you want.

  • You may take the input through STDIN, as a function argument, or anything similar.

  • You may print the output to STDOUT, return it from a function, or anything similar.

  • You may chose any format for the lists and the integer as long as it is the most natural representation of lists and integers in your language.

Test cases

Input:  [1,2,3,4], 2
Output: [[1,2],[3,4]]

Input:  [-1,-2,3,4,-5], 2
Output: [[-1,-2],[3,4,-5]]

Input:  [1,2,3,4], 1
Output: [[1,2,3,4]]

Input:  [4,8,15,16,23,42], 5
Output: [[4],[8],[15],[16],[23,42]]

Input:  [4,8,15,16,23,42], 7
Output: [[],[],[],[],[],[],[4,8,15,16,23,42]]

Input:  [2,3,5,7,11,13,17,19,23], 3
Output: [[2,3,5],[7,11,13],[17,19,23]]

Input:  [], 3
Output: [[],[],[]]

Input:  [1,2,3,4,5,6,7,8], 3
Output: [[1,2],[3,4],[5,6,7,8]]

Scoring

This is , so the shortest answer in bytes wins.

\$\endgroup\$
5
  • \$\begingroup\$ Related \$\endgroup\$
    – Fatalize
    Jun 7, 2016 at 7:15
  • \$\begingroup\$ Also related \$\endgroup\$
    – Sp3000
    Jun 7, 2016 at 7:57
  • \$\begingroup\$ Only positive integers? Or maybe add a test case \$\endgroup\$
    – Luis Mendo
    Jun 7, 2016 at 9:53
  • \$\begingroup\$ @LuisMendo No. I changed a test case to reflect that. \$\endgroup\$
    – Fatalize
    Jun 7, 2016 at 9:54
  • \$\begingroup\$ A list of length 8 with length n=3 (suggested by user2357112) would be a good test case -- it broke my method. \$\endgroup\$
    – xnor
    Jun 7, 2016 at 23:54

9 Answers 9

4
\$\begingroup\$

JavaScript (ES6), 63 bytes

(a,n,l=a.length/n|0)=>[...Array(n)].map(_=>--n?a.splice(0,l):a)
\$\endgroup\$
2
\$\begingroup\$

Pyth, 11 10 bytes

1 byte thanks to @FryAmTheEggman.

cJEt*R/lJQ

Test suite.

Takes inputs in reversed order.

Sample input:

5
[1,2,3,4,5,6,7]

Sample output:

[[1], [2], [3], [4], [5, 6, 7]]

Explanation

cJEt*R/lJQ     Main function, first input:Q, second input:E.
cJEt*R/lJQQ    Implicit arguments.

c              The function c is special.
               It can chop arrays.
               If the second argument is a list of integers,
               then it chops the first array at the indices
               specified by the second array.

 JE            The first argument is the second input, stored
               to the variable J.

   t*R/lJQQ    This is the second argument.
      /lJQ     Yield length of J, integer-divided by Q.
    *R    Q    Multiply it to the following respectively:
                   [0,1,2,3,...,Q-1]
   t           Then throw away the first element.
               For example, if Q=3 and E=[1,2,3,4,5,6,7,8],
               we would now have [3,6].
\$\endgroup\$
0
2
\$\begingroup\$

Python, 76 73 bytes

lambda L,N:list(map(lambda x,r=len(L)//N:L[x*r:][:r+(x>N-2)*N],range(N)))

Basically an unnamed function that performs the task. Thanks to LeakyNun for the bytes saved!

\$\endgroup\$
7
  • 1
    \$\begingroup\$ Also, welcome to PPCG! \$\endgroup\$
    – Leaky Nun
    Jun 7, 2016 at 8:15
  • \$\begingroup\$ @LeakyNun Nun It's 73 I think actually. Also it's mostly my fault as I wasn't paying much attention while editing. Perils of codegolfing at work :P \$\endgroup\$
    – Lause
    Jun 7, 2016 at 8:45
  • \$\begingroup\$ @LeakyNun - to the first point - it doesn't work. The expression basically is [:r] for regular items and [:r+N] for the last item, which is supposed to catch all the remaining elements. The second point - I tried but all the ways I know that let me assign r make it longer than my code. \$\endgroup\$
    – Lause
    Jun 7, 2016 at 10:31
  • \$\begingroup\$ It would, but in the case of r*(x>N-2) it's [:0] , not [:]. \$\endgroup\$
    – Lause
    Jun 7, 2016 at 11:21
  • \$\begingroup\$ Well, here \$\endgroup\$
    – Leaky Nun
    Jun 7, 2016 at 12:21
2
\$\begingroup\$

Common Lisp, 114 bytes

(defun f(l n &optional(p(floor(length l)n))(i 1))(if(= i n)(list l)(cons(subseq l 0 p)(f(subseq l p)n p(+ i 1)))))

Ungolfed:

(defun f (l n &optional (p (floor (length l) n)) (i 1))
  (if (= i n) (list l)
              (cons (subseq l 0 p)
                    (f (subseq l p) n p (+ i 1))))
  )

Example call:

(format t "~A~C~C" (f (read) (read)) #\return #\newline)

Try it here!

Basically:

  • If we are cutting the last group, return whatever's left of the initial list.
  • Otherwise take p = |L| / N elements out of the list and join that to the result of a recursive call on the remainder. i is an iteration counter used for the stop condition.

I had misunderstood the challenge at first, thinking the program should build groups of N elements rather than N groups. Anyway, this version does the job for an extra 10 bytes. LisP won't win this time but I couldn't really miss the opportunity :')

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

Haskell, 69 67 bytes

a%b=a#b where l#1=[l];l#n|(h,t)<-splitAt(div(length a)b)l=h:t#(n-1)

Usage example: [1,2,3,4] % 3 -> [[1],[2],[3,4]].

A simple recursive approach, similar to @xnor's answer.

Edit: @Will Ness saved 2 bytes. Thanks!

\$\endgroup\$
1
  • \$\begingroup\$ h:t#(n-1) also works. \$\endgroup\$
    – Will Ness
    Jun 7, 2016 at 23:22
1
\$\begingroup\$

PowerShell v2+, 125 bytes

param($l,$n)if($p=[math]::Floor(($c=$l.count)/$n)){1..$n|%{$l[(($_-1)*$p)..((($_*$p-1),$c)[!($_-$n)])]}}else{(,''*($n-1))+$l}

Feels too long, but I can't seem to come up with a way to get the slicing to work happily if there are empty arrays in the output, so I need the encapsulating if/else to handle those cases. Additionally, since PowerShell's default .ToString() for arrays via console output can look a little weird, you can tack on a -join',' to show the arrays as comma-separated rather than newline-separated on the console. I've done that in the examples below to make the output more clear, but you won't want to do that if you're leaving the output on the pipeline for another command to pick up.

Explanation

Takes input param($l,$n) for the list and number of partitions, respectively. We then enter an if/else statement. If the size of each partition, $p is non-zero (setting helper $c to be the .count along the way), we're in the if.

Inside the if, we loop from 1 to $n with |%{...}, and each iteration we're doing a pretty complex-looking array slice $l[(($_-1)*$p)..((($_*$p-1),$c)[!($_-$n)])]. The first parens is our start index, based on what partition we're on and how big our partition size is. We range that .. with our end index, which is formed from a pseudo-ternary. Here, we're choosing between either $c (the literal end of the array), or the length of our partition, based on whether we're in the last chunk $_-$n or not.

Otherwise, we're in the else. We construct an empty array with the comma-operator ,''* equal to one fewer partitions than requested, and then tack on the input array as the final element.

Examples

Here I'm showing the partitions separated with newlines and each individual element separated with ,, as described above.

PS C:\Tools\Scripts\golfing> .\n-chotomize-a-list.ps1 (1,2,3,4) 2
1,2
3,4

PS C:\Tools\Scripts\golfing> .\n-chotomize-a-list.ps1 (-1,-2,3,4,-5) 2
-1,-2
3,4,-5

PS C:\Tools\Scripts\golfing> .\n-chotomize-a-list.ps1 (1,2,3,4) 1
1,2,3,4

PS C:\Tools\Scripts\golfing> .\n-chotomize-a-list.ps1 (4,8,15,16,23,42) 5
4
8
15
16
23,42

PS C:\Tools\Scripts\golfing> .\n-chotomize-a-list.ps1 (4,8,15,16,23,42) 7






4,8,15,16,23,42

PS C:\Tools\Scripts\golfing> .\n-chotomize-a-list.ps1 (2,3,5,7,11,13,17,19,23) 3
2,3,5
7,11,13
17,19,23

PS C:\Tools\Scripts\golfing> .\n-chotomize-a-list.ps1 $null 3



PS C:\Tools\Scripts\golfing> 
\$\endgroup\$
1
\$\begingroup\$

F#, 100 98 bytes

fun n l->
let a=List.length l/n
List.init n (fun i->if i<n-1 then l.[a*i..a*i+a-1] else l.[a*i..])

Using F# list slicing, with an if clause deciding whether to pick a elements or all remaining elements.

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

Prolog, 100 99 bytes.

n(A,B):-length(B,A).
p(L,K,G):-n(K,G),append(A,[_],G),n(N,L),M is N//K,maplist(n(M),A),append(G,L).

Call e.g.

?- p( [1,2,3,4,5,6,7], 3, X).
X = [[1, 2], [3, 4], [5, 6, 7]] .

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

PHP, 109 Bytes

<?for($n=(count($a=$_GET[0]))/($d=$_GET[1])^0;$i<$d;)$r[]=array_slice($a,$i*$n,++$i==$d?NULL:$n);print_r($r);

All Testcases

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