Peter’s solutions: week 372 — 4 May 2026

THE WEEKLY CHALLENGE
Strings of strings

The Perl Camel

Task 1

Rearrange spaces

You are given a string of words and spaces. Write a script to rearrange the spaces so that there is an equal number of spaces between every pair of adjacent words and that number is maximised. If you can’t distribute all the spaces, place the extra ones at the end of the string.

Examples


Example 1
Input: $str = '  challenge  '
Output: 'challenge    '
We have 4 spaces and 1 word. So all spaces go to the end.

Example 2
Input: $str = 'coding  is  fun'
Output: 'coding  is  fun'
We have 4 spaces and 3 words (2 gaps). So 2 spaces per 
   gap.

Example 3
Input: $str = 'a b c  d'
Output: 'a b c d '
We have 4 spaces and 4 words (3 gaps). So 1 space per gap 
   and 1 remainder.

Example 4
Input: $str = '  team      pwc  '
Output: 'team          pwc'
We have 10 spaces and 2 words (1 gap). So 10 spaces per 
   gap.

Example 5
Input: $str = '   the  weekly  challenge  '
Output: 'the    weekly    challenge '
We have 9 spaces and 3 words (2 gaps). So 4 spaces per 
   gap and 1 remainder.

Analysis

Well, this should be easy. And it is quite easy, but there are several edge cases, such as no words, no spaces, a single word, an empty string.

My algorithm:

  • Collect the words and count the spaces
  • Find the largest number of spaces available to go between each pair of words
  • ... and the number of extra spaces
  • Build the output

And I think that covers all the possibilities.

Try it 

Try running the script with any input:



example: the cat sat on the mat

Script


#!/usr/bin/perl

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

use v5.26;    # The Weekly Challenge - 2026-05-04
use utf8;     # Week 372 - task 1 - Rearrange spaces
use warnings; # Peter Campbell Smith
binmode STDOUT, ':utf8';
use Encode;

rearrange_spaces('aa bb cc bb ee      ');
rearrange_spaces('aa bb cc bb ee        ');
rearrange_spaces('  aa bb cc bb ee  ');
rearrange_spaces('abcde');
rearrange_spaces('abcde     ');
rearrange_spaces('     abcde');
rearrange_spaces('     ');
rearrange_spaces('');
rearrange_spaces('one two three four      ');

sub rearrange_spaces {
    
    my ($string, $rest, @words, $spaces, $fill, $extra, $word, $output);
    
    # initialise
    $string = $rest = $_[0];
    $spaces = 0;
    
    # collect words and count spaces
    while ($rest) {
        if ($rest =~ m|(^[^\s]+)(.*)|) {
            push @words, $1;
        } elsif ($rest =~ m|^(\s+)(.*)|) {
            $spaces += length $1;
        }
        $rest = $2;
    }
    
    # calculate inter-word spaces
    $fill = @words > 1 ? int($spaces / (@words - 1)) : 0;
    $extra = $spaces - $fill * (@words - 1);
    
    # build the output
    for $word (@words) {
        $output .= $word . (' ' x $fill);
    }
    $output = substr($output, 0, -$fill) if @words > 1;
    $output .= ' ' x $extra;
    
    # report
    say qq[\nInput:  '$string'];
    say qq[Output: '$output'];
}

18 lines of code

Output


Input:  'aa bb cc bb ee      '
Output: 'aa  bb  cc  bb  ee  '

Input:  'aa bb cc bb ee        '
Output: 'aa   bb   cc   bb   ee'

Input:  '  aa bb cc bb ee  '
Output: 'aa  bb  cc  bb  ee'

Input:  'abcde'
Output: 'abcde'

Input:  'abcde     '
Output: 'abcde     '

Input:  '     abcde'
Output: 'abcde     '

Input:  '     '
Output: '     '

Input:  ''
Output: ''

Input:  'one two three four      '
Output: 'one   two   three   four'

 

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