Peter’s blog ✴ Week 336 ✴ 25 August 2025
THE WEEKLY CHALLENGE
Grouping and scoring
You are given an array of integers. Write a script to return true if the given array can be divided into one or more groups: each group must be of the same size as the others, with at least two members, and with all members having the same value.
From example 3 we can see that if several group sizes are possible, we are to return the largest.
Example 1 Input: @ints = (1,1,2,2,2,2) Output: true Groups: (1,1), (2,2), (2,2) Example 2 Input: @ints = (1,1,1,2,2,2,3,3) Output: false Groups: (1,1,1), (2,2,2), (3,3) Example 3 Input: @ints = (5,5,5,5,5,5,7,7,7,7,7,7) Output: true Groups: (5,5,5,5,5,5), (7,7,7,7,7,7) Example 4 Input: @ints = (1,2,3,4) Output: false Example 5 Input: @ints = (8,8,9,9,10,10,11,11) Output: true Groups: (8,8), (9,9), (10,10), (11,11)
I have solved this in a straightforward way:
And that's it.
Solutions are more mathematically elegant, while they are more explicit about verifying the actual grouping conditions. Both approaches have merit depending on the specific requirements!
This review may cover either or both challenges for this week.
#!/usr/bin/perl # Blog: http://ccgi.campbellsmiths.force9.co.uk/challenge use v5.26; # The Weekly Challenge - 2025-08-25 use utf8; # Week 336 - task 1 - Equal group use warnings; # Peter Campbell Smith binmode STDOUT, ':utf8'; use Encode; equal_group(1, 1, 2, 2, 2, 2); equal_group(1, 1, 1, 2, 2, 2, 3, 3); equal_group(5, 5, 5, 5, 5, 5, 7, 7, 7, 7, 7, 7); equal_group(); equal_group(42); equal_group(77, 77); equal_group(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1); sub equal_group { my (@array, $result, $size, $groups, $group, $start, $member, $output); # initialise @array = @_; $result = 'false'; # loop down over possible group sizes SIZE: for ($size = scalar @array; $size >= 2; $size --) { # check for integral number of groups $groups = scalar @array / $size; next SIZE unless $groups == int($groups); # check each group $output = '('; for $group (0 .. $groups - 1) { $start = $group * $size; # check each member for $member (0 .. $size - 1) { next SIZE unless $array[$start + $member] == $array[$start]; $output .= qq[$array[$start + $member], ]; } $output = substr($output, 0, -2) . '), ('; } $result = qq[true - ] . substr($output, 0, -3); last; } say qq[\nInput: (] . join(', ', @array) . ')'; say qq[Output: $result]; }
18 lines of code
Input: (1, 1, 2, 2, 2, 2) Output: true - (1, 1), (2, 2), (2, 2) Input: (1, 1, 1, 2, 2, 2, 3, 3) Output: false Input: (5, 5, 5, 5, 5, 5, 7, 7, 7, 7, 7, 7) Output: true - (5, 5, 5, 5, 5, 5), (7, 7, 7, 7, 7, 7) Input: () Output: false Input: (42) Output: false Input: (77, 77) Output: true - (77, 77) Input: (-1, -1, -1, -1, -1, -1, -1, -1, -1, -1) Output: true - (-1, -1, -1, -1, -1, -1, -1, -1, -1, -1)
Any content of this website which has been created by Peter Campbell Smith is in the public domain