Peter’s solutions: week 372 — 4 May 2026
THE WEEKLY CHALLENGE
Strings of strings
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.
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.
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:
And I think that covers all the possibilities.
#!/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
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