Peter’s blog ✴ Week 355 ✴ 5 January 2026

THE WEEKLY CHALLENGE
Thousands of mountains

The Perl Camel

Task 1

Thousand separator

You are given a positive integer, $int. Write a script to add the thousands separator ',' and return it as a string.

Examples


Example 1
Input: $int = 123
Output: '123'

Example 2
Input: $int = 1234
Output: '1,234'

Example 3
Input: $int = 1000000
Output: '1,000,000'

Example 4
Input: $int = 1
Output: '1'

Example 5
Input: $int = 12345
Output: '12,345'

Analysis

Eddington
Arthur Eddington

Two challenges here:

  • Pattern matching that needs to start at the end of the string and work back, and
  • Overlapping pattern matching.

Here's an easy way to overcome both of those:

  • Reverse the string,
  • Do a repeated replacement of 4 consecutive digits with the first 3 of them, a comma, and the last one.
  • Reverse the result

Yes it's a bit inefficient, but the astronomer Sir Arthur Eddington is quoted as saying: 'I believe there are
15,747,724,136,275,002,577,605,653,961,181,555,468,044,
717,914,527,116,709,366,231,425,076,185,631,031,296
protons in the universe', which is probably the largest physically significant integer and it contains only 26 commas.

Perl Weekly’s review

from PW issue 755

This submission demonstrates strong problem understanding, solid algorithmic choices, and pragmatic Perl coding. The solutions are intentionally explicit, readable, and correct, favoring clarity and single-pass logic over clever one-liners. Both tasks are handled with approaches that scale reasonably and align well with Perl’s strengths.

Try it 

Try running the script with any input:



example: 1234567890

Script


#!/usr/bin/perl

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

use v5.26;    # The Weekly Challenge - 2026-01-05
use utf8;     # Week 355 - task 1 - Thousand separator
use warnings; # Peter Campbell Smith
binmode STDOUT, ':utf8';
use Encode;

thousand_separator(1);
thousand_separator(12);
thousand_separator(123);
thousand_separator(1234);
thousand_separator(123456);
thousand_separator(12345678901234567890);

sub thousand_separator {
    
    my ($number, $n, $reversed);
    
    # reverse the input
    $reversed = reverse($_[0]); 
    
    # repeatedly change 5555 to 555,5
    do { $n = $reversed =~ s|(\d{3})(\d)|$1,$2| } until $n == 0;
        
    say qq[\nInput:  $_[0]];
    say qq[Output: ] . reverse($reversed);
}

6 lines of code

Output from script


Input:  1
Output: 1

Input:  12
Output: 12

Input:  123
Output: 123

Input:  1234
Output: 1,234

Input:  123456
Output: 123,456

Input:  12345678901234567890
Output: 12,345,678,901,234,567,890

 

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