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 }