Camel
Peter
Peter Campbell Smith

gROUP dIGIT sUM

Weekly challenge 311 — 3 March 2025

Week 311: 3 Mar 2025

Task 2

Task — Group digit sum

You are given a string, $str, made up of digits, and an integer, $int, which is less than the length of the given string.

Write a script to divide the given string into consecutive groups of size $int (plus one for leftovers if any).

Then sum the digits of each group, and concatenate all group sums to create a new string. If the length of the new string is less than or equal to the given integer then return the new string, otherwise continue the process.

Examples


Example 1
Input: $str = "111122333", $int = 3
Output: "359"
Step 1: "111", "122", "333" => "359"

Example 2
Input: $str = "1222312", $int = 2
Output: "76"
Step 1: "12", "22", "31", "2" => "3442"
Step 2: "34", "42" => "76"

Example 3
Input: $str = "100012121001", $int = 4
Output: "162"
Step 1: "1000", "1212", "1001" => "162"

Analysis

This is fairly straightforward to code, essentially following the steps in the task description. The algorithm will not converge unless $int is at least 2, so for simplicity I set it to 2 if it is is less than that.

I initially misread the instructions as requiring the end result to have < $int digits, but as the examples illustrate it's <= $int! digits.

Perhaps the least commonly used feature in my solution is the use of \d{1,$int} in a regular expression, which means match between 1 and $int digits.

Try it 

Try running the script with any input:



example: 1223334444



example: 3

Script


#!/usr/bin/perl

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

use v5.26;    # The Weekly Challenge - 2025-03-03
use utf8;     # Week 311 - task 2 - Group digit sum
use warnings; # Peter Campbell Smith
binmode STDOUT, ':utf8';

group_digit_sum('111122333', 3);
group_digit_sum('1222312', 2);
group_digit_sum('100012121001', 4);
group_digit_sum('314159265358', 5);

sub group_digit_sum {
    
    my ($str, $int, $new_str, $group, $sum);
    
    # intialise
    ($str, $int) = @_;
    $int = 2 if $int < 2;

    # loop until string no longer than $int
    while (length($str) > $int) {       
        $new_str = '';
        
        # loop across groups of digits
        while ($str =~ m|(\d{1,$int})|g) {
            $group = $1;
            $sum = 0;
            $sum += $_ for split('', $group);
            $new_str .= $sum;
        }
        $str = $new_str;
    }

    say qq[\nInput:  \$str = '$_[0]', \$int = $int];
    say qq[Output: '$str'];
}

Output


Input:  $str = 111122333, $int = 3
Output: 359

Input:  $str = 1222312, $int = 2
Output: 76

Input:  $str = 100012121001, $int = 4
Output: 162

Input:  $str = 314159265358, $int = 5
Output: 133

 

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