You are given a list and a non-negative integer.
Write a script to divide the given list into given non-negative integer equal parts. Return
-1if the integer is more than the size of the list.
Input: @list = (1,2,3,4,5), $n = 2
Output: ((1,2,3), (4,5))
Input: @list = (1,2,3,4,5,6), $n = 3
Output: ((1,2), (3,4), (5,6))
Input: @list = (1,2,3), $n = 2
Output: ((1,2), (3))
Input: @list = (1,2,3,4,5,6,7,8,9,10), $n = 5
Output: ((1,2), (3,4), (5,6), (7,8), (9,10))
Input: @list = (1,2,3), $n = 4
Output: -1
Input: @list = (72,57,89,55,36,84,10,95,99,35), $n = 7;
Output: ((72,57), (89,55), (36,84), (10), (95), (99), (35))
We prefer to take our input not as arrays or scalar variables, but
to read it from standard input — where each line corresponds with
an excercise. Our input consists of numbers separated by white space,
where the first number equals the $n above.
So, the input corresponding to the examples above is as follows:
2 1 2 3 4 5
3 1 2 3 4 5 6
2 1 2 3
5 1 2 3 4 5 6 7 8 9 10
4 1 2 3
7 72 57 89 55 36 84 10 95 99 35
We output the sets with the elements separated by a space, and each set terminated by a semi-colon. So, the output with when given the input above will be
1 2 3; 4 5;
1 2; 3 4; 5 6;
1 2; 3;
1 2; 3 4; 5 6; 7 8; 9 10;
-1;
72 57; 89 55; 36 84; 10; 95; 99; 35;
To solve this exercise, for each line of input, we do the following steps:
$n from above), the rest the list (@list)
to be split.-1; and continue with the
next time.per_set in our solutions), and the number
of sets which get one more element (overflow).per_set, or per_set + 1)With a line of input in $line, we start off by splitting it into
the number of wanted subsets ($n) and the list of elements (@list):
my ($n, @list) = split /\s+/ => $line;
Then we check whether we have enough elements in the list — if not,
we print -1; and continue:
do {say "-1;"; next} if $n > @list;
Next, we calculate the minimum amount of element each set gets, and how many sets get one more element:
my $per_set = int (@list / $n);
my $overflow = @list - $n * $per_set;
Iterate over the number of wanted sets, and calculate how many elements it gets:
for my $i (1 .. $n) {
my $set_size = $per_set;
$set_size ++ if $i <= $overflow;
Finally, print the set, and terminate it with a semi-colon:
print join " " => splice @list, 0, $set_size;
print "; ";
Find the full program on GitHub.
We also have solutions in AWK, Bash, bc, C, Lua, Go, Node.js, Python, R, Ruby, and Tcl, all following the same algorithm as the Perl solution.