Peter’s solutions: week 373 — 11 May 2026

THE WEEKLY CHALLENGE
The week of lists

The Perl Camel

Task 2

List division

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 -1 if the integer is more than the size of the list.

Examples


Example 1
Input: @list = (1,2,3,4,5), $n = 2
Output: ((1,2,3), (4,5))
5 / 2 = 2 remainder 1.
The extra element goes into the first chunk.

Example 2
Input: @list = (1,2,3,4,5,6), $n = 3
Output: ((1,2), (3,4), (5,6))
6 / 3 = 2 remainder 0.

Example 3
Input: @list = (1,2,3), $n = 2
Output: ((1,2), (3))

Example 4
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))

Example 5
Input: @list = (1,2,3), $n = 4
Output: -1

Example 6
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))

Analysis

The slight catch in this challenge is the need to add any 'extra' items to the first bucket. I did that by first calculating how many extras there are, and my while ($extras) loop will only run once during the creation of the first part.

Try it 

Try running the script with any input:



example: 2, 4, 6, 8, 10, 12, 14



example: 3

Script


#!/usr/bin/perl

# Blog: http://ccgi.campbellsmiths.force9.co.uk/challenge

use v5.26;    # The Weekly Challenge - 2026-05-11
use utf8;     # Week 373 - task 2 - List division
use warnings; # Peter Campbell Smith
binmode STDOUT, ':utf8';
use Encode;

list_division([1, 2, 3, 4, 5], 2);
list_division([1, 2, 3, 4, 5], 5);
list_division([1, 2, 3, 4, 5], 6);
list_division([1, 2, 3, 4, 5], 0);
list_division([11, 12, 13, 14, 15, 16, 17, 18, 19, 20], 4);

my @nums;
push(@nums, int(rand(100))) for 1 .. 50;
list_division(\@nums, int(rand(10)) + 1);

sub list_division {
    
    my (@list, $part, $parts, $extras, $output, $p);
    
    # initialise
    @list = @{$_[0]};
    $part = $_[1];
    if ($part <= @list and $part > 0) {
        
        # determine no of parts and extras
        $parts = int(@list / $part);
        $extras = @list % $part;
        $output = '((';
        
        # loop over parts
        for $p (1 .. $parts) {
            
            # add extras to first part
            while ($extras) {
                $output .= shift(@list) . ', ';
                $extras --;
            }
            
            # and add $part entries to this part
            $output .= shift(@list) . ', ' for (1 .. $part);
            $output =~ s|, $|), (|;
        }
        $output =~ s|, \($|)|;
    
    # $int is invalid
    } else {
        $output = -1;
    }
    
    # report
    say qq[\nInput:  \@list = (] . join(', ', @{$_[0]}) . 
        qq[), \$int = $part];
    say qq[Output: $output];
}

20 lines of code

Output


Input:  @list = (1, 2, 3, 4, 5), $int = 2
Output: ((1, 2, 3), (4, 5))

Input:  @list = (1, 2, 3, 4, 5), $int = 5
Output: ((1, 2, 3, 4, 5))

Input:  @list = (1, 2, 3, 4, 5), $int = 6
Output: -1

Input:  @list = (1, 2, 3, 4, 5), $int = 0
Output: -1

Input:  @list = (11, 12, 13, 14, 15, 16, 17, 18, 19, 20), $int = 4
Output: ((11, 12, 13, 14, 15, 16), (17, 18, 19, 20))

Input:  @list = (25, 19, 57, 26, 7, 63, 61, 72, 58, 57, 29, 23, 6, 88,
   88, 61, 32, 2, 4, 75, 48, 93, 83, 96, 20, 20, 33, 22, 97, 88, 36,
   53, 73, 91, 95, 17, 56, 51, 77, 38, 21, 52, 2, 63, 84, 31, 11, 74,
   86, 39), $int = 8
Output: ((25, 19, 57, 26, 7, 63, 61, 72, 58, 57), (29, 23, 6, 88, 88,
   61, 32, 2), (4, 75, 48, 93, 83, 96, 20, 20), (33, 22, 97, 88, 36,
   53, 73, 91), (95, 17, 56, 51, 77, 38, 21, 52), (2, 63, 84, 31, 11,
   74, 86, 39))

 

Any content of this website which has been created by Peter Campbell Smith is in the public domain