Camel
Peter
Peter Campbell Smith

Fun with strings

Weekly challenge 329 — 7 July 2025

Week 329: 7 Jul 2025

Task 1

Task — Counter integers

You are given a string containing only lower case English letters and digits. Write a script to replace every non-digit character with a space and then return all the distinct integers left.

Examples


Example 1
Input: $str = 'the1weekly2challenge2'
Output: 1, 2
2 appears twice, so we count it once only.

Example 2
Input: $str = 'go21od1lu5c7k'
Output: 21, 1, 5, 7

Example 3
Input: $str = '4p3e2r1l'
Output: 4, 3, 2, 1

Analysis

This challenge contains a number of conundrums:

  1. Do we really need literally to replace non-digits with spaces, as there are other ways of producing the desired output?
  2. The examples show the output with the numbers in the same order as in the string, but is that a requirement?
  3. The string might contain something like a9a09a. Are 9 and 09 distinct?

I decided on point one to do what it says with spaces, although the line $string =~ s|[a-z]| |gi; is entirely redundant!

On point 2 I assumed that retaining the order was required, and on point 3 I decided that 9 and 09 are not distinct.

Others may have made different assumptions.

Although this is a trivial example, it illustrates pitfalls I have encountered many times when dealing with clients:

  • 'requirements' that are not really required
  • edge cases whose treament has not been defined
  • actual requirements which have not been specified

Try it 

Try running the script with any input:



example: 3frenchhens2turtledoves1partridge

Script


#!/usr/bin/perl

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

use v5.26;    # The Weekly Challenge - 2025-07-07
use utf8;     # Week 329 - task 1 - Counter integers
use warnings; # Peter Campbell Smith
binmode STDOUT, ':utf8';
use Encode;

counter_integers('the1weekly2challenge2');
counter_integers('go21od1lu5c7k');
counter_integers('4p3e2r1l');

# longer example
my ($string, $chars);
$chars .= $_ for ('a' .. 'z', '0' .. '9');
$string .= substr($chars, int(rand(36)), 1) for 0 .. 499;
counter_integers($string);

sub counter_integers {
    
    my ($string, $result, $found);
    
    # initialise
    $string = shift;
    say qq[\nInput:  '$string'];
    
    # replace non-digit sequences with blanks
    $string =~ s|[a-z]| |gi;
    
    # create result in original order
    $result = ', ';
    while ($string =~ m|(\d+)|g) {
        $found = $1 + 0;
        if ($result !~ m|, $found,|) {
            $result .= qq[$found, ];
        }
    }
    
    # list them
    say qq[Output: ] . substr($result, 2, -2);
}

Output


Input:  'the1weekly2challenge2'
Output: 1, 2

Input:  'go21od1lu5c7k'
Output: 21, 1, 5, 7

Input:  '4p3e2r1l'
Output: 4, 3, 2, 1

Input:  'fmgg56cl0kmvcjwpkitj0cziepevfrxmayr6enz5po2qudjw9
lyvv8z92ymeutqzxy0km8ilnc8tclf45w1s16ad2f7w52ygg40llp0cv9s
f5mssmsb4l2btj4pyeb9srdp3ok1h99vr8vo1pywatytkursm8hqdf7op1
i3n0kig2vj8twi4qbeqds4oovl6dql9royjjzcj5yxh3m8tpcxt50jiuuf
tx2ssl9pu8o69mzubkwm6z98hgipzafkbgnswy9v9rr7fotfs6l8ceful7
5c61zl8iu516j5e3ksh7jhmbxcg9gxogqk8cvbbfjxr6s90zv59ynzjhev
04e1igdyt9gsij1p5g4i9ekhabtk5gqz2rjidynwrosjoww35ef6y9ivv7
s4l9sf7blff23gbbobif2wzv6zz4jwsst5qz1qa9e4jf6ds8ps7ozro9c2
z7wulf0dieddzntdesz1f88l84xdhricsexqs2m3g8b95'
Output: 56, 0, 6, 5, 2, 9, 8, 92, 45, 1, 16, 7, 52, 40, 4,
3, 99, 50, 69, 98, 75, 61, 516, 90, 59, 35, 23, 88, 84,
95

 

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