perl logo Perl logo (Thanks to Olaf Alders)

The weekly challenge 373 - Task 2: List Division

 1 #!/usr/bin/env perl
 2 # https://theweeklychallenge.org/blog/perl-weekly-challenge-373/#TASK2
 3 #
 4 # Task 2: List Division
 5 # =====================
 6 #
 7 # You are given a list and a non-negative integer.
 8 #
 9 # Write a script to divide the given list into given non-negative integer equal
10 # parts. Return -1 if the integer is more than the size of the list.
11 #
12 ## Example 1
13 ##
14 ## Input: @list = (1,2,3,4,5), $n = 2
15 ## Output: ((1,2,3), (4,5))
16 ##
17 ## 5 / 2 = 2 remainder 1.
18 ## The extra element goes into the first chunk.
19 #
20 ## Example 2
21 ##
22 ## Input: @list = (1,2,3,4,5,6), $n = 3
23 ## Output: ((1,2), (3,4), (5,6))
24 ##
25 ## 6 / 3 = 2 remainder 0.
26 #
27 ## Example 3
28 ##
29 ## Input: @list = (1,2,3), $n = 2
30 ## Output: ((1,2), (3))
31 #
32 ## Example 4
33 ##
34 ## Input: @list = (1,2,3,4,5,6,7,8,9,10), $n = 5
35 ## Output: ((1,2), (3,4), (5,6), (7,8), (9,10))
36 #
37 ## Example 5
38 ##
39 ## Input: @list = (1,2,3), $n = 4
40 ## Output: -1
41 #
42 ## Example 6
43 ##
44 ## Input: @list = (72,57,89,55,36,84,10,95,99,35), $n = 7;
45 ## Output: ((72,57), (89,55), (36,84), (10), (95), (99), (35))
46 #
47 ############################################################
48 ##
49 ## discussion
50 ##
51 ############################################################
52 #
53 # First we handle the case that $n is bigger than the amount of elements
54 # in the list.
55 # Then we calculate the amount of elements per part and the remainder for
56 # the division. We then run from 0 to $n - 1, calculating the correct sublist
57 # that we need to collect this time, considering whether we are still below
58 # the calculated remainder or not. If we are below that threshold, we collect
59 # the elements from index $i * ($m + 1), with $m being the number of elements for
60 # each sublist, up to ($i+1) * ($m + 1) - 1 - right before the next sublist's
61 # beginning. After the threshold, this becomes a sublist starting at index
62 # $i * $m + $r until ($i+1) * $m + $r - 1, So we calculate the sublists and
63 # add them to the result.
64 #
65 use v5.36;
66 
67 list_division([1,2,3,4,5], 2);
68 list_division([1,2,3,4,5,6], 3);
69 list_division([1,2,3], 2);
70 list_division([1,2,3,4,5,6,7,8,9,10], 5);
71 list_division([1,2,3], 4);
72 list_division([72,57,89,55,36,84,10,95,99,35], 7);
73 
74 sub list_division($list, $n) {
75     say "Input: (" . join(", ", @$list) . "), $n";
76     my @tmp = @$list;
77     if($n > scalar(@tmp)) {
78         return say "Output: -1";
79     }
80     my $m = int( scalar(@tmp) / $n); # how many elements we will see in each part
81     my $r = scalar(@tmp) - ($m * $n); # how many elements to distribute extra
82     my @result = ();
83     foreach my $i (0..$n-1) {
84         if($i < $r) {
85             my @t = @tmp[ $i * ($m + 1).. ($i+1) * ($m + 1) - 1 ];
86             push @result, [ @t ];
87         } else {
88             my @t = @tmp[ $i * $m + $r .. ($i+1) * $m + $r - 1];
89             push @result, [ @t ];
90         }
91     }
92     print "Output: (";
93     foreach my $elem (@result) {
94         print "(" . join(", ", @$elem) . "), ";
95     }
96     say "^H^H)";
97 }