Persistent reduction
Weekly challenge 359 — 2 February 2026
Week 359: 2 Feb 2026
You are given a word containing only alphabetic characters.
Write a function that repeatedly removes adjacent duplicate characters from the word until no adjacent duplicates remain and return the final word.
Example 1 Input: $word = 'aabbccdd' Output: '' Iteration 1: remove 'aa', 'bb', 'cc', 'dd' => '' Example 2 Input: $word = 'abccba' Output: '' Iteration 1: remove 'cc' => 'abba' Iteration 2: remove 'bb' => 'aa' Iteration 3: remove 'aa' => '' Example 3 Input: $word = 'abcdef' Output: 'abcdef' No duplicate found. Example 4 Input: $word = 'aabbaeaccdd' Output: 'aea' Iteration 1: remove 'aa', 'bb', 'cc', 'dd' => 'aea' Example 5 Input: $word = 'mississippi' Output: 'm' Iteration 1: Remove 'ss', 'ss', 'pp' => 'miiii' Iteration 2: Remove 'ii', 'ii' => 'm'
My solution is this:
$count = $string =~ s|(\w)\1||g while $count;
with $count initialised to 1.
It works, it's short, it's efficient but it probably fails my usual test of 'is it understandable by a non-Perl maintainer'?
It works because $string =~ s|(\w)\1||g eliminates
all adjacent pairs of letters in the initial $string.
But it only makes one pass, so, for example 'abba' will
only be reduced to 'aa'.
It does however return (in scalar context) a $count of
its deletions and if that isn't zero the while ensures
that it tries again until no further pairs exist.
I am aware that it's possible to do that within the regex, but I think that makes it even more opaque.
I used \w rather than [a-z] to allow for non-Latin
alphabets such as Greek or Cyrillic, and I also used
lc() in the initialisation so that 'Ee' would be deleted,
which might - or might not - be what Mohammad wanted.
#!/usr/bin/perl # Blog: http://ccgi.campbellsmiths.force9.co.uk/challenge use v5.26; # The Weekly Challenge - 2026-02-02 use utf8; # Week 359 - task 2 - String reduction use warnings; # Peter Campbell Smith binmode STDOUT, ':utf8'; use Encode; string_reduction('mississippi'); string_reduction('house'); string_reduction('abcdefggfedcba'); string_reduction('aaaaaaaaaaaaaaaaaa'); string_reduction('abcdeEDCBA'); string_reduction('αβγδεεδγβαω'); sub string_reduction { my ($string, $count); # initialise $string = lc($_[0]); $count = 1; # delete matched pairs $count = $string =~ s|(\w)\1||g while $count; say qq[\nInput: '$_[0]']; say qq[Output: '$string']; }
Input: 'mississippi' Output: 'm' Input: 'house' Output: 'house' Input: 'abcdefggfedcba' Output: '' Input: 'aaaaaaaaaaaaaaaaaa' Output: '' Input: 'abcdeEDCBA' Output: '' Input: 'αβγδεεδγβαω' Output: 'ω'
Any content of this website which has been created by Peter Campbell Smith is in the public domain